From 2b0ebc60924d09ee924a27e9bd8f9285489f9be9 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Sun, 22 Jan 2023 21:38:27 -0800 Subject: [PATCH 1/4] Demonstrate failing test --- src/tests.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/tests.rs b/src/tests.rs index 252dc79f..67956b38 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1068,6 +1068,30 @@ fn footnote_in_table() { )); } +#[test] +fn footnote_with_superscript() { + html_opts!( + [extension.superscript, extension.footnotes], + concat!( + "Here is a footnote reference.[^1]\n", + "\n", + "[^1]: Here is the footnote.\n", + ), + concat!( + "

Here is a footnote reference.1

\n", + "
\n", + "
    \n", + "
  1. \n", + "

    Here is the footnote.

    \n", + "
  2. \n", + "
\n", + "
\n" + ), + ); +} + #[test] fn regression_back_to_back_ranges() { html( From 8cd3e8911ca76de71a7dc1bd0a257c0ea51f220c Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Sun, 22 Jan 2023 22:53:50 -0800 Subject: [PATCH 2/4] keep track of when within brackets --- src/parser/inlines.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/parser/inlines.rs b/src/parser/inlines.rs index 46fdd157..28a1235e 100644 --- a/src/parser/inlines.rs +++ b/src/parser/inlines.rs @@ -26,6 +26,7 @@ pub struct Subject<'a: 'd, 'r, 'o, 'd, 'i, 'c: 'subj, 'subj> { delimiter_arena: &'d Arena>, last_delimiter: Option<&'d Delimiter<'a, 'd>>, brackets: Vec>, + within_brackets: bool, pub backticks: [usize; MAXBACKTICKS + 1], pub scanned_for_backticks: bool, special_chars: [bool; 256], @@ -74,6 +75,7 @@ impl<'a, 'r, 'o, 'd, 'i, 'c, 'subj> Subject<'a, 'r, 'o, 'd, 'i, 'c, 'subj> { delimiter_arena, last_delimiter: None, brackets: vec![], + within_brackets: false, backticks: [0; MAXBACKTICKS + 1], scanned_for_backticks: false, special_chars: [false; 256], @@ -128,9 +130,13 @@ impl<'a, 'r, 'o, 'd, 'i, 'c, 'subj> Subject<'a, 'r, 'o, 'd, 'i, 'c, 'subj> { self.pos += 1; let inl = make_inline(self.arena, NodeValue::Text(b"[".to_vec())); self.push_bracket(false, inl); + self.within_brackets = true; Some(inl) } - ']' => self.handle_close_bracket(), + ']' => { + self.within_brackets = false; + self.handle_close_bracket() + } '!' => { self.pos += 1; if self.peek_char() == Some(&(b'[')) && self.peek_char_n(1) != Some(&(b'^')) { From 43f334e7848d0ab33cf2c3d4785765ff8b440af5 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 24 Jan 2023 16:51:42 -0800 Subject: [PATCH 3/4] Improve test case of superscript + foonotes --- src/tests.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests.rs b/src/tests.rs index 67956b38..a356b11b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1075,17 +1075,29 @@ fn footnote_with_superscript() { concat!( "Here is a footnote reference.[^1]\n", "\n", + "Here is a longer footnote reference.[^ref]\n", + "\n", + "e = mc^2^.\n", + "\n", "[^1]: Here is the footnote.\n", + "[^ref]: Here is another footnote.\n", ), concat!( "

Here is a footnote reference.1

\n", + "

Here is a longer footnote reference.2

\n", + "

e = mc2.

\n", "
\n", "
    \n", "
  1. \n", "

    Here is the footnote.

    \n", "
  2. \n", + "
  3. \n", + "

    Here is another footnote.

    \n", + "
  4. \n", "
\n", "
\n" ), From 83a81ce1502a0d34b4502627cebfac6aefb40989 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 24 Jan 2023 16:52:04 -0800 Subject: [PATCH 4/4] avoid special "^" char pattern matching --- src/parser/inlines.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/parser/inlines.rs b/src/parser/inlines.rs index 28a1235e..21379808 100644 --- a/src/parser/inlines.rs +++ b/src/parser/inlines.rs @@ -149,7 +149,9 @@ impl<'a, 'r, 'o, 'd, 'i, 'c, 'subj> Subject<'a, 'r, 'o, 'd, 'i, 'c, 'subj> { } } '~' if self.options.extension.strikethrough => Some(self.handle_delim(b'~')), - '^' if self.options.extension.superscript => Some(self.handle_delim(b'^')), + '^' if self.options.extension.superscript && !self.within_brackets => { + Some(self.handle_delim(b'^')) + } _ => { let endpos = self.find_special_char(); let mut contents = self.input[self.pos..endpos].to_vec(); @@ -458,7 +460,11 @@ impl<'a, 'r, 'o, 'd, 'i, 'c, 'subj> Subject<'a, 'r, 'o, 'd, 'i, 'c, 'subj> { pub fn find_special_char(&self) -> usize { for n in self.pos..self.input.len() { if self.special_chars[self.input[n] as usize] { - return n; + if self.input[n] == b'^' && self.within_brackets { + // NO OP + } else { + return n; + } } if self.options.parse.smart && self.smart_chars[self.input[n] as usize] { return n;