diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-07-13 10:40:11 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-07-13 10:40:11 +0200 |
commit | ad8eac98c1468b30c17c339e79b84c37a7b15517 (patch) | |
tree | daffac5b46b474787ebe6e886061510249f37cab | |
parent | 86834a02b301bba48c2bd568beb156e604470167 (diff) | |
download | markdown-rs-ad8eac98c1468b30c17c339e79b84c37a7b15517.tar.gz markdown-rs-ad8eac98c1468b30c17c339e79b84c37a7b15517.tar.bz2 markdown-rs-ad8eac98c1468b30c17c339e79b84c37a7b15517.zip |
Fix to close containers before several (blank) line endings
-rw-r--r-- | src/compiler.rs | 23 | ||||
-rw-r--r-- | src/content/document.rs | 24 | ||||
-rw-r--r-- | tests/block_quote.rs | 11 | ||||
-rw-r--r-- | tests/code_fenced.rs | 22 | ||||
-rw-r--r-- | tests/list.rs | 48 |
5 files changed, 66 insertions, 62 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index 2d42011..4b38c8d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -241,6 +241,7 @@ struct CompileContext<'a> { pub tight_stack: Vec<bool>, /// Fields used to influance the current compilation. pub slurp_one_line_ending: bool, + pub slurp_all_line_endings: bool, pub tags: bool, pub ignore_encode: bool, pub last_was_tag: bool, @@ -275,6 +276,7 @@ impl<'a> CompileContext<'a> { definitions: HashMap::new(), tight_stack: vec![], slurp_one_line_ending: false, + slurp_all_line_endings: false, tags: true, ignore_encode: false, last_was_tag: false, @@ -381,7 +383,6 @@ impl<'a> CompileContext<'a> { /// Turn events and codes into a string of HTML. #[allow(clippy::too_many_lines)] pub fn compile(events: &[Event], codes: &[Code], options: &Options) -> String { - // let slurp_all_line_endings = false; let mut index = 0; let mut line_ending_inferred: Option<LineEnding> = None; @@ -718,7 +719,7 @@ fn on_enter_paragraph(context: &mut CompileContext) { context.tag("<p>".to_string()); } - // context.slurp_all_line_endings = false; + context.slurp_all_line_endings = false; } /// Handle [`Enter`][EventType::Enter]:[`Resource`][Token::Resource]. @@ -784,7 +785,7 @@ fn on_exit_block_quote(context: &mut CompileContext) { context.tight_stack.pop(); context.line_ending_if_needed(); context.tag("</blockquote>".to_string()); - // context.slurp_all_line_endings = false; + context.slurp_all_line_endings = false; } /// Handle [`Exit`][EventType::Exit]:[`CharacterReferenceMarker`][Token::CharacterReferenceMarker]. @@ -1074,10 +1075,9 @@ fn on_exit_label_text(context: &mut CompileContext) { /// Handle [`Exit`][EventType::Exit]:[`LineEnding`][Token::LineEnding]. fn on_exit_line_ending(context: &mut CompileContext) { - // if context.slurp_all_line_endings { - // // Empty. - // } else - if context.slurp_one_line_ending { + if context.slurp_all_line_endings { + // Empty. + } else if context.slurp_one_line_ending { context.slurp_one_line_ending = false; } else { context.push(context.encode_opt(&serialize( @@ -1156,7 +1156,9 @@ fn on_exit_media(context: &mut CompileContext) { fn on_exit_paragraph(context: &mut CompileContext) { let tight = context.tight_stack.last().unwrap_or(&false); - if !tight { + if *tight { + context.slurp_all_line_endings = true; + } else { context.tag("</p>".to_string()); } } @@ -1281,13 +1283,12 @@ fn on_exit_list_item_value(context: &mut CompileContext) { /// To do. fn on_exit_list_item(context: &mut CompileContext) { - // && !context.slurp_all_line_endings - if context.last_was_tag { + if context.last_was_tag && !context.slurp_all_line_endings { context.line_ending_if_needed(); } context.tag("</li>".to_string()); - // context.slurp_all_line_endings = false; + context.slurp_all_line_endings = false; } /// To do. diff --git a/src/content/document.rs b/src/content/document.rs index 27fb73d..7f8a116 100644 --- a/src/content/document.rs +++ b/src/content/document.rs @@ -410,6 +410,7 @@ fn flow_end( let mut index = 0; let add = info.inject[line_index].0.clone(); + let mut first_line_ending_in_run: Option<usize> = None; map.add(0, 0, add); while index < tokenizer.events.len() { @@ -419,19 +420,28 @@ fn flow_end( || event.token_type == Token::BlankLineEnding { if event.event_type == EventType::Enter { + first_line_ending_in_run = first_line_ending_in_run.or(Some(index)); let mut add = info.inject[line_index].1.clone(); - let mut deep_index = 0; - while deep_index < add.len() { - add[deep_index].point = event.point.clone(); - add[deep_index].index = event.index; - deep_index += 1; + let mut index = 0; + while index < add.len() { + add[index].point = event.point.clone(); + add[index].index = event.index; + index += 1; + } + if !add.is_empty() { + map.add(first_line_ending_in_run.unwrap(), 0, add); } - map.add(index, 0, add); } else { line_index += 1; let add = info.inject[line_index].0.clone(); - map.add(index + 1, 0, add); + if !add.is_empty() { + map.add(index + 1, 0, add); + } } + } else if event.token_type == Token::SpaceOrTab { + // Empty to allow whitespace in blank lines. + } else { + first_line_ending_in_run = None; } index += 1; diff --git a/tests/block_quote.rs b/tests/block_quote.rs index 8fb4e61..782104f 100644 --- a/tests/block_quote.rs +++ b/tests/block_quote.rs @@ -143,12 +143,11 @@ fn block_quote() { "should support interrupting block quotes w/ blank lines" ); - // To do: some container bug introduces due to lists? - // assert_eq!( - // micromark("> a\n>\nb"), - // "<blockquote>\n<p>a</p>\n</blockquote>\n<p>b</p>", - // "should not support interrupting a blank line in a block quotes w/ paragraphs" - // ); + assert_eq!( + micromark("> a\n>\nb"), + "<blockquote>\n<p>a</p>\n</blockquote>\n<p>b</p>", + "should not support interrupting a blank line in a block quotes w/ paragraphs" + ); assert_eq!( micromark("> > > a\nb"), diff --git a/tests/code_fenced.rs b/tests/code_fenced.rs index b7bfd79..fa9ed5f 100644 --- a/tests/code_fenced.rs +++ b/tests/code_fenced.rs @@ -57,12 +57,11 @@ fn code_fenced() { "should support an eof somewhere in content" ); - // To do: container exits before (blank) line endings. - // assert_eq!( - // micromark("> ```\n> aaa\n\nbbb"), - // "<blockquote>\n<pre><code>aaa\n</code></pre>\n</blockquote>\n<p>bbb</p>", - // "should support no closing sequence in a block quote" - // ); + assert_eq!( + micromark("> ```\n> aaa\n\nbbb"), + "<blockquote>\n<pre><code>aaa\n</code></pre>\n</blockquote>\n<p>bbb</p>", + "should support no closing sequence in a block quote" + ); assert_eq!( micromark("```\n\n \n```"), @@ -227,12 +226,11 @@ fn code_fenced() { "should not support a closing sequence w/ too much indent, regardless of opening sequence (1)" ); - // To do: container exits before (blank) line endings. - // assert_eq!( - // micromark("> ```\n>\n>\n>\n\na"), - // "<blockquote>\n<pre><code>\n\n\n</code></pre>\n</blockquote>\n<p>a</p>", - // "should not support a closing sequence w/ too much indent, regardless of opening sequence (2)" - // ); + assert_eq!( + micromark("> ```\n>\n>\n>\n\na"), + "<blockquote>\n<pre><code>\n\n\n</code></pre>\n</blockquote>\n<p>a</p>", + "should not support a closing sequence w/ too much indent, regardless of opening sequence (2)" + ); assert_eq!( micromark("> ```a\nb"), diff --git a/tests/list.rs b/tests/list.rs index e45c31d..1eee72a 100644 --- a/tests/list.rs +++ b/tests/list.rs @@ -383,19 +383,17 @@ fn list() { // "should support blank lines between items (2)" // ); - // To do: list (for some weird reason seen as one list?). - // assert_eq!( - // micromark_with_options("- foo\n- bar\n\n<!-- -->\n\n- baz\n- bim", DANGER), - // "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<!-- -->\n<ul>\n<li>baz</li>\n<li>bim</li>\n</ul>", - // "should support HTML comments between lists" - // ); + assert_eq!( + micromark_with_options("- foo\n- bar\n\n<!-- -->\n\n- baz\n- bim", DANGER), + "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<!-- -->\n<ul>\n<li>baz</li>\n<li>bim</li>\n</ul>", + "should support HTML comments between lists" + ); - // To do: list (for some weird reason the HTML is in the list?). - // assert_eq!( - // micromark_with_options("- foo\n\n notcode\n\n- foo\n\n<!-- -->\n\n code", DANGER), - // "<ul>\n<li>\n<p>foo</p>\n<p>notcode</p>\n</li>\n<li>\n<p>foo</p>\n</li>\n</ul>\n<!-- -->\n<pre><code>code\n</code></pre>", - // "should support HTML comments between lists and indented code" - // ); + assert_eq!( + micromark_with_options("- foo\n\n notcode\n\n- foo\n\n<!-- -->\n\n code", DANGER), + "<ul>\n<li>\n<p>foo</p>\n<p>notcode</p>\n</li>\n<li>\n<p>foo</p>\n</li>\n</ul>\n<!-- -->\n<pre><code>code\n</code></pre>", + "should support HTML comments between lists and indented code" + ); // To do: list (indent). // assert_eq!( @@ -529,14 +527,13 @@ fn list() { // "should support blank lines in code after an initial blank line" // ); - // To do: list (blank lines). - // assert_eq!( - // micromark( - // "* a tight item that ends with an html element: `x`\n\nParagraph" - // ), - // "<ul>\n<li>a tight item that ends with an html element: <code>x</code></li>\n</ul>\n<p>Paragraph</p>", - // "should ignore line endings after tight items ending in tags" - // ); + assert_eq!( + micromark( + "* a tight item that ends with an html element: `x`\n\nParagraph" + ), + "<ul>\n<li>a tight item that ends with an html element: <code>x</code></li>\n</ul>\n<p>Paragraph</p>", + "should ignore line endings after tight items ending in tags" + ); // To do: list (empty). // assert_eq!( @@ -608,12 +605,11 @@ fn list() { // "should support complex nested and empty lists (3)" // ); - // To do: list (blank lines in lists?). - // assert_eq!( - // micromark_with_options("* a\n\n<!---->\n\n* b", DANGER), - // "<ul>\n<li>a</li>\n</ul>\n<!---->\n<ul>\n<li>b</li>\n</ul>", - // "should support the common list breaking comment method" - // ); + assert_eq!( + micromark_with_options("* a\n\n<!---->\n\n* b", DANGER), + "<ul>\n<li>a</li>\n</ul>\n<!---->\n<ul>\n<li>b</li>\n</ul>", + "should support the common list breaking comment method" + ); // To do: turning things off. // assert_eq!( |