Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fuzz/fuzz_targets/all_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ struct FuzzRenderOptions {
r#unsafe: bool,
escape: bool,
list_style: options::ListStyleType,
alert_style: options::AlertStyleType,
sourcepos: bool,
escaped_char_spans: bool,
ignore_empty_links: bool,
Expand All @@ -209,6 +210,7 @@ impl FuzzRenderOptions {
r#unsafe: self.r#unsafe,
escape: self.escape,
list_style: self.list_style,
alert_style: self.alert_style,
sourcepos: self.sourcepos,
escaped_char_spans: self.escaped_char_spans,
ignore_empty_links: self.ignore_empty_links,
Expand Down
2 changes: 2 additions & 0 deletions fuzz/fuzz_targets/quadratic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ struct FuzzRenderOptions {
r#unsafe: bool,
escape: bool,
list_style: options::ListStyleType,
alert_style: options::AlertStyleType,
sourcepos: bool,
escaped_char_spans: bool,
}
Expand All @@ -274,6 +275,7 @@ impl FuzzRenderOptions {
r#unsafe: self.r#unsafe,
escape: self.escape,
list_style: self.list_style,
alert_style: self.alert_style,
sourcepos: self.sourcepos,
escaped_char_spans: self.escaped_char_spans,
..Default::default()
Expand Down
25 changes: 20 additions & 5 deletions src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::nodes::{
NodeFootnoteReference, NodeHeading, NodeHtmlBlock, NodeLink, NodeList, NodeMath, NodeTaskItem,
NodeValue, NodeWikiLink, TableAlignment,
};
use crate::parser::options::{Options, Plugins};
use crate::parser::options::{AlertStyleType, Options, Plugins};
use crate::{node_matches, scanners};

#[doc(hidden)]
Expand Down Expand Up @@ -1284,13 +1284,25 @@ fn render_alert<T>(
) -> Result<ChildRendering, fmt::Error> {
if entering {
context.cr()?;
context.write_str("<div class=\"markdown-alert ")?;
context.write_str(alert.alert_type.css_class())?;
context.write_str(match context.options.render.alert_style {
AlertStyleType::Specific => "<div class=\"markdown-alert ",
AlertStyleType::Semantic => "<aside class=\"admonition ",
})?;
context.write_str(
alert
.alert_type
.css_class(context.options.render.alert_style),
)?;
context.write_str("\"")?;
render_sourcepos(context, node)?;
context.write_str(">")?;
context.lf()?;
context.write_str("<p class=\"markdown-alert-title\">")?;
context.write_str("<p class=\"")?;
context.write_str(match context.options.render.alert_style {
AlertStyleType::Specific => "markdown-alert-title",
AlertStyleType::Semantic => "admonition-title",
})?;
context.write_str("\">")?;
match alert.title {
Some(ref title) => context.escape(title)?,
None => {
Expand All @@ -1301,7 +1313,10 @@ fn render_alert<T>(
context.lf()?;
} else {
context.cr()?;
context.write_str("</div>")?;
context.write_str(match context.options.render.alert_style {
AlertStyleType::Specific => "</div>",
AlertStyleType::Semantic => "</aside>",
})?;
context.lf()?;
}

Expand Down
20 changes: 20 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ struct Cli {
#[arg(long, value_enum, default_value_t = ListStyle::Dash)]
list_style: ListStyle,

/// Specify alert style (<div> vs <aside>) in HTML output
#[arg(long, value_enum, default_value_t = AlertStyle::Specific)]
alert_style: AlertStyle,

/// Include source position attributes in HTML and XML output
#[arg(long)]
sourcepos: bool,
Expand Down Expand Up @@ -242,6 +246,21 @@ impl From<ListStyle> for options::ListStyleType {
}
}

#[derive(Clone, Copy, Debug, ValueEnum)]
enum AlertStyle {
Specific,
Semantic,
}

impl From<AlertStyle> for options::AlertStyleType {
fn from(style: AlertStyle) -> Self {
match style {
AlertStyle::Specific => Self::Specific,
AlertStyle::Semantic => Self::Semantic,
}
}
}

fn cli_with_config() -> Cli {
let cli = Cli::parse();
let config_file_path = &cli.config_file;
Expand Down Expand Up @@ -345,6 +364,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.r#unsafe(cli.r#unsafe)
.escape(cli.escape)
.list_style(cli.list_style.into())
.alert_style(cli.alert_style.into())
.sourcepos(cli.sourcepos)
.experimental_minimize_commonmark(cli.experimental_minimize_commonmark)
.compact_html(cli.compact)
Expand Down
21 changes: 13 additions & 8 deletions src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use std::borrow::Cow;
use std::cell::RefCell;
use std::convert::TryFrom;

use crate::arena_tree;
#[cfg(feature = "phoenix_heex")]
pub use crate::parser::phoenix_heex::{HeexNode, NodeHeexBlock};
#[cfg(feature = "shortcodes")]
pub use crate::parser::shortcodes::NodeShortCode;
use crate::{arena_tree, options::AlertStyleType};

/// Shorthand for checking if a node's value matches the given expression.
///
Expand Down Expand Up @@ -587,13 +587,18 @@ impl AlertType {
}

/// Returns the CSS class to use for an alert type
pub fn css_class(&self) -> &'static str {
match *self {
AlertType::Note => "markdown-alert-note",
AlertType::Tip => "markdown-alert-tip",
AlertType::Important => "markdown-alert-important",
AlertType::Warning => "markdown-alert-warning",
AlertType::Caution => "markdown-alert-caution",
pub fn css_class(&self, style: AlertStyleType) -> &'static str {
match (*self, style) {
(AlertType::Note, AlertStyleType::Specific) => "markdown-alert-note",
(AlertType::Note, AlertStyleType::Semantic) => "note",
(AlertType::Tip, AlertStyleType::Specific) => "markdown-alert-tip",
(AlertType::Tip, AlertStyleType::Semantic) => "tip",
(AlertType::Important, AlertStyleType::Specific) => "markdown-alert-important",
(AlertType::Important, AlertStyleType::Semantic) => "important",
(AlertType::Warning, AlertStyleType::Specific) => "markdown-alert-warning",
(AlertType::Warning, AlertStyleType::Semantic) => "warning",
(AlertType::Caution, AlertStyleType::Specific) => "markdown-alert-caution",
(AlertType::Caution, AlertStyleType::Semantic) => "caution",
}
}
}
Expand Down
29 changes: 28 additions & 1 deletion src/parser/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,22 @@ pub struct Render {
#[cfg_attr(feature = "bon", builder(default))]
pub tasklist_classes: bool,

/// How to render alert blocks. Options are:
///
/// * [`AlertStyleType::Specific`] to use `div`s with `markdown-` prefixed classes (default)
/// * [`AlertStyleType::Semantic`] to use `aside`s with an `admonition` class
///
/// ```rust
/// # use comrak::{markdown_to_html, Options, options::AlertStyleType};
/// let mut options = Options::default();
/// options.extension.alerts = true;
/// options.render.alert_style = AlertStyleType::Semantic;
/// assert_eq!(markdown_to_html("> [!note]\n> Something of note", &options),
/// "<aside class=\"admonition note\">\n<p class=\"admonition-title\">Note</p>\n<p>Something of note</p>\n</aside>\n");
/// ```
#[cfg_attr(feature = "bon", builder(default))]
pub alert_style: AlertStyleType,

/// Render ordered list with a minimum marker width.
/// Having a width lower than 3 doesn't do anything.
///
Expand Down Expand Up @@ -1386,7 +1402,7 @@ pub struct Render {

#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Options for bulleted list rendering in markdown. See `link_style` in [`Render`] for more details.
/// Options for bulleted list rendering in markdown. See [`Render::list_style`] for more details.
pub enum ListStyleType {
/// The `-` character
#[default]
Expand All @@ -1397,6 +1413,17 @@ pub enum ListStyleType {
Star = 42,
}

#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Options for alert rendering in markdown. See [`Render::alert_style`] for more details.
pub enum AlertStyleType {
/// `div`s with `class="markdown-alert markdown-alert-<type>"`
#[default]
Specific,
/// `aside`s with `class="admonition <type>"`, matching `docutils`' output
Semantic,
}

#[derive(Default, Debug, Clone)]
#[cfg_attr(feature = "bon", derive(Builder))]
/// Umbrella plugins struct.
Expand Down
17 changes: 17 additions & 0 deletions src/tests/alerts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ fn multiline_alerts() {
);
}

#[test]
fn semantic_alerts() {
html_opts!(
[
extension.alerts = true,
render.alert_style = options::AlertStyleType::Semantic
],
concat!("> [!note]\n", "> Pay attention\n",),
concat!(
"<aside class=\"admonition note\">\n",
"<p class=\"admonition-title\">Note</p>\n",
"<p>Pay attention</p>\n",
"</aside>\n",
),
);
}

#[test]
fn sourcepos() {
assert_ast_match!(
Expand Down
Loading