Skip to content

Commit

Permalink
Add Raw Node
Browse files Browse the repository at this point in the history
  • Loading branch information
wakairo committed Dec 17, 2024
1 parent 8d1e90c commit 04eedf6
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/cm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ impl<'a, 'o, 'c> CommonMarkFormatter<'a, 'o, 'c> {
NodeValue::HtmlInline(ref literal) => {
self.format_html_inline(literal.as_bytes(), entering)
}
NodeValue::Raw(ref literal) => self.format_raw(literal.as_bytes(), entering),
NodeValue::Strong => {
if parent_node.is_none()
|| !matches!(parent_node.unwrap().data.borrow().value, NodeValue::Strong)
Expand Down Expand Up @@ -686,6 +687,12 @@ impl<'a, 'o, 'c> CommonMarkFormatter<'a, 'o, 'c> {
}
}

fn format_raw(&mut self, literal: &[u8], entering: bool) {
if entering {
self.write_all(literal).unwrap();
}
}

fn format_strong(&mut self) {
write!(self, "**").unwrap();
}
Expand Down
9 changes: 9 additions & 0 deletions src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ where
| NodeValue::HtmlInline(ref literal) => {
self.escape(literal.as_bytes())?;
}
NodeValue::Raw(ref literal) => {
self.output.write_all(literal.as_bytes())?;
}
NodeValue::LineBreak | NodeValue::SoftBreak => {
self.output.write_all(b" ")?;
}
Expand Down Expand Up @@ -757,6 +760,12 @@ where
}
}
}
NodeValue::Raw(ref literal) => {
// No sourcepos.
if entering {
self.output.write_all(literal.as_bytes())?;
}
}
NodeValue::Strong => {
// Unreliable sourcepos.
let parent_node = node.parent();
Expand Down
4 changes: 4 additions & 0 deletions src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ pub enum NodeValue {
/// **Inline**. [Raw HTML](https://github.github.com/gfm/#raw-html) contained inline.
HtmlInline(String),

/// **Inline**. A Raw text.
Raw(String),

/// **Inline**. [Emphasized](https://github.github.com/gfm/#emphasis-and-strong-emphasis)
/// text.
Emph,
Expand Down Expand Up @@ -511,6 +514,7 @@ impl NodeValue {
NodeValue::Strong => "strong",
NodeValue::Code(..) => "code",
NodeValue::HtmlInline(..) => "html_inline",
NodeValue::Raw(..) => "raw",
NodeValue::Strikethrough => "strikethrough",
NodeValue::FrontMatter(_) => "frontmatter",
NodeValue::TaskItem { .. } => "taskitem",
Expand Down
1 change: 1 addition & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod multiline_block_quotes;
mod options;
mod pathological;
mod plugins;
mod raw;
mod regressions;
mod rewriter;
mod shortcodes;
Expand Down
3 changes: 3 additions & 0 deletions src/tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ fn exercise_full_api() {
nodes::NodeValue::HtmlInline(html) => {
let _: &String = html;
}
nodes::NodeValue::Raw(text) => {
let _: &String = text;
}
nodes::NodeValue::Emph => {}
nodes::NodeValue::Strong => {}
nodes::NodeValue::Strikethrough => {}
Expand Down
77 changes: 77 additions & 0 deletions src/tests/raw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::cell::RefCell;

use crate::{
arena_tree::Node,
nodes::{Ast, NodeValue},
};

use super::*;

#[test]
fn raw_node() {
let user_input = "User input: <iframe></iframe>";
let system_input_inline = "System Inline input: <iframe></iframe>";
let system_input_block = "System Block input: <iframe></iframe>";
let input = user_input.to_owned() + system_input_inline + "\n\n" + system_input_block + "\n";

let mut options = Options::default();
options.render.escape = true;
options.render.unsafe_ = false;
options.extension.tagfilter = true;

let arena = Arena::new();
let root = parse_document(&arena, user_input, &options);
let raw_ast_inline = Ast::new(
NodeValue::Raw(system_input_inline.to_string()),
(0, 0).into(),
);
let raw_node_inline = arena.alloc(Node::new(RefCell::new(raw_ast_inline)));
root.first_child()
.unwrap()
.last_child()
.unwrap()
.insert_after(raw_node_inline);
let raw_ast_block = Ast::new(
NodeValue::Raw(system_input_block.to_string()),
(0, 0).into(),
);
let raw_node_block = arena.alloc(Node::new(RefCell::new(raw_ast_block)));
root.first_child().unwrap().insert_after(raw_node_block);

let mut output = vec![];
html::format_document(root, &options, &mut output).unwrap();
compare_strs(
&String::from_utf8(output).unwrap(),
concat!(
"<p>User input: &lt;iframe&gt;&lt;/iframe&gt;",
"System Inline input: <iframe></iframe></p>\n",
"System Block input: <iframe></iframe>"
),
"html",
&input,
);

let mut md = vec![];
cm::format_document_with_plugins(root, &options, &mut md, &Plugins::default()).unwrap();
compare_strs(&String::from_utf8(md).unwrap(), &input, "cm", &input);

let mut xml = vec![];
crate::xml::format_document(root, &options, &mut xml).unwrap();
compare_strs(
&String::from_utf8(xml).unwrap(),
concat!(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n",
"<document xmlns=\"http://commonmark.org/xml/1.0\">\n",
" <paragraph>\n",
" <text xml:space=\"preserve\">User input: </text>\n",
" <html_inline xml:space=\"preserve\">&lt;iframe&gt;</html_inline>\n",
" <html_inline xml:space=\"preserve\">&lt;/iframe&gt;</html_inline>\n",
" <raw xml:space=\"preserve\">System Inline input: &lt;iframe&gt;&lt;/iframe&gt;</raw>\n",
" </paragraph>\n",
" <raw xml:space=\"preserve\">System Block input: &lt;iframe&gt;&lt;/iframe&gt;</raw>\n</document>\n"
),
"xml",
&input,
);
}
6 changes: 4 additions & 2 deletions src/xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ impl<'o, 'c> XmlFormatter<'o, 'c> {
match node.data.borrow().value {
NodeValue::Text(ref literal)
| NodeValue::Code(NodeCode { ref literal, .. })
| NodeValue::HtmlInline(ref literal) => {
| NodeValue::HtmlInline(ref literal)
| NodeValue::Raw(ref literal) => {
self.escape(literal.as_bytes())?;
}
NodeValue::LineBreak | NodeValue::SoftBreak => {
Expand Down Expand Up @@ -148,7 +149,8 @@ impl<'o, 'c> XmlFormatter<'o, 'c> {
NodeValue::Text(ref literal)
| NodeValue::Code(NodeCode { ref literal, .. })
| NodeValue::HtmlBlock(NodeHtmlBlock { ref literal, .. })
| NodeValue::HtmlInline(ref literal) => {
| NodeValue::HtmlInline(ref literal)
| NodeValue::Raw(ref literal) => {
self.output.write_all(b" xml:space=\"preserve\">")?;
self.escape(literal.as_bytes())?;
write!(self.output, "</{}", ast.value.xml_node_name())?;
Expand Down

0 comments on commit 04eedf6

Please sign in to comment.