Skip to content

Commit c1bdfba

Browse files
committed
fix node ext propagation from inline rules
1 parent 32b33e8 commit c1bdfba

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/parser/inline/builtin/inline_parser.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl InlineParserRule {
5959
let mut inline_ext = std::mem::take(&mut data.ext);
6060

6161
let mut root = std::mem::take(child);
62+
root.ext = std::mem::take(&mut node.ext);
6263
root.children = Vec::new();
6364
root = if CAN_FAIL {
6465
md.inline.try_parse(content, mapping, root, md, root_ext, &mut inline_ext)?
@@ -68,6 +69,7 @@ impl InlineParserRule {
6869

6970
let len = root.children.len();
7071
node.children.splice(idx..=idx, std::mem::take(&mut root.children));
72+
node.ext = std::mem::take(&mut root.ext);
7173
idx += len;
7274
} else {
7375
stacker::maybe_grow(64*1024, 1024*1024, || -> Result<()> {

tests/extras.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,70 @@ r#"<blockquote>
111111
run("<https://www.reddit.com/r/programming/comments/vxttiq/comment/ifyqsqt/?utm_source=reddit&utm_medium=web2x&context=3>",
112112
"<p><a href=\"https://www.reddit.com/r/programming/comments/vxttiq/comment/ifyqsqt/?utm_source=reddit&amp;utm_medium=web2x&amp;context=3\">www.reddit.com/r/programming/comments/…/ifyqsqt/?…</a></p>");
113113
}
114+
115+
#[test]
116+
fn test_node_ext_propagation() {
117+
use markdown_it::parser::block::{BlockRule, BlockState};
118+
use markdown_it::parser::core::CoreRule;
119+
use markdown_it::parser::extset::NodeExt;
120+
use markdown_it::parser::inline::{InlineRule, InlineState};
121+
use markdown_it::{MarkdownIt, Node};
122+
123+
#[derive(Debug, Default)]
124+
struct NodeErrors(Vec<&'static str>);
125+
impl NodeExt for NodeErrors {}
126+
127+
struct MyInlineRule;
128+
impl InlineRule for MyInlineRule {
129+
const MARKER: char = '@';
130+
131+
fn run(state: &mut InlineState) -> Option<(Node, usize)> {
132+
let err = state.node.ext.get_or_insert_default::<NodeErrors>();
133+
err.0.push("inline");
134+
None
135+
}
136+
}
137+
138+
struct MyBlockRule;
139+
impl BlockRule for MyBlockRule {
140+
fn run(state: &mut BlockState) -> Option<(Node, usize)> {
141+
let err = state.node.ext.get_or_insert_default::<NodeErrors>();
142+
err.0.push("block");
143+
None
144+
}
145+
}
146+
147+
struct MyCoreRule;
148+
impl CoreRule for MyCoreRule {
149+
fn run(root: &mut Node, _md: &MarkdownIt) {
150+
let err = root.ext.get_or_insert_default::<NodeErrors>();
151+
err.0.push("core");
152+
}
153+
}
154+
155+
let md = &mut markdown_it::MarkdownIt::new();
156+
markdown_it::plugins::cmark::add(md);
157+
158+
md.inline.add_rule::<MyInlineRule>();
159+
md.block.add_rule::<MyBlockRule>();
160+
md.add_rule::<MyCoreRule>().after_all();
161+
162+
let text1 = r#"*hello @world*"#;
163+
let ast = md.parse(text1);
164+
let mut collected: Vec<&str> = vec![];
165+
166+
ast.walk_post(|node, _| -> markdown_it::Result<()> {
167+
if let Some(errors) = node.ext.get::<NodeErrors>() {
168+
collected.extend(errors.0.iter());
169+
}
170+
Ok(())
171+
}).unwrap();
172+
173+
assert_eq!(
174+
collected,
175+
vec!["inline", "block", "core"],
176+
);
177+
}
114178
}
115179

116180
mod examples {

0 commit comments

Comments
 (0)