markdown_it_gfm/
lib.rs

1//! A [markdown_it] plugin for parsing Github Flavoured Markdown
2//!
3//! ```rust
4//! let parser = &mut markdown_it::MarkdownIt::new();
5//! markdown_it_gfm::add(parser);
6//! let root = parser.parse("https://github.github.com/gfm");
7//! assert_eq!(root.render(), "<p><a href=\"https://github.github.com/gfm\">https://github.github.com/gfm</a></p>\n");
8//! ```
9use markdown_it::parser::inline::builtin::InlineParserRule;
10use markdown_it::plugins::html::html_block::HtmlBlock;
11use markdown_it::plugins::html::html_inline::HtmlInline;
12use markdown_it::{parser::core::CoreRule, MarkdownIt, Node};
13use regex::Regex;
14
15/// Add the GFM plugin to the parser
16pub fn add(md: &mut MarkdownIt) {
17    markdown_it::plugins::cmark::add(md);
18    markdown_it::plugins::extra::tables::add(md);
19    markdown_it::plugins::extra::strikethrough::add(md);
20    markdown_it::plugins::html::add(md);
21    md.add_rule::<TagFilter>().after::<InlineParserRule>();
22    markdown_it_tasklist::add_disabled(md);
23    markdown_it_autolink::add(md);
24}
25
26/// Add the GFM plugin to the parser, plus heading anchors
27pub fn add_with_anchors(md: &mut MarkdownIt) {
28    add(md);
29    markdown_it_heading_anchors::add(md);
30}
31
32/// Implement the Disallowed Raw HTML (tagfilter) rule
33struct TagFilter;
34impl CoreRule for TagFilter {
35    fn run(root: &mut Node, _md: &MarkdownIt) {
36        let regex = Regex::new(
37            r#"<(?i)(iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)"#,
38        )
39        .unwrap();
40        root.walk_mut(|node, _| {
41            if let Some(value) = node.cast_mut::<HtmlBlock>() {
42                value.content = regex.replace_all(&value.content, "&lt;$1").to_string();
43            }
44            if let Some(value) = node.cast_mut::<HtmlInline>() {
45                value.content = regex.replace_all(&value.content, "&lt;$1").to_string();
46            }
47        });
48    }
49}