diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-07-05 14:52:49 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-07-05 14:52:49 +0200 |
commit | fec46e918e5bdf4a9137041298ab1475d2f43202 (patch) | |
tree | fb733a356b234bfeaf18fee911c6af72cfebe615 | |
parent | 195e25958cfaa42d91b36f3fc51e8315586c6378 (diff) | |
download | markdown-rs-fec46e918e5bdf4a9137041298ab1475d2f43202.tar.gz markdown-rs-fec46e918e5bdf4a9137041298ab1475d2f43202.tar.bz2 markdown-rs-fec46e918e5bdf4a9137041298ab1475d2f43202.zip |
Fix interleaving of attention/label
-rw-r--r-- | readme.md | 2 | ||||
-rw-r--r-- | src/construct/attention.rs | 98 | ||||
-rw-r--r-- | tests/attention.rs | 22 | ||||
-rw-r--r-- | tests/link_reference.rs | 22 | ||||
-rw-r--r-- | tests/link_resource.rs | 11 |
5 files changed, 80 insertions, 75 deletions
@@ -127,7 +127,6 @@ cargo doc --document-private-items #### Parse -- [ ] (2) Fix attention/label interplay - [ ] (8) block quote\ test (`code_fenced`, `definition`, `code_indented`, `heading_atx`, `heading_setext`, `html_flow`, `misc_default_line_ending`, `thematic_break`) @@ -276,3 +275,4 @@ important. - [x] (1) Document attention - [x] (1) Remove todos in `span.rs` if not needed - [x] (2) Fix resizing attention bug +- [x] (2) Fix interleaving of attention/label diff --git a/src/construct/attention.rs b/src/construct/attention.rs index d445938..d460afb 100644 --- a/src/construct/attention.rs +++ b/src/construct/attention.rs @@ -146,6 +146,8 @@ impl MarkerKind { struct Sequence { /// Marker used in this sequence. marker: MarkerKind, + /// The depth in events where this sequence resides. + balance: usize, /// The index into events where this sequence’s `Enter` currently resides. event_index: usize, /// The (shifted) point where this sequence starts. @@ -220,57 +222,62 @@ fn resolve(tokenizer: &mut Tokenizer) -> Vec<Event> { let codes = &tokenizer.parse_state.codes; let mut edit_map = EditMap::new(); let mut start = 0; + let mut balance = 0; let mut sequences: Vec<Sequence> = vec![]; // Find sequences of sequences and information about them. while start < tokenizer.events.len() { let enter = &tokenizer.events[start]; - if enter.event_type == EventType::Enter && enter.token_type == TokenType::AttentionSequence - { - let end = start + 1; - let exit = &tokenizer.events[end]; - let marker = MarkerKind::from_code(codes[enter.index]); - let before = classify_character(if enter.index > 0 { - codes[enter.index - 1] - } else { - Code::None - }); - let after = classify_character(if exit.index < codes.len() { - codes[exit.index] - } else { - Code::None - }); - let open = after == GroupKind::Other - || (after == GroupKind::Punctuation && before != GroupKind::Other); - // To do: GFM strikethrough? - // || attentionMarkers.includes(code) - let close = before == GroupKind::Other - || (before == GroupKind::Punctuation && after != GroupKind::Other); - // To do: GFM strikethrough? - // || attentionMarkers.includes(previous) - - sequences.push(Sequence { - event_index: start, - start_point: enter.point.clone(), - start_index: enter.index, - end_point: exit.point.clone(), - end_index: exit.index, - size: exit.index - enter.index, - open: if marker == MarkerKind::Asterisk { - open + if enter.event_type == EventType::Enter { + balance += 1; + + if enter.token_type == TokenType::AttentionSequence { + let end = start + 1; + let exit = &tokenizer.events[end]; + let marker = MarkerKind::from_code(codes[enter.index]); + let before = classify_character(if enter.index > 0 { + codes[enter.index - 1] } else { - open && (before != GroupKind::Other || !close) - }, - close: if marker == MarkerKind::Asterisk { - close + Code::None + }); + let after = classify_character(if exit.index < codes.len() { + codes[exit.index] } else { - close && (after != GroupKind::Other || !open) - }, - marker, - }); - - start += 1; + Code::None + }); + let open = after == GroupKind::Other + || (after == GroupKind::Punctuation && before != GroupKind::Other); + // To do: GFM strikethrough? + // || attentionMarkers.includes(code) + let close = before == GroupKind::Other + || (before == GroupKind::Punctuation && after != GroupKind::Other); + // To do: GFM strikethrough? + // || attentionMarkers.includes(previous) + + sequences.push(Sequence { + event_index: start, + balance, + start_point: enter.point.clone(), + start_index: enter.index, + end_point: exit.point.clone(), + end_index: exit.index, + size: exit.index - enter.index, + open: if marker == MarkerKind::Asterisk { + open + } else { + open && (before != GroupKind::Other || !close) + }, + close: if marker == MarkerKind::Asterisk { + close + } else { + close && (after != GroupKind::Other || !open) + }, + marker, + }); + } + } else { + balance -= 1; } start += 1; @@ -296,7 +303,10 @@ fn resolve(tokenizer: &mut Tokenizer) -> Vec<Event> { let sequence_open = &sequences[open]; // We found a sequence that can open the closer we found. - if sequence_open.open && sequence_close.marker == sequence_open.marker { + if sequence_open.open + && sequence_close.marker == sequence_open.marker + && sequence_close.balance == sequence_open.balance + { println!("open! {:?} {:?}", open, sequence_open); // If the opening can close or the closing can open, // and the close size *is not* a multiple of three, diff --git a/tests/attention.rs b/tests/attention.rs index 6ab173b..789d860 100644 --- a/tests/attention.rs +++ b/tests/attention.rs @@ -753,19 +753,17 @@ fn attention() { ); // Rule 17. - // To do: attention/link interplay. - // assert_eq!( - // micromark("*[bar*](/url)"), - // "<p>*<a href=\"/url\">bar*</a></p>", - // "should not mismatch inside links (1)" - // ); + assert_eq!( + micromark("*[bar*](/url)"), + "<p>*<a href=\"/url\">bar*</a></p>", + "should not mismatch inside links (1)" + ); - // To do: attention/link interplay. - // assert_eq!( - // micromark("_[bar_](/url)"), - // "<p>_<a href=\"/url\">bar_</a></p>", - // "should not mismatch inside links (1)" - // ); + assert_eq!( + micromark("_[bar_](/url)"), + "<p>_<a href=\"/url\">bar_</a></p>", + "should not mismatch inside links (1)" + ); assert_eq!( micromark_with_options("*<img src=\"foo\" title=\"*\"/>", DANGER), diff --git a/tests/link_reference.rs b/tests/link_reference.rs index b53b99b..30fb2b5 100644 --- a/tests/link_reference.rs +++ b/tests/link_reference.rs @@ -51,12 +51,11 @@ fn link_reference() { "should not support deep links in link references" ); - // To do: link/attention interplay. - // assert_eq!( - // micromark("[ref]: /uri\n\n*[foo*][ref]"), - // "<p>*<a href=\"/uri\">foo*</a></p>", - // "should prefer link references over emphasis (1)" - // ); + assert_eq!( + micromark("[ref]: /uri\n\n*[foo*][ref]"), + "<p>*<a href=\"/uri\">foo*</a></p>", + "should prefer link references over emphasis (1)" + ); assert_eq!( micromark("[ref]: /uri\n\n[foo *bar][ref]"), @@ -232,12 +231,11 @@ fn link_reference() { "should “support” an escaped shortcut reference" ); - // To do: link/attention interplay. - // assert_eq!( - // micromark("[foo*]: /url\n\n*[foo*]"), - // "<p>*<a href=\"/url\">foo*</a></p>", - // "should prefer shortcut references over emphasis" - // ); + assert_eq!( + micromark("[foo*]: /url\n\n*[foo*]"), + "<p>*<a href=\"/url\">foo*</a></p>", + "should prefer shortcut references over emphasis" + ); assert_eq!( micromark("[foo]: /url1\n[bar]: /url2\n\n[foo][bar]"), diff --git a/tests/link_resource.rs b/tests/link_resource.rs index e4037a2..31e4b81 100644 --- a/tests/link_resource.rs +++ b/tests/link_resource.rs @@ -261,12 +261,11 @@ fn link_resource() { "should not support links in links (3)" ); - // To do: link/attention interplay. - // assert_eq!( - // micromark("*[foo*](/uri)"), - // "<p>*<a href=\"/uri\">foo*</a></p>", - // "should prefer links over emphasis (1)" - // ); + assert_eq!( + micromark("*[foo*](/uri)"), + "<p>*<a href=\"/uri\">foo*</a></p>", + "should prefer links over emphasis (1)" + ); assert_eq!( micromark("[foo *bar](baz*)"), |