From bf459e248576b4142dc6e1b39213845a2acc7f72 Mon Sep 17 00:00:00 2001 From: digitalMoksha Date: Sat, 18 Jan 2025 14:15:16 -0600 Subject: [PATCH] Add `alerts` extension option --- README.md | 2 +- fuzz/fuzz_targets/all_options.rs | 1 + fuzz/fuzz_targets/quadratic.rs | 8 +++++ script/cibuild | 2 +- src/main.rs | 2 ++ src/parser/mod.rs | 20 ++++++++++-- src/tests.rs | 1 + src/tests/alerts.rs | 56 ++++++++++++++++++++++++++++++++ src/tests/api.rs | 3 +- src/tests/commonmark.rs | 2 +- 10 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/tests/alerts.rs diff --git a/README.md b/README.md index d496052d..af1264ec 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ Options: [possible values: strikethrough, tagfilter, table, autolink, tasklist, superscript, footnotes, description-lists, multiline-block-quotes, math-dollars, math-code, wikilinks-title-after-pipe, wikilinks-title-before-pipe, underline, subscript, spoiler, - greentext] + greentext, alerts] -t, --to Specify output format diff --git a/fuzz/fuzz_targets/all_options.rs b/fuzz/fuzz_targets/all_options.rs index 9831e905..37c90e91 100644 --- a/fuzz/fuzz_targets/all_options.rs +++ b/fuzz/fuzz_targets/all_options.rs @@ -29,6 +29,7 @@ fuzz_target!(|s: &str| { extension.underline = true; extension.spoiler = true; extension.greentext = true; + extension.alerts = true; let mut parse = ParseOptions::default(); parse.smart = true; diff --git a/fuzz/fuzz_targets/quadratic.rs b/fuzz/fuzz_targets/quadratic.rs index 2c0addbc..373bc2fe 100644 --- a/fuzz/fuzz_targets/quadratic.rs +++ b/fuzz/fuzz_targets/quadratic.rs @@ -197,6 +197,10 @@ struct FuzzExtensionOptions { shortcodes: bool, wikilinks_title_after_pipe: bool, wikilinks_title_before_pipe: bool, + underline: bool, + spoiler: bool, + greentext: bool, + alerts: bool, } impl FuzzExtensionOptions { @@ -216,6 +220,10 @@ impl FuzzExtensionOptions { extension.shortcodes = self.shortcodes; extension.wikilinks_title_after_pipe = self.wikilinks_title_after_pipe; extension.wikilinks_title_before_pipe = self.wikilinks_title_before_pipe; + extension.underline = self.underline; + extension.spoiler = self.spoiler; + extension.greentext = self.greentext; + extension.alerts = self.alerts; extension.front_matter_delimiter = None; extension.header_ids = None; extension diff --git a/script/cibuild b/script/cibuild index e5139222..d757412f 100755 --- a/script/cibuild +++ b/script/cibuild @@ -50,7 +50,7 @@ python3 spec_tests.py --no-normalize --spec ../../../src/tests/fixtures/wikilink || failed=1 python3 spec_tests.py --no-normalize --spec ../../../src/tests/fixtures/description_lists.md "$PROGRAM_ARG -e description-lists" \ || failed=1 -python3 spec_tests.py --no-normalize --spec ../../../src/tests/fixtures/alerts.md "$PROGRAM_ARG -e description-lists" \ +python3 spec_tests.py --no-normalize --spec ../../../src/tests/fixtures/alerts.md "$PROGRAM_ARG -e alerts" \ || failed=1 python3 spec_tests.py --no-normalize --spec regression.txt "$PROGRAM_ARG" \ diff --git a/src/main.rs b/src/main.rs index f9bd64ad..43698ef7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -187,6 +187,7 @@ enum Extension { Subscript, Spoiler, Greentext, + Alerts, } #[derive(Clone, Copy, Debug, ValueEnum)] @@ -271,6 +272,7 @@ fn main() -> Result<(), Box> { .subscript(exts.contains(&Extension::Subscript)) .spoiler(exts.contains(&Extension::Spoiler)) .greentext(exts.contains(&Extension::Greentext)) + .alerts(exts.contains(&Extension::Alerts)) .maybe_front_matter_delimiter(cli.front_matter_delimiter); #[cfg(feature = "shortcodes")] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5a4cdf1e..66f023aa 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -422,8 +422,23 @@ pub struct ExtensionOptions<'c> { #[cfg_attr(feature = "bon", builder(default))] pub multiline_block_quotes: bool, - // #[cfg_attr(feature = "bon", builder(default))] - // pub alerts: bool, + /// Enables GitHub style alerts + /// + /// ```md + /// > [!note] + /// > Something of note + /// ``` + /// + /// ``` + /// # use comrak::{markdown_to_html, Options}; + /// let mut options = Options::default(); + /// options.extension.alerts = true; + /// assert_eq!(markdown_to_html("> [!note]\n> Something of note", &options), + /// "
\n

Note

\n

Something of note

\n
\n"); + /// ``` + #[cfg_attr(feature = "bon", builder(default))] + pub alerts: bool, + /// Enables math using dollar syntax. /// /// ``` md @@ -1996,6 +2011,7 @@ where fn detect_alert(&mut self, line: &[u8], indented: bool, alert_type: &mut AlertType) -> bool { !indented + && self.options.extension.alerts && line[self.first_nonspace] == b'>' && unwrap_into( scanners::alert_start(&line[self.first_nonspace..]), diff --git a/src/tests.rs b/src/tests.rs index af8c1c31..2d38fac2 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use std::io::{self, Write}; use std::panic; +mod alerts; mod api; mod autolink; mod commonmark; diff --git a/src/tests/alerts.rs b/src/tests/alerts.rs new file mode 100644 index 00000000..4386f1f7 --- /dev/null +++ b/src/tests/alerts.rs @@ -0,0 +1,56 @@ +use super::*; + +#[test] +fn alerts() { + html_opts!( + [extension.alerts], + concat!("> [!note]\n", "> Pay attention\n",), + concat!( + "
\n", + "

Note

\n", + "

Pay attention

\n", + "
\n", + ), + ); +} + +#[test] +fn sourcepos() { + assert_ast_match!( + [extension.alerts], + "> [!note]\n" + "> Pay attention\n", + (document (1:1-2:15) [ + (alert (1:1-2:15) [ + (paragraph (2:3-2:15) [ + (text (2:3-2:15) "Pay attention") + ]) + ]) + ]) + ); +} + +#[test] +fn sourcepos_in_list() { + assert_ast_match!( + [extension.alerts], + "- item one\n" + "\n" + " > [!note]\n" + " > Pay attention\n", + (document (1:1-4:17) [ + (list (1:1-4:17) [ + (item (1:1-4:17) [ + (paragraph (1:3-1:10) [ + (text (1:3-1:10) "item one") + ]) + (alert (3:3-4:17) [ + (paragraph (4:5-4:17) [ + (text (4:5-4:17) "Pay attention") + ]) + ]) + ]) + ]) + ]) + ); +} diff --git a/src/tests/api.rs b/src/tests/api.rs index 47d8a654..7e6ed094 100644 --- a/src/tests/api.rs +++ b/src/tests/api.rs @@ -75,7 +75,8 @@ fn exercise_full_api() { .underline(true) .subscript(true) .spoiler(true) - .greentext(true); + .greentext(true) + .alerts(true); let parse = ParseOptions::builder() .smart(false) diff --git a/src/tests/commonmark.rs b/src/tests/commonmark.rs index 46dc75d1..8cce1917 100644 --- a/src/tests/commonmark.rs +++ b/src/tests/commonmark.rs @@ -111,7 +111,7 @@ fn commonmark_relist() { #[test_case("> [!note] Title\n> A note", "> [!NOTE] Title\n> A note\n")] fn commonmark_alerts(markdown: &str, cm: &str) { let mut options = Options::default(); - options.extension.wikilinks_title_before_pipe = true; + options.extension.alerts = true; commonmark(markdown, cm, Some(&options)); }