Skip to content

Commit

Permalink
better grouping errors (#7)
Browse files Browse the repository at this point in the history
* better grouping errors

* building

* add dummy for equations

* run fmt

* remove done todos
  • Loading branch information
carloskiki authored Aug 7, 2024
1 parent 9e0db58 commit 7e8045f
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 133 deletions.
128 changes: 128 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,134 @@ impl Grouping {
}
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum GroupingKind {
Normal,
OptionalArgument,
BeginEnd,
LeftRight,
Array { display: bool },
Matrix { ty: MatrixType, column_spec: bool },
Cases { left: bool, display: bool },
Equation { eq_numbers: bool },
Align { eq_numbers: bool },
Aligned,
SubArray,
Alignat { eq_numbers: bool },
Alignedat,
Gather { eq_numbers: bool },
Gathered,
Multline,
Split,
}

impl GroupingKind {
pub(crate) fn opening_str(&self) -> &'static str {
match self {
Self::Normal => "{",
Self::OptionalArgument => "[",
Self::BeginEnd => "\\begin",
Self::LeftRight => "\\left",
Self::Array { display: false } => "\\begin{array}",
Self::Array { display: true } => "\\begin{darray}",
Self::Matrix { ty, column_spec } => match (ty, column_spec) {
(MatrixType::Normal, true) => "\\begin{matrix*}",
(MatrixType::Normal, false) => "\\begin{matrix}",
(MatrixType::Small, true) => "\\begin{smallmatrix*}",
(MatrixType::Small, false) => "\\begin{smallmatrix}",
(MatrixType::Parens, true) => "\\begin{pmatrix*}",
(MatrixType::Parens, false) => "\\begin{pmatrix}",
(MatrixType::Brackets, true) => "\\begin{bmatrix*}",
(MatrixType::Brackets, false) => "\\begin{bmatrix}",
(MatrixType::Braces, true) => "\\begin{Bmatrix*}",
(MatrixType::Braces, false) => "\\begin{Bmatrix}",
(MatrixType::Vertical, true) => "\\begin{vmatrix*}",
(MatrixType::Vertical, false) => "\\begin{vmatrix}",
(MatrixType::DoubleVertical, true) => "\\begin{Vmatrix*}",
(MatrixType::DoubleVertical, false) => "\\begin{Vmatrix}",
},
Self::Cases { left, display } => match (left, display) {
(true, false) => "\\begin{cases}",
(true, true) => "\\begin{dcases}",
(false, false) => "\\begin{rcases}",
(false, true) => "\\begin{drcases}",
},
Self::Equation { eq_numbers: true } => "\\begin{equation}",
Self::Equation { eq_numbers: false } => "\\begin{equation*}",
Self::Align { eq_numbers: true } => "\\begin{align}",
Self::Align { eq_numbers: false } => "\\begin{align*}",
Self::Aligned => "\\begin{aligned}",
Self::SubArray => "\\begin{subarray}",
Self::Alignat { eq_numbers: true } => "\\begin{alignat}",
Self::Alignat { eq_numbers: false } => "\\begin{alignat*}",
Self::Alignedat => "\\begin{alignedat}",
Self::Gather { eq_numbers: true } => "\\begin{gather}",
Self::Gather { eq_numbers: false } => "\\begin{gather*}",
Self::Gathered => "\\begin{gathered}",
Self::Multline => "\\begin{multline}",
Self::Split => "\\begin{split}",
}
}

pub(crate) fn closing_str(&self) -> &'static str {
match self {
Self::Normal => "}",
Self::OptionalArgument => "]",
Self::BeginEnd => "\\end",
Self::LeftRight => "\\right",
Self::Array { display: false } => "\\end{array}",
Self::Array { display: true } => "\\end{darray}",
Self::Matrix { ty, column_spec } => match (ty, column_spec) {
(MatrixType::Normal, true) => "\\end{matrix*}",
(MatrixType::Normal, false) => "\\end{matrix}",
(MatrixType::Small, true) => "\\end{smallmatrix*}",
(MatrixType::Small, false) => "\\end{smallmatrix}",
(MatrixType::Parens, true) => "\\end{pmatrix*}",
(MatrixType::Parens, false) => "\\end{pmatrix}",
(MatrixType::Brackets, true) => "\\end{bmatrix*}",
(MatrixType::Brackets, false) => "\\end{bmatrix}",
(MatrixType::Braces, true) => "\\end{Bmatrix*}",
(MatrixType::Braces, false) => "\\end{Bmatrix}",
(MatrixType::Vertical, true) => "\\end{vmatrix*}",
(MatrixType::Vertical, false) => "\\end{vmatrix}",
(MatrixType::DoubleVertical, true) => "\\end{Vmatrix*}",
(MatrixType::DoubleVertical, false) => "\\end{Vmatrix}",
},
Self::Cases { left, display } => match (left, display) {
(true, false) => "\\end{cases}",
(true, true) => "\\end{dcases}",
(false, false) => "\\end{rcases}",
(false, true) => "\\end{drcases}",
},
Self::Equation { eq_numbers: true } => "\\end{equation}",
Self::Equation { eq_numbers: false } => "\\end{equation*}",
Self::Align { eq_numbers: true } => "\\end{align}",
Self::Align { eq_numbers: false } => "\\end{align*}",
Self::Aligned => "\\end{aligned}",
Self::SubArray => "\\end{subarray}",
Self::Alignat { eq_numbers: true } => "\\end{alignat}",
Self::Alignat { eq_numbers: false } => "\\end{alignat*}",
Self::Alignedat => "\\end{alignedat}",
Self::Gather { eq_numbers: true } => "\\end{gather}",
Self::Gather { eq_numbers: false } => "\\end{gather*}",
Self::Gathered => "\\end{gathered}",
Self::Multline => "\\end{multline}",
Self::Split => "\\end{split}",
}
}
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum MatrixType {
Normal,
Small,
Parens,
Brackets,
Braces,
Vertical,
DoubleVertical,
}

/// Represents a column in a matrix or array environment.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ColumnAlignment {
Expand Down
11 changes: 6 additions & 5 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::{error::Error, fmt::Display};

use super::SpanStack;
use crate::event::Grouping;
use crate::event::GroupingKind;

/// Anything that could possibly go wrong while parsing.
///
Expand Down Expand Up @@ -145,8 +145,7 @@ pub(crate) type InnerResult<T> = std::result::Result<T, ErrorKind>;

#[derive(Debug)]
pub(crate) enum ErrorKind {
// TODO: this error is very misleading. Rework it.
UnbalancedGroup(Option<Grouping>),
UnbalancedGroup(Option<GroupingKind>),
Environment,
MathShift,
HashSign,
Expand Down Expand Up @@ -175,7 +174,6 @@ pub(crate) enum ErrorKind {
IncorrectReplacementParams(u8, u8),
TooManyParams,
StandaloneHashSign,
// TODO: should specify what the macro expects the prefix string to be.
IncorrectMacroPrefix,
MacroAlreadyDefined,
MacroNotDefined,
Expand All @@ -185,7 +183,10 @@ impl Display for ErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
// TODO: this error is very misleading. Rework it.
ErrorKind::UnbalancedGroup(_) => f.write_str("unbalanced group found"),
ErrorKind::UnbalancedGroup(Some(missing)) => {
write!(f, "unbalanced group found, expected it to be closed with `{}`", missing.closing_str())
},
ErrorKind::UnbalancedGroup(None) => f.write_str("unbalanced group found, unexpected group closing found"),
ErrorKind::Environment => f.write_str("unkown mathematical environment found"),
ErrorKind::MathShift => f.write_str(
"unexpected math `$` (math shift) character - this character cannot be used inside math mode"),
Expand Down
27 changes: 15 additions & 12 deletions src/parser/lex.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
attribute::{Dimension, DimensionUnit, Glue},
event::DelimiterType,
event::{DelimiterType, GroupingKind},
};

use super::{tables::token_to_delim, Argument, CharToken, ErrorKind, InnerResult, Token};
Expand All @@ -23,7 +23,7 @@ pub fn definition<'a>(input: &mut &'a str) -> InnerResult<(&'a str, &'a str, &'a
}

*input = rest;
let replacement_text = group_content(input, "{", "}")?;
let replacement_text = group_content(input, GroupingKind::Normal)?;

Ok((control_sequence, parameter_text, replacement_text))
}
Expand All @@ -32,27 +32,27 @@ pub fn definition<'a>(input: &mut &'a str) -> InnerResult<(&'a str, &'a str, &'a
pub fn argument<'a>(input: &mut &'a str) -> InnerResult<Argument<'a>> {
if let Some(rest) = input.trim_start().strip_prefix('{') {
*input = rest;
let content = group_content(input, "{", "}")?;
let content = group_content(input, GroupingKind::Normal)?;
Ok(Argument::Group(content))
} else {
Ok(Argument::Token(token(input)?))
}
}

pub fn optional_argument<'a>(input: &mut &'a str) -> InnerResult<Option<&'a str>> {
pub fn optional_argument<'a>(input: &mut &'a str) -> Option<&'a str> {
if let Some(rest) = input.trim_start().strip_prefix('[') {
*input = rest;
let content = group_content(input, "[", "]")?;
Ok(Some(content))
let content = group_content(input, GroupingKind::OptionalArgument).ok()?;
Some(content)
} else {
Ok(None)
None
}
}

pub fn brace_argument<'a>(input: &mut &'a str) -> InnerResult<&'a str> {
if let Some(rest) = input.trim_start().strip_prefix('{') {
*input = rest;
group_content(input, "{", "}")
group_content(input, GroupingKind::Normal)
} else {
Err(ErrorKind::GroupArgument)
}
Expand All @@ -62,7 +62,9 @@ pub fn brace_argument<'a>(input: &mut &'a str) -> InnerResult<&'a str> {
///
/// The output is the content within the group without the surrounding `start` and `end`.
/// This content is guaranteed to be balanced.
pub fn group_content<'a>(input: &mut &'a str, start: &str, end: &str) -> InnerResult<&'a str> {
pub fn group_content<'a>(input: &mut &'a str, grouping_kind: GroupingKind) -> InnerResult<&'a str> {
let start = grouping_kind.opening_str();
let end = grouping_kind.closing_str();
let mut escaped = false;
let mut index = 0;
let mut depth = 0u32;
Expand Down Expand Up @@ -123,8 +125,8 @@ pub fn content_with_suffix<'a>(input: &mut &'a str, suffix: &str) -> InnerResult
index += rest_pos;
}
b'{' if !escaped => {
let conetent = group_content(&mut &input[index + 1..], "{", "}")?;
index += conetent.len() + 1;
let content = group_content(&mut &input[index + 1..], GroupingKind::Normal)?;
index += content.len() + 1;
}
_ => escaped = false,
}
Expand Down Expand Up @@ -449,6 +451,7 @@ pub fn token<'a>(input: &mut &'a str) -> InnerResult<Token<'a>> {
mod tests {
use crate::{
attribute::DimensionUnit,
event::GroupingKind,
parser::{lex, Token},
};

Expand Down Expand Up @@ -550,7 +553,7 @@ mod tests {
fn group_content() {
let mut input =
"this { { is a test } to see if { the content parsing { of this } } } works }";
let content = lex::group_content(&mut input, "{", "}").unwrap();
let content = lex::group_content(&mut input, GroupingKind::Normal).unwrap();
assert_eq!(
content,
"this { { is a test } to see if { the content parsing { of this } } } works "
Expand Down
2 changes: 1 addition & 1 deletion src/parser/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl<'input> MacroContext<'input> {

if let Some(default_argument) = first_arg_default {
arguments.push(Ok(Argument::Group(
lex::optional_argument(&mut input_rest)?.unwrap_or(default_argument),
lex::optional_argument(&mut input_rest).unwrap_or(default_argument),
)));
}

Expand Down
Loading

0 comments on commit 7e8045f

Please sign in to comment.