Struct markdown_it::Node

source ·
pub struct Node {
    pub children: Vec<Node>,
    pub srcmap: Option<SourcePos>,
    pub ext: NodeExtSet,
    pub attrs: Vec<(&'static str, String)>,
    pub node_type: TypeKey,
    pub node_value: Box<dyn NodeValue>,
}
Expand description

Single node in the CommonMark AST.

Fields§

§children: Vec<Node>

Array of child nodes.

§srcmap: Option<SourcePos>

Source mapping info.

§ext: NodeExtSet

Custom data specific to this token.

§attrs: Vec<(&'static str, String)>

Additional attributes to be added to resulting html.

§node_type: TypeKey

Type name, used for debugging.

§node_value: Box<dyn NodeValue>

Storage for arbitrary token-specific data.

Implementations§

source§

impl Node

source

pub fn new<T: NodeValue>(value: T) -> Self

Create a new Node with a custom value.

Examples found in repository?
examples/ferris/inline_rule.rs (line 52)
46
47
48
49
50
51
52
53
54
55
    fn run(state: &mut InlineState) -> Option<(Node, usize)> {
        let input = &state.src[state.pos..state.pos_max]; // look for stuff at state.pos
        if !input.starts_with(CRAB_CLAW) { return None; } // return None if it's not found

        // return new node and length of this structure
        Some((
            Node::new(InlineFerris),
            CRAB_CLAW.len(),
        ))
    }
More examples
Hide additional examples
examples/ferris/core_rule.rs (line 57)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    fn run(root: &mut Node, _: &MarkdownIt) {
        let mut counter = 0;

        // walk through AST recursively and count the number of two
        // custom nodes added by other two rules
        root.walk(|node, _| {
            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
                counter += 1;
            }
        });

        // append a counter to the root as a custom node
        root.children.push(Node::new(FerrisCounter(counter)))
    }
examples/ferris/block_rule.rs (line 63)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    fn run(state: &mut BlockState) -> Option<(Node, usize)> {
        // get contents of a line number `state.line` and check it
        let line = state.get_line(state.line).trim();
        if !line.starts_with(CRAB_CLAW) { return None; }
        if !line.ends_with(CRAB_CLAW)   { return None; }

        // require any number of `-` in between, but no less than 4
        if line.len() < CRAB_CLAW.len() * 2 + 4 { return None; }

        // and make sure no other characters are present there
        let dashes = &line[CRAB_CLAW.len()..line.len()-CRAB_CLAW.len()];
        if dashes.chars().any(|c| c != '-') { return None; }

        // return new node and number of lines it occupies
        Some((
            Node::new(BlockFerris),
            1,
        ))
    }
source

pub fn name(&self) -> &'static str

Return std::any::type_name() of node value.

source

pub fn is<T: NodeValue>(&self) -> bool

Check that this node value is of given type.

Examples found in repository?
examples/ferris/core_rule.rs (line 51)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    fn run(root: &mut Node, _: &MarkdownIt) {
        let mut counter = 0;

        // walk through AST recursively and count the number of two
        // custom nodes added by other two rules
        root.walk(|node, _| {
            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
                counter += 1;
            }
        });

        // append a counter to the root as a custom node
        root.children.push(Node::new(FerrisCounter(counter)))
    }
source

pub fn cast<T: NodeValue>(&self) -> Option<&T>

Downcast node value to specific type.

source

pub fn cast_mut<T: NodeValue>(&mut self) -> Option<&mut T>

Downcast node value to specific type.

source

pub fn render(&self) -> String

Render this node to HTML.

Examples found in repository?
examples/ferris/main.rs (line 22)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
fn main() {
    // create markdown parser
    let md = &mut markdown_it::MarkdownIt::new();

    // add commonmark syntax, you almost always want to do that
    markdown_it::plugins::cmark::add(md);

    // add custom three rules described above
    inline_rule::add(md);
    block_rule::add(md);
    core_rule::add(md);

    // and now you can use it
    let html = md.parse(r#"
(\/) hello world (\/)
(\/)-------------(\/)
    "#).render();

    print!("{html}");

    assert_eq!(html.trim(), r#"
<p><span class="ferris-inline">🦀</span> hello world <span class="ferris-inline">🦀</span></p>
<div class="ferris-block"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0f/Original_Ferris.svg"></div>
<footer class="ferris-counter">There are 3 crabs lurking in this document.</footer>
    "#.trim());
}
source

pub fn xrender(&self) -> String

Render this node to XHTML, it adds slash to self-closing tags like this: <img />.

This mode exists for compatibility with CommonMark tests.

source

pub fn replace<T: NodeValue>(&mut self, value: T)

Replace custom value with another value (this is roughly equivalent to replacing the entire node and copying children and sourcemaps).

source

pub fn walk<'a>(&'a self, f: impl FnMut(&'a Node, u32))

Execute function f recursively on every member of AST tree (using preorder deep-first search).

Examples found in repository?
examples/ferris/core_rule.rs (lines 50-54)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    fn run(root: &mut Node, _: &MarkdownIt) {
        let mut counter = 0;

        // walk through AST recursively and count the number of two
        // custom nodes added by other two rules
        root.walk(|node, _| {
            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
                counter += 1;
            }
        });

        // append a counter to the root as a custom node
        root.children.push(Node::new(FerrisCounter(counter)))
    }
source

pub fn walk_mut(&mut self, f: impl FnMut(&mut Node, u32))

Execute function f recursively on every member of AST tree (using preorder deep-first search).

source

pub fn walk_post(&self, f: impl FnMut(&Node, u32))

Execute function f recursively on every member of AST tree (using postorder deep-first search).

source

pub fn walk_post_mut(&mut self, f: impl FnMut(&mut Node, u32))

Execute function f recursively on every member of AST tree (using postorder deep-first search).

source

pub fn collect_text(&self) -> String

Walk recursively through child nodes and collect all text nodes into a single string.

Trait Implementations§

source§

impl Debug for Node

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Node

source§

fn default() -> Self

Create empty Node. Empty node should only be used as placeholder for functions like std::mem::take, and it cannot be rendered.

source§

impl Drop for Node

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Node

§

impl !Send for Node

§

impl !Sync for Node

§

impl Unpin for Node

§

impl !UnwindSafe for Node

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Downcast for Twhere T: Any,

source§

fn into_any(self: Box<T, Global>) -> Box<dyn Any + 'static, Global>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any + 'static>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.