")?;
+ self.output.write_all(b"")?;
self.escape(literal.as_bytes())?;
self.output.write_all(b"
")?;
}
@@ -771,47 +783,67 @@ impl<'o, 'c: 'o> HtmlFormatter<'o, 'c> {
}
}
NodeValue::Strong => {
- // No sourcepos.
+ // Unreliable sourcepos.
let parent_node = node.parent();
if !self.options.render.gfm_quirks
|| (parent_node.is_none()
|| !matches!(parent_node.unwrap().data.borrow().value, NodeValue::Strong))
{
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
}
NodeValue::Emph => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
NodeValue::Strikethrough => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
NodeValue::Superscript => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
NodeValue::Link(ref nl) => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b" HtmlFormatter<'o, 'c> {
}
}
NodeValue::Image(ref nl) => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b" HtmlFormatter<'o, 'c> {
}
#[cfg(feature = "shortcodes")]
NodeValue::ShortCode(ref nsc) => {
+ // Nowhere to put sourcepos.
if entering {
self.output.write_all(nsc.emoji.as_bytes())?;
}
@@ -941,14 +978,17 @@ impl<'o, 'c: 'o> HtmlFormatter<'o, 'c> {
}
}
NodeValue::FootnoteDefinition(ref nfd) => {
- // No sourcepos.
if entering {
if self.footnote_ix == 0 {
+ self.output.write_all(b"\n\n")?;
+ .write_all(b" class=\"footnotes\" data-footnotes>\n\n")?;
}
self.footnote_ix += 1;
- self.output.write_all(b"- ")?;
} else {
@@ -959,14 +999,19 @@ impl<'o, 'c: 'o> HtmlFormatter<'o, 'c> {
}
}
NodeValue::FootnoteReference(ref nfr) => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
let mut ref_id = format!("fnref-{}", nfr.name);
if nfr.ref_num > 1 {
ref_id = format!("{}-{}", ref_id, nfr.ref_num);
}
+
+ self.output.write_all(b" HtmlFormatter<'o, 'c> {
}
}
NodeValue::Escaped => {
- // No sourcepos.
+ // Unreliable sourcepos.
if self.options.render.escaped_char_spans {
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
@@ -1024,9 +1073,13 @@ impl<'o, 'c: 'o> HtmlFormatter<'o, 'c> {
}
}
NodeValue::WikiLink(ref nl) => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b" HtmlFormatter<'o, 'c> {
}
}
NodeValue::Underline => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
NodeValue::SpoileredText => {
- // No sourcepos.
+ // Unreliable sourcepos.
if entering {
- self.output.write_all(b"")?;
+ self.output.write_all(b"")?;
} else {
self.output.write_all(b"")?;
}
}
NodeValue::EscapedTag(ref net) => {
- // No sourcepos.
+ // Nowhere to put sourcepos.
self.output.write_all(net.as_bytes())?;
}
}
@@ -1114,7 +1175,8 @@ impl<'o, 'c: 'o> HtmlFormatter<'o, 'c> {
tag_attributes.push((String::from("data-math-style"), String::from(style_attr)));
- if self.options.render.sourcepos {
+ // Unreliable sourcepos.
+ if self.options.render.experimental_inline_sourcepos && self.options.render.sourcepos {
let ast = node.data.borrow();
tag_attributes.push(("data-sourcepos".to_string(), ast.sourcepos.to_string()));
}
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index b6987a97..fed397bc 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -761,19 +761,35 @@ pub struct RenderOptions {
/// extensions. The description lists extension still has issues; see
///
.
///
- /// Sourcepos information is **not** reliable for inlines. See
- /// for a discussion.
+ /// Sourcepos information is **not** reliable for inlines, and is not
+ /// included in HTML without also setting [`experimental_inline_sourcepos`].
+ /// See for a discussion.
///
/// ```rust
/// # use comrak::{markdown_to_commonmark_xml, Options};
/// let mut options = Options::default();
/// options.render.sourcepos = true;
- /// let input = "Hello *world*!";
+ /// let input = "## Hello world!";
/// let xml = markdown_to_commonmark_xml(input, &options);
- /// assert!(xml.contains(""));
+ /// assert!(xml.contains(""));
/// ```
pub sourcepos: bool,
+ /// Include inline sourcepos in HTML output, which is known to have issues.
+ /// See for a discussion.
+ /// ```rust
+ /// # use comrak::{markdown_to_html, Options};
+ /// let mut options = Options::default();
+ /// options.render.sourcepos = true;
+ /// let input = "Hello *world*!";
+ /// assert_eq!(markdown_to_html(input, &options),
+ /// "Hello world!
\n");
+ /// options.render.experimental_inline_sourcepos = true;
+ /// assert_eq!(markdown_to_html(input, &options),
+ /// "Hello world!
\n");
+ /// ```
+ pub experimental_inline_sourcepos: bool,
+
/// Wrap escaped characters in a `` to allow any
/// post-processing to recognize them.
///