Skip to content

Commit

Permalink
Merge branch 'main' into trav-desc-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
kaesluder authored Apr 14, 2024
2 parents 209a4a8 + 2c2de3f commit a264526
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 4 deletions.
69 changes: 69 additions & 0 deletions examples/traverse_demo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use comrak::{
arena_tree::NodeEdge,
nodes::{AstNode, NodeValue},
parse_document, Arena, ComrakOptions,
};

// `node.traverse()`` creates an itertor that will traverse
// the current node and all descendants in order.
// The iterator yields `NodeEdges`. `NodeEdges` can have the
// following values:
//
// `NodeEdge::Start(node)` Start of node.
// `NodeEdge::End(node)` End of node.
// `None` End of iterator at bottom of last branch.
//
// This example extracts plain text ignoring nested
// markup.

// Note: root can be any AstNode, not just document root.

fn extract_text_traverse<'a>(root: &'a AstNode<'a>) -> String {
let mut output_text = String::new();

// Use `traverse` to get an iterator of `NodeEdge` and process each.
for edge in root.traverse() {
if let NodeEdge::Start(node) = edge {
// Handle the Start edge to process the node's value.
if let NodeValue::Text(ref text) = node.data.borrow().value {
// If the node is a text node, append its text to `output_text`.
output_text.push_str(text);
}
}
}

output_text
}

fn main() {
let markdown_input = "Hello, *worl[d](https://example.com/)*";
// Nested inline markup. Equivalent html should look like this:
//"<p>Hello, <em>worl<a href="https://example.com">d</a></em></p>

println!("INPUT: {}", markdown_input);

// setup parser
let arena = Arena::new();
let options = ComrakOptions::default();

// parse document and return root.
let root = parse_document(&arena, markdown_input, &options);

// extract text and print
println!("OUTPUT: {}", extract_text_traverse(root).as_str())
}

#[cfg(test)]
mod tests {
// Import everything from the outer module to make it available for tests
use super::*;

#[test]
fn extract_text_traverse_test() {
let markdown_input = "Hello, *worl[d](https://example.com/)*";
let arena = Arena::new();
let options = ComrakOptions::default();
let root = parse_document(&arena, markdown_input, &options);
assert_eq!("Hello, world", extract_text_traverse(root));
}
}
2 changes: 1 addition & 1 deletion fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions src/cm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
)
&& self.get_in_tight_list_item(node);
}
let next_is_block = node
.next_sibling()
.map_or(true, |next| next.data.borrow().value.block());

match node.data.borrow().value {
NodeValue::Document => (),
Expand All @@ -345,7 +348,7 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
NodeValue::Text(ref literal) => {
self.format_text(literal.as_bytes(), allow_wrap, entering)
}
NodeValue::LineBreak => self.format_line_break(entering),
NodeValue::LineBreak => self.format_line_break(entering, next_is_block),
NodeValue::SoftBreak => self.format_soft_break(allow_wrap, entering),
NodeValue::Code(ref code) => {
self.format_code(code.literal.as_bytes(), allow_wrap, entering)
Expand Down Expand Up @@ -571,10 +574,16 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
}
}

fn format_line_break(&mut self, entering: bool) {
fn format_line_break(&mut self, entering: bool, next_is_block: bool) {
if entering {
if !self.options.render.hardbreaks {
write!(self, "\\").unwrap();
if !next_is_block {
// If the next element is a block, a backslash means a
// literal backslash instead of a line break. In this case
// we can just skip the line break since it's meaningless
// before a block.
write!(self, "\\").unwrap();
}
}
self.cr();
}
Expand Down
34 changes: 34 additions & 0 deletions src/tests/commonmark.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::cell::RefCell;

use self::nodes::{Ast, LineColumn};

use super::*;
use ntest::test_case;

Expand All @@ -11,6 +15,36 @@ fn commonmark_removes_redundant_strong() {
commonmark(input, output, Some(&options));
}

#[test]
fn commonmark_avoids_spurious_backslash() {
let arena = Arena::new();
let options = Options::default();
let empty = LineColumn { line: 0, column: 0 };

let ast = |val: NodeValue| arena.alloc(AstNode::new(RefCell::new(Ast::new(val, empty))));
let root = ast(NodeValue::Document);

let p1 = ast(NodeValue::Paragraph);
p1.append(ast(NodeValue::Text("Line 1".to_owned())));
root.append(p1);

root.append(ast(NodeValue::LineBreak));

let p2 = ast(NodeValue::Paragraph);
p2.append(ast(NodeValue::Text("Line 2".to_owned())));
root.append(p2);

let mut output = vec![];
cm::format_document(root, &options, &mut output).unwrap();

compare_strs(
&String::from_utf8(output).unwrap(),
"Line 1\n\nLine 2\n",
"rendered",
"<synthetic>",
);
}

#[test_case("$$x^2$$ and $1 + 2$ and $`y^2`$", "$$x^2$$ and $1 + 2$ and $`y^2`$\n")]
#[test_case("$$\nx^2\n$$", "$$\nx^2\n$$\n")]
#[test_case("```math\nx^2\n```", "``` math\nx^2\n```\n")]
Expand Down

0 comments on commit a264526

Please sign in to comment.