Skip to content

Commit

Permalink
Removed support for redundant NodeMathBlock
Browse files Browse the repository at this point in the history
Inline parsing of $$ handles the block style
while providing better compatability
with other parsers.
  • Loading branch information
digitalmoksha committed Mar 28, 2024
1 parent 5fa3106 commit 003f777
Show file tree
Hide file tree
Showing 10 changed files with 20 additions and 711 deletions.
41 changes: 2 additions & 39 deletions src/cm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::ctype::{isalpha, isdigit, ispunct, isspace};
use crate::nodes::TableAlignment;
use crate::nodes::{
AstNode, ListDelimType, ListType, NodeCodeBlock, NodeHeading, NodeHtmlBlock, NodeLink,
NodeMath, NodeMathBlock, NodeTable, NodeValue,
NodeMath, NodeTable, NodeValue,
};
#[cfg(feature = "shortcodes")]
use crate::parser::shortcodes::NodeShortCode;
Expand Down Expand Up @@ -382,7 +382,6 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
// noop - automatic escaping is already being done
}
NodeValue::Math(ref math) => self.format_math(math, allow_wrap, entering),
NodeValue::MathBlock(ref nmb) => self.format_math_block(node, nmb, entering),
};
true
}
Expand Down Expand Up @@ -410,7 +409,7 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
&& match node.next_sibling() {
Some(next_sibling) => matches!(
next_sibling.data.borrow().value,
NodeValue::CodeBlock(..) | NodeValue::List(..) | NodeValue::MathBlock(..)
NodeValue::CodeBlock(..) | NodeValue::List(..)
),
_ => false,
}
Expand Down Expand Up @@ -804,42 +803,6 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
self.output(end_fence.as_bytes(), false, Escaping::Literal);
}
}

fn format_math_block(&mut self, node: &'a AstNode<'a>, nmb: &NodeMathBlock, entering: bool) {
if entering {
let literal = nmb.literal.as_bytes();
let fence_char = "$";
let fence_length = 2;
let first_in_list_item = node.previous_sibling().is_none()
&& match node.parent() {
Some(parent) => {
matches!(
parent.data.borrow().value,
NodeValue::Item(..) | NodeValue::TaskItem(..)
)
}
_ => false,
};

if !first_in_list_item {
self.blankline();
}

for _ in 0..fence_length {
write!(self, "{}", fence_char).unwrap();
}

self.cr();
self.write_all(literal).unwrap();
self.cr();

for _ in 0..fence_length {
write!(self, "{}", fence_char).unwrap();
}

self.blankline();
}
}
}

fn longest_char_sequence(literal: &[u8], ch: u8) -> usize {
Expand Down
38 changes: 2 additions & 36 deletions src/html.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! The HTML renderer for the CommonMark AST, as well as helper functions.
use crate::ctype::isspace;
use crate::nodes::{
AstNode, ListType, NodeCode, NodeFootnoteDefinition, NodeMath, NodeMathBlock, NodeTable,
NodeValue, TableAlignment,
AstNode, ListType, NodeCode, NodeFootnoteDefinition, NodeMath, NodeTable, NodeValue,
TableAlignment,
};
use crate::parser::{Options, Plugins};
use crate::scanners;
Expand Down Expand Up @@ -1038,11 +1038,6 @@ impl<'o> HtmlFormatter<'o> {
self.render_math_inline(node, literal, display_math, dollar_math)?;
}
}
NodeValue::MathBlock(NodeMathBlock { ref literal, .. }) => {
if entering {
self.render_math_dollar_block(node, literal)?;
}
}
}
Ok(false)
}
Expand Down Expand Up @@ -1112,35 +1107,6 @@ impl<'o> HtmlFormatter<'o> {
Ok(())
}

// Renders a math dollar block, `$$\n...\n$$` using `<p><span>` to be similar
// to other renderers.
fn render_math_dollar_block<'a>(
&mut self,
node: &'a AstNode<'a>,
literal: &String,
) -> io::Result<()> {
self.cr()?;

// use vectors to ensure attributes always written in the same order,
// for testing stability
let mut p_attributes: Vec<(String, String)> = Vec::new();
let span_attributes: Vec<(String, String)> =
vec![(String::from("data-math-style"), String::from("display"))];

if self.options.render.sourcepos {
let ast = node.data.borrow();
p_attributes.push(("data-sourcepos".to_string(), ast.sourcepos.to_string()));
}

write_opening_tag(self.output, "p", p_attributes)?;
write_opening_tag(self.output, "span", span_attributes)?;

self.escape(literal.as_bytes())?;
self.output.write_all(b"</span></p>\n")?;

Ok(())
}

// Renders a math code block, ```` ```math ```` using `<pre><code>`
fn render_math_code_block<'a>(
&mut self,
Expand Down
22 changes: 4 additions & 18 deletions src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::convert::TryFrom;
#[cfg(feature = "shortcodes")]
pub use crate::parser::shortcodes::NodeShortCode;

pub use crate::parser::math::{NodeMath, NodeMathBlock};
pub use crate::parser::math::NodeMath;
pub use crate::parser::multiline_block_quote::NodeMultilineBlockQuote;

/// The core AST node enum.
Expand Down Expand Up @@ -160,20 +160,12 @@ pub enum NodeValue {
///
/// Inline math $1 + 2$ and $`1 + 2`$
///
/// Display math $$1 + 2$$
Math(NodeMath),

/// **Block**. A math block. Contains raw text which is not parsed as Markdown.
/// Dollar math or code math
///
/// Display math $$1 + 2$$ and
/// $$
/// 1 + 2
/// $$
///
/// ```math
/// 1 + 2
/// ```
MathBlock(NodeMathBlock),
Math(NodeMath),

/// **Block**. A [multiline block quote](https://github.github.com/gfm/#block-quotes). Spans multiple
/// lines and contains other **blocks**.
Expand Down Expand Up @@ -431,7 +423,6 @@ impl NodeValue {
| NodeValue::TableCell
| NodeValue::TaskItem(..)
| NodeValue::MultilineBlockQuote(_)
| NodeValue::MathBlock(..)
)
}

Expand Down Expand Up @@ -466,10 +457,7 @@ impl NodeValue {
pub(crate) fn accepts_lines(&self) -> bool {
matches!(
*self,
NodeValue::Paragraph
| NodeValue::Heading(..)
| NodeValue::CodeBlock(..)
| NodeValue::MathBlock(..)
NodeValue::Paragraph | NodeValue::Heading(..) | NodeValue::CodeBlock(..)
)
}

Expand Down Expand Up @@ -510,9 +498,7 @@ impl NodeValue {
NodeValue::ShortCode(_) => "shortcode",
NodeValue::MultilineBlockQuote(_) => "multiline_block_quote",
NodeValue::Escaped => "escaped",
NodeValue::MathBlock(..) => "math_block",
NodeValue::Math(..) => "math",
NodeValue::MathBlock(..) => "math_block",
}
}
}
Expand Down
18 changes: 0 additions & 18 deletions src/parser/math.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
// use crate::nodes::{Ast, AstNode, NodeValue};
// use crate::parser::Parser;
// use crate::scanners;
// use crate::strings;

/// An inline math span
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NodeMath {
Expand All @@ -19,16 +14,3 @@ pub struct NodeMath {
/// rather than inserted into a child inline of any kind.
pub literal: String,
}

/// A math block using `$$`
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct NodeMathBlock {
/// The indentation level of the math within the block.
pub fence_offset: usize,

/// The literal contents of the math block.
/// As the contents are not interpreted as Markdown at all,
/// they are contained within this structure,
/// rather than inserted into a child block of any kind.
pub literal: String,
}
87 changes: 2 additions & 85 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use std::str;
use typed_arena::Arena;

use crate::adapters::HeadingAdapter;
use crate::parser::math::NodeMathBlock;
use crate::parser::multiline_block_quote::NodeMultilineBlockQuote;

use self::inlines::RefMap;
Expand Down Expand Up @@ -384,7 +383,7 @@ pub struct ExtensionOptions {
/// assert_eq!(markdown_to_html("$1 + 2$ and $$x = y$$", &options),
/// "<p><span data-math-style=\"inline\">1 + 2</span> and <span data-math-style=\"display\">x = y</span></p>\n");
/// assert_eq!(markdown_to_html("$$\nx^2\n$$\n", &options),
/// "<p><span data-math-style=\"display\">x^2\n</span></p>\n");
/// "<p><span data-math-style=\"display\">\nx^2\n</span></p>\n");
/// ```
pub math_dollars: bool,

Expand Down Expand Up @@ -1062,11 +1061,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
return (false, container, should_continue);
}
}
NodeValue::MathBlock(..) => {
if !self.parse_math_block_prefix(line, container, ast, &mut should_continue) {
return (false, container, should_continue);
}
}
_ => {}
}
}
Expand All @@ -1083,7 +1077,7 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {

while !node_matches!(
container,
NodeValue::CodeBlock(..) | NodeValue::HtmlBlock(..) | NodeValue::MathBlock(..)
NodeValue::CodeBlock(..) | NodeValue::HtmlBlock(..)
) {
depth += 1;
self.find_first_nonspace(line);
Expand Down Expand Up @@ -1172,25 +1166,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
self.first_nonspace + 1,
);
self.advance_offset(line, first_nonspace + matched - offset, false);
} else if !indented
&& self.options.extension.math_dollars
&& unwrap_into(
scanners::open_math_fence(&line[self.first_nonspace..]),
&mut matched,
)
{
let first_nonspace = self.first_nonspace;
let offset = self.offset;
let nmb = NodeMathBlock {
fence_offset: first_nonspace - offset,
literal: String::new(),
};
*container = self.add_child(
container,
NodeValue::MathBlock(nmb),
self.first_nonspace + 1,
);
self.advance_offset(line, first_nonspace + matched - offset, false);
} else if !indented
&& (unwrap_into(
scanners::html_block_start(&line[self.first_nonspace..]),
Expand Down Expand Up @@ -1505,41 +1480,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
true
}

fn parse_math_block_prefix(
&mut self,
line: &[u8],
container: &'a AstNode<'a>,
ast: &mut Ast,
should_continue: &mut bool,
) -> bool {
let fence_char = b'$';
let fence_length = 2;
let fence_offset = match ast.value {
NodeValue::MathBlock(ref nmb) => nmb.fence_offset,
_ => unreachable!(),
};

let matched = if self.indent <= 3 && line[self.first_nonspace] == fence_char {
scanners::close_math_fence(&line[self.first_nonspace..]).unwrap_or(0)
} else {
0
};

if matched >= fence_length {
*should_continue = false;
self.advance_offset(line, matched, false);
self.current = self.finalize_borrowed(container, ast).unwrap();
return false;
}

let mut i = fence_offset;
while i > 0 && strings::is_space_or_tab(line[self.offset]) {
self.advance_offset(line, 1, true);
i -= 1;
}
true
}

fn parse_html_block_prefix(&mut self, t: u8) -> bool {
match t {
1 | 2 | 3 | 4 | 5 => true,
Expand Down Expand Up @@ -1707,7 +1647,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
|| container.data.borrow().sourcepos.start.line != self.line_number
}
NodeValue::MultilineBlockQuote(..) => false,
NodeValue::MathBlock(..) => false,
_ => true,
};

Expand All @@ -1731,7 +1670,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
let add_text_result = match container.data.borrow().value {
NodeValue::CodeBlock(..) => AddTextResult::LiteralText,
NodeValue::HtmlBlock(ref nhb) => AddTextResult::HtmlBlock(nhb.block_type),
NodeValue::MathBlock(..) => AddTextResult::LiteralText,
_ => AddTextResult::Otherwise,
};

Expand Down Expand Up @@ -1890,7 +1828,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
NodeValue::CodeBlock(ref ncb) => ncb.fenced,
NodeValue::Heading(ref nh) => nh.setext,
NodeValue::MultilineBlockQuote(..) => true,
NodeValue::MathBlock(..) => true,
_ => false,
} {
ast.sourcepos.end = (self.line_number, self.curline_end_col).into();
Expand Down Expand Up @@ -1975,26 +1912,6 @@ impl<'a, 'o, 'c> Parser<'a, 'o, 'c> {
ch = item.next_sibling();
}
}
NodeValue::MathBlock(ref mut nmb) => {
let mut pos = 0;
while pos < content.len() {
if strings::is_line_end_char(content.as_bytes()[pos]) {
break;
}
pos += 1;
}
assert!(pos < content.len());

if content.as_bytes()[pos] == b'\r' {
pos += 1;
}
if content.as_bytes()[pos] == b'\n' {
pos += 1;
}

content.drain(..pos);
mem::swap(&mut nmb.literal, content);
}
_ => (),
}

Expand Down
Loading

0 comments on commit 003f777

Please sign in to comment.