use markdown_it::Node;
use markdown_it::common::sourcemap::SourceWithLineStarts;
fn run(input: &str, f: fn (&Node, SourceWithLineStarts)) {
let md = &mut markdown_it::MarkdownIt::new();
markdown_it::plugins::cmark::add(md);
markdown_it::plugins::html::add(md);
let node = md.parse(input);
node.walk(|node, _| assert!(node.srcmap.is_some()));
f(&node, SourceWithLineStarts::new(input));
}
fn getmap(node: &Node, map: &SourceWithLineStarts) -> ((u32, u32), (u32, u32)) {
node.srcmap.unwrap().get_positions(map)
}
#[test]
fn paragraph() {
// same as commonmark.js
run("foo \n \n \n\n barbaz\n\tquux \n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 1), (1, 6)),
);
assert_eq!(
getmap(&node.children[1], &map),
((5, 3), (6, 8)),
);
});
}
#[test]
fn hr() {
// same as commonmark.js
run(" --- \n\n * * *\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 2), (1, 6)),
);
assert_eq!(
getmap(&node.children[1], &map),
((3, 3), (3, 7)),
);
});
}
#[test]
fn heading() {
// same as commonmark.js
run(" \n ### foo ### \n\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((2, 3), (2, 15)),
);
});
run(" #\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (1, 3)),
);
});
}
#[test]
fn lheading() {
// same as commonmark.js
run(" foo\n bar\n ----\n\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (3, 5)),
);
});
}
#[test]
fn fence() {
// same as commonmark.js
run(" ~~~ foo ~~~\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (1, 13)),
);
});
run(" ```\n 12\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (2, 3)),
);
});
run("```\n\n\n\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 1), (4, 0)),
);
});
run("~~~\na\nb\n~~~ \nc\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 1), (4, 5)),
);
});
}
#[test]
fn html_block() {
// same as commonmark.js
run("
\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (1, 7)),
);
});
run("
\n
\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 1), (2, 8)),
);
});
}
#[test]
fn code_block() {
// this should be (1, 5), (1, 9)
// for simplicity, we point source maps for block tags to first
// nonspace character, but it isn't quite correct for code blocks
run(" foo\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 7), (1, 9)),
);
});
run(" a\n b\n c\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 4), (3, 6)),
);
});
// this I believe to be error in commonmark, code block
// only have 1 line as per spec, but cmark reports 3 lines
run(" foobar \n \n \n\nbar\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 5), (1, 12)),
);
});
}
#[test]
fn blockquotes() {
// same as commonmark.js
run(" > foo \n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 3), (1, 9)),
);
});
run("> foo\nbar\n\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 1), (2, 3)),
);
});
}
#[test]
fn lists() {
// same as commonmark.js
run(" 1. foo\n 2. bar\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 2), (2, 7)),
);
assert_eq!(
getmap(&node.children[0].children[0], &map),
((1, 2), (1, 7)),
);
});
run(" - foo\n\n - bar\n", |node, map| {
assert_eq!(
getmap(&node.children[0], &map),
((1, 2), (3, 6)),
);
assert_eq!(
getmap(&node.children[0].children[0], &map),
((1, 2), (2, 0)),
);
assert_eq!(
getmap(&node.children[0].children[1], &map),
((3, 2), (3, 6)),
);
});
}
#[test]
fn autolinks() {
run("foo
bar", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 23)),
);
assert_eq!(
getmap(&node.children[0].children[1].children[0], &map),
((1, 6), (1, 22)),
);
});
}
#[test]
fn emphasis() {
run("***foo***", |node, map| {
assert_eq!(
getmap(&node.children[0].children[0], &map),
((1, 1), (1, 9)),
);
assert_eq!(
getmap(&node.children[0].children[0].children[0], &map),
((1, 2), (1, 8)),
);
});
run("aaa **bb _cc_ dd** eee", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 18)),
);
assert_eq!(
getmap(&node.children[0].children[1].children[1], &map),
((1, 10), (1, 13)),
);
});
}
#[test]
fn newline() {
run("foo \nbar \nbaz\nquux", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 4), (2, 0)),
);
assert_eq!(
getmap(&node.children[0].children[3], &map),
((2, 4), (3, 0)),
);
assert_eq!(
getmap(&node.children[0].children[5], &map),
((4, 0), (4, 0)),
);
/*let marks : Vec<_> = node.children[0].children.iter().map(|x| getmap(x, &map)).collect();
assert_eq!(marks, [
((1, 1), (1, 5)),
((2, 0), (2, 1)),
((2, 1), (2, 3)),
((3, 0), (3, 0)),
((3, 1), (3, 3)),
]);*/
});
}
#[test]
fn escapes() {
run("foo\\Δ\\*bar", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 4), (1, 5)),
);
assert_eq!(
getmap(&node.children[0].children[2], &map),
((1, 6), (1, 7)),
);
});
run(" foo \\\n bar ", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 8), (2, 2)),
);
});
}
#[test]
fn entities() {
run("aa bb cc", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 4), (1, 9)),
);
assert_eq!(
getmap(&node.children[0].children[3], &map),
((1, 14), (1, 18)),
);
/*let marks : Vec<_> = node.children[0].children.iter().map(|x| getmap(x, &map)).collect();
assert_eq!(marks, [
((1, 1), (1, 5)),
((2, 0), (2, 1)),
((2, 1), (2, 3)),
((3, 0), (3, 0)),
((3, 1), (3, 3)),
]);*/
});
}
#[test]
fn html_inline() {
run("foo baz", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 9)),
);
});
}
#[test]
fn backticks() {
run("foo ```bar``` baz", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 13)),
);
assert_eq!(
getmap(&node.children[0].children[1].children[0], &map),
((1, 8), (1, 10)),
);
});
run("foo ` bar ` baz", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 11)),
);
assert_eq!(
getmap(&node.children[0].children[1].children[0], &map),
((1, 7), (1, 9)),
);
});
}
#[test]
fn imglink() {
run("foo [bar](baz) quux", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 14)),
);
});
run("foo ![bar](baz) quux", |node, map| {
assert_eq!(
getmap(&node.children[0].children[1], &map),
((1, 5), (1, 15)),
);
});
}