diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-06-30 12:49:55 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-06-30 12:49:55 +0200 |
commit | bf9460fddeec7366df117ddae13b7d31d3354313 (patch) | |
tree | aa29606a51cf464590cca88b35ee83041bb6a2f6 | |
parent | b0bc9ea9b5f5bf8a5c2f33b1102abf4f649e60c7 (diff) | |
download | markdown-rs-bf9460fddeec7366df117ddae13b7d31d3354313.tar.gz markdown-rs-bf9460fddeec7366df117ddae13b7d31d3354313.tar.bz2 markdown-rs-bf9460fddeec7366df117ddae13b7d31d3354313.zip |
Add support for stripping tags in image `alt`
-rw-r--r-- | src/compiler.rs | 104 | ||||
-rw-r--r-- | tests/heading_setext.rs | 8 | ||||
-rw-r--r-- | tests/image.rs | 32 | ||||
-rw-r--r-- | tests/link_resource.rs | 11 |
4 files changed, 81 insertions, 74 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index fbc4792..acba76a 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -241,6 +241,7 @@ struct CompileContext<'a> { pub definitions: HashMap<String, Definition>, /// Fields used to influance the current compilation. pub slurp_one_line_ending: bool, + pub tags: bool, pub ignore_encode: bool, pub last_was_tag: bool, /// Configuration @@ -272,6 +273,7 @@ impl<'a> CompileContext<'a> { media_stack: vec![], definitions: HashMap::new(), slurp_one_line_ending: false, + tags: true, ignore_encode: false, last_was_tag: false, protocol_href: if options.allow_dangerous_protocol { @@ -309,6 +311,17 @@ impl<'a> CompileContext<'a> { .last_mut() .expect("Cannot push w/o buffer") .push(value); + self.last_was_tag = false; + } + + pub fn tag(&mut self, value: String) { + if self.tags { + self.buffers + .last_mut() + .expect("Cannot push w/o buffer") + .push(value); + self.last_was_tag = true; + } } /// Get the last chunk of current buffer. @@ -323,13 +336,6 @@ impl<'a> CompileContext<'a> { .expect("at least one buffer should exist") } - /// Get the mutable last chunk of current buffer. - pub fn buf_tail_mut(&mut self) -> &mut Vec<String> { - self.buffers - .last_mut() - .expect("at least one buffer should exist") - } - /// Optionally encode. pub fn encode_opt(&self, value: &str) -> String { if self.ignore_encode { @@ -600,7 +606,7 @@ fn on_enter_buffer(context: &mut CompileContext) { fn on_enter_code_indented(context: &mut CompileContext) { context.code_flow_seen_data = Some(false); context.line_ending_if_needed(); - context.push("<pre><code>".to_string()); + context.tag("<pre><code>".to_string()); } /// Handle [`Enter`][EventType::Enter]:[`CodeFenced`][TokenType::CodeFenced]. @@ -608,13 +614,13 @@ fn on_enter_code_fenced(context: &mut CompileContext) { context.code_flow_seen_data = Some(false); context.line_ending_if_needed(); // Note that no `>` is used, which is added later. - context.push("<pre><code".to_string()); + context.tag("<pre><code".to_string()); context.code_fenced_fences_count = Some(0); } /// Handle [`Enter`][EventType::Enter]:[`CodeText`][TokenType::CodeText]. fn on_enter_code_text(context: &mut CompileContext) { - context.push("<code>".to_string()); + context.tag("<code>".to_string()); context.buffer(); } @@ -662,7 +668,7 @@ fn on_enter_image(context: &mut CompileContext) { destination: None, title: None, }); - // tags = undefined // Disallow tags. + context.tags = false; // Disallow tags. } /// Handle [`Enter`][EventType::Enter]:[`Link`][TokenType::Link]. @@ -679,7 +685,7 @@ fn on_enter_link(context: &mut CompileContext) { /// Handle [`Enter`][EventType::Enter]:[`Paragraph`][TokenType::Paragraph]. fn on_enter_paragraph(context: &mut CompileContext) { - context.buf_tail_mut().push("<p>".to_string()); + context.tag("<p>".to_string()); } /// Handle [`Enter`][EventType::Enter]:[`Resource`][TokenType::Resource]. @@ -704,11 +710,16 @@ fn on_exit_autolink_email(context: &mut CompileContext) { &from_exit_event(context.events, context.index), false, ); - context.push(format!( - "<a href=\"mailto:{}\">{}</a>", - sanitize_uri(slice.as_str(), &context.protocol_href), - context.encode_opt(&slice) + // To do: + context.tag(format!( + "<a href=\"{}\">", + sanitize_uri( + format!("mailto:{}", slice.as_str()).as_str(), + &context.protocol_href + ) )); + context.push(context.encode_opt(&slice)); + context.tag("</a>".to_string()); } /// Handle [`Exit`][EventType::Exit]:[`AutolinkProtocol`][TokenType::AutolinkProtocol]. @@ -718,16 +729,17 @@ fn on_exit_autolink_protocol(context: &mut CompileContext) { &from_exit_event(context.events, context.index), false, ); - context.push(format!( - "<a href=\"{}\">{}</a>", - sanitize_uri(slice.as_str(), &context.protocol_href), - context.encode_opt(&slice) + context.tag(format!( + "<a href=\"{}\">", + sanitize_uri(slice.as_str(), &context.protocol_href) )); + context.push(context.encode_opt(&slice)); + context.tag("</a>".to_string()); } /// Handle [`Exit`][EventType::Exit]:{[`HardBreakEscape`][TokenType::HardBreakEscape],[`HardBreakTrailing`][TokenType::HardBreakTrailing]}. fn on_exit_break(context: &mut CompileContext) { - context.push("<br />".to_string()); + context.tag("<br />".to_string()); } /// Handle [`Exit`][EventType::Exit]:[`CharacterReferenceMarker`][TokenType::CharacterReferenceMarker]. @@ -785,8 +797,7 @@ fn on_exit_code_fenced_fence(context: &mut CompileContext) { }; if count == 0 { - context.push(">".to_string()); - // tag = true; + context.tag(">".to_string()); context.slurp_one_line_ending = true; } @@ -796,8 +807,7 @@ fn on_exit_code_fenced_fence(context: &mut CompileContext) { /// Handle [`Exit`][EventType::Exit]:[`CodeFencedFenceInfo`][TokenType::CodeFencedFenceInfo]. fn on_exit_code_fenced_fence_info(context: &mut CompileContext) { let value = context.resume(); - context.push(format!(" class=\"language-{}\"", value)); - // tag = true; + context.tag(format!(" class=\"language-{}\"", value)); } /// Handle [`Exit`][EventType::Exit]:{[`CodeFenced`][TokenType::CodeFenced],[`CodeIndented`][TokenType::CodeIndented]}. @@ -823,7 +833,7 @@ fn on_exit_code_flow(context: &mut CompileContext) { context.line_ending_if_needed(); } - context.push("</code></pre>".to_string()); + context.tag("</code></pre>".to_string()); if let Some(count) = context.code_fenced_fences_count.take() { if count < 2 { @@ -855,7 +865,7 @@ fn on_exit_code_text(context: &mut CompileContext) { } else { result }); - context.push("</code>".to_string()); + context.tag("</code>".to_string()); } /// Handle [`Exit`][EventType::Exit]:[`CodeTextLineEnding`][TokenType::CodeTextLineEnding]. @@ -873,7 +883,6 @@ fn on_exit_drop(context: &mut CompileContext) { /// Handle [`Exit`][EventType::Exit]:{[`CodeTextData`][TokenType::CodeTextData],[`Data`][TokenType::Data],[`CharacterEscapeValue`][TokenType::CharacterEscapeValue]}. fn on_exit_data(context: &mut CompileContext) { // Just output it. - // last_was_tag = false; context.push(context.encode_opt(&serialize( context.codes, &from_exit_event(context.events, context.index), @@ -930,7 +939,7 @@ fn on_exit_heading_atx(context: &mut CompileContext) { .take() .expect("`atx_opening_sequence_size` must be set in headings"); - context.push(format!("</h{}>", rank)); + context.tag(format!("</h{}>", rank)); } /// Handle [`Exit`][EventType::Exit]:[`HeadingAtxSequence`][TokenType::HeadingAtxSequence]. @@ -944,7 +953,7 @@ fn on_exit_heading_atx_sequence(context: &mut CompileContext) { ) .len(); context.atx_opening_sequence_size = Some(rank); - context.push(format!("<h{}>", rank)); + context.tag(format!("<h{}>", rank)); } } @@ -973,7 +982,9 @@ fn on_exit_heading_setext_underline(context: &mut CompileContext) { )[0]; let level: usize = if head == Code::Char('-') { 2 } else { 1 }; - context.push(format!("<h{}>{}</h{}>", level, text, level)); + context.tag(format!("<h{}>", level)); + context.push(text); + context.tag(format!("</h{}>", level)); } /// Handle [`Exit`][EventType::Exit]:{[`HtmlFlow`][TokenType::HtmlFlow],[`HtmlText`][TokenType::HtmlText]}. @@ -988,7 +999,6 @@ fn on_exit_html_data(context: &mut CompileContext) { &from_exit_event(context.events, context.index), false, ); - // last_was_tag = false; context.push(context.encode_opt(&slice)); } @@ -1029,6 +1039,7 @@ fn on_exit_line_ending(context: &mut CompileContext) { fn on_exit_media(context: &mut CompileContext) { let mut is_in_image = false; let mut index = 0; + // Skip current. while index < (context.media_stack.len() - 1) { if context.media_stack[index].image { @@ -1038,7 +1049,7 @@ fn on_exit_media(context: &mut CompileContext) { index += 1; } - // context.tags = is_in_image; + context.tags = !is_in_image; let media = context.media_stack.pop().unwrap(); let id = media @@ -1070,28 +1081,27 @@ fn on_exit_media(context: &mut CompileContext) { "".to_string() }; - let result = if media.image { - format!( - "<img src=\"{}\" alt=\"{}\"{} />", + if media.image { + context.tag(format!( + "<img src=\"{}\" alt=\"", sanitize_uri(&destination, &context.protocol_src), - label, - title - ) + )); + context.push(label); + context.tag(format!("\"{} />", title)); } else { - format!( - "<a href=\"{}\"{}>{}</a>", + context.tag(format!( + "<a href=\"{}\"{}>", sanitize_uri(&destination, &context.protocol_href), title, - label - ) + )); + context.push(label); + context.tag("</a>".to_string()); }; - - context.push(result); } /// Handle [`Exit`][EventType::Exit]:[`Paragraph`][TokenType::Paragraph]. fn on_exit_paragraph(context: &mut CompileContext) { - context.push("</p>".to_string()); + context.tag("</p>".to_string()); } /// Handle [`Exit`][EventType::Exit]:[`ReferenceString`][TokenType::ReferenceString]. @@ -1123,5 +1133,5 @@ fn on_exit_resource_title_string(context: &mut CompileContext) { /// Handle [`Exit`][EventType::Exit]:[`ThematicBreak`][TokenType::ThematicBreak]. fn on_exit_thematic_break(context: &mut CompileContext) { - context.push("<hr />".to_string()); + context.tag("<hr />".to_string()); } diff --git a/tests/heading_setext.rs b/tests/heading_setext.rs index 92a5b43..ecf22a8 100644 --- a/tests/heading_setext.rs +++ b/tests/heading_setext.rs @@ -3,28 +3,28 @@ use micromark::micromark; #[test] fn heading_setext() { - // To do: emphasis. + // To do: attention. // assert_eq!( // micromark("Foo *bar*\n========="), // "<h1>Foo <em>bar</em></h1>", // "should support a heading w/ an equals to (rank of 1)" // ); - // To do: emphasis. + // To do: attention. // assert_eq!( // micromark("Foo *bar*\n---------"), // "<h2>Foo <em>bar</em></h2>", // "should support a heading w/ a dash (rank of 2)" // ); - // To do: emphasis. + // To do: attention. // assert_eq!( // micromark("Foo *bar\nbaz*\n===="), // "<h1>Foo <em>bar\nbaz</em></h1>", // "should support line endings in setext headings" // ); - // To do: emphasis, trim. + // To do: attention, trim. // assert_eq!( // micromark(" Foo *bar\nbaz*\t\n===="), // "<h1>Foo <em>bar\nbaz</em></h1>", diff --git a/tests/image.rs b/tests/image.rs index 9be056f..68b9717 100644 --- a/tests/image.rs +++ b/tests/image.rs @@ -14,35 +14,33 @@ fn image() { "should support image w/ resource" ); - // To do: attention, tags in images. + // To do: attention. // assert_eq!( // micromark("[foo *bar*]: train.jpg \"train & tracks\"\n\n![foo *bar*]"), // "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>", // "should support image as shortcut reference" // ); - // To do: tags in images. - // assert_eq!( - // micromark("![foo ![bar](/url)](/url2)"), - // "<p><img src=\"/url2\" alt=\"foo bar\" /></p>", - // "should “support” images in images" - // ); + assert_eq!( + micromark("![foo ![bar](/url)](/url2)"), + "<p><img src=\"/url2\" alt=\"foo bar\" /></p>", + "should “support” images in images" + ); - // To do: tags in images. - // assert_eq!( - // micromark("![foo [bar](/url)](/url2)"), - // "<p><img src=\"/url2\" alt=\"foo bar\" /></p>", - // "should “support” links in images" - // ); + assert_eq!( + micromark("![foo [bar](/url)](/url2)"), + "<p><img src=\"/url2\" alt=\"foo bar\" /></p>", + "should “support” links in images" + ); - // To do: attention, tags in images. + // To do: attention. // assert_eq!( // micromark("[foo *bar*]: train.jpg \"train & tracks\"\n\n![foo *bar*][]"), // "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>", // "should support “content” in images" // ); - // To do: attention, tags in images. + // To do: attention. // assert_eq!( // micromark("[FOOBAR]: train.jpg \"train & tracks\"\n\n![foo *bar*][foobar]"), // "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>", @@ -91,7 +89,7 @@ fn image() { "should support collapsed references (1)" ); - // To do: attention, tags in images. + // To do: attention. // assert_eq!( // micromark("[*foo* bar]: /url \"title\"\n\n![*foo* bar][]"), // "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>", @@ -117,7 +115,7 @@ fn image() { "should support shortcut references (1)" ); - // To do: attention, tags in images. + // To do: attention. // assert_eq!( // micromark("[*foo* bar]: /url \"title\"\n\n![*foo* bar]"), // "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>", diff --git a/tests/link_resource.rs b/tests/link_resource.rs index 992c7d2..d75736e 100644 --- a/tests/link_resource.rs +++ b/tests/link_resource.rs @@ -257,12 +257,11 @@ fn link_resource() { // "should not support links in links (2)" // ); - // To do: tags in images. - // assert_eq!( - // micromark("![[[foo](uri1)](uri2)](uri3)"), - // "<p><img src=\"uri3\" alt=\"[foo](uri2)\" /></p>", - // "should not support links in links (3)" - // ); + assert_eq!( + micromark("![[[foo](uri1)](uri2)](uri3)"), + "<p><img src=\"uri3\" alt=\"[foo](uri2)\" /></p>", + "should not support links in links (3)" + ); assert_eq!( micromark("*[foo*](/uri)"), |