Struct 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 the 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 53)
46    fn run(state: &mut InlineState) -> Option<(Node, usize)> {
47        let input = &state.src[state.pos..state.pos_max]; // look for stuff at state.pos
48        if !input.starts_with(CRAB_CLAW) {
49            return None;
50        } // return None if it's not found
51
52        // return new node and length of this structure
53        Some((Node::new(InlineFerris), CRAB_CLAW.len()))
54    }
More examples
Hide additional examples
examples/ferris/core_rule.rs (line 57)
45    fn run(root: &mut Node, _: &MarkdownThat) {
46        let mut counter = 0;
47
48        // walk through AST recursively and count the number of two
49        // custom nodes added by other two rules
50        root.walk(|node, _| {
51            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
52                counter += 1;
53            }
54        });
55
56        // append a counter to the root as a custom node
57        root.children.push(Node::new(FerrisCounter(counter)))
58    }
examples/ferris/block_rule.rs (line 70)
48    fn run(state: &mut BlockState) -> Option<(Node, usize)> {
49        // get contents of a line number `state.line` and check it
50        let line = state.get_line(state.line).trim();
51        if !line.starts_with(CRAB_CLAW) {
52            return None;
53        }
54        if !line.ends_with(CRAB_CLAW) {
55            return None;
56        }
57
58        // require any number of `-` in between, but no less than 4
59        if line.len() < CRAB_CLAW.len() * 2 + 4 {
60            return None;
61        }
62
63        // and make sure no other characters are present there
64        let dashes = &line[CRAB_CLAW.len()..line.len() - CRAB_CLAW.len()];
65        if dashes.chars().any(|c| c != '-') {
66            return None;
67        }
68
69        // return new node and number of lines it occupies
70        Some((Node::new(BlockFerris), 1))
71    }
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 a given type.

Examples found in repository?
examples/ferris/core_rule.rs (line 51)
45    fn run(root: &mut Node, _: &MarkdownThat) {
46        let mut counter = 0;
47
48        // walk through AST recursively and count the number of two
49        // custom nodes added by other two rules
50        root.walk(|node, _| {
51            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
52                counter += 1;
53            }
54        });
55
56        // append a counter to the root as a custom node
57        root.children.push(Node::new(FerrisCounter(counter)))
58    }
Source

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

Downcast node value to a specific type.

Source

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

Downcast node value to a specific type.

Source

pub fn render(&self) -> String

Render this node to HTML.

Examples found in repository?
examples/ferris/main.rs (line 26)
6fn main() {
7    // create markdown parser
8    let md = &mut markdown_that::MarkdownThat::new();
9
10    // add commonmark syntax, you almost always want to do that
11    markdown_that::plugins::cmark::add(md);
12
13    // add custom three rules described above
14    inline_rule::add(md);
15    block_rule::add(md);
16    core_rule::add(md);
17
18    // and now you can use it
19    let html = md
20        .parse(
21            r#"
22(\/) hello world (\/)
23(\/)-------------(\/)
24    "#,
25        )
26        .render();
27
28    print!("{html}");
29
30    assert_eq!(html.trim(), r#"
31<p><span class="ferris-inline">🦀</span> hello world <span class="ferris-inline">🦀</span></p>
32<div class="ferris-block"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0f/Original_Ferris.svg"></div>
33<footer class="ferris-counter">There are 3 crabs lurking in this document.</footer>
34    "#.trim());
35}
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 a custom value with another value (this is roughly equivalent to replacing the entire node and copying children and sourcemaps).

Source

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

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

Examples found in repository?
examples/ferris/core_rule.rs (lines 50-54)
45    fn run(root: &mut Node, _: &MarkdownThat) {
46        let mut counter = 0;
47
48        // walk through AST recursively and count the number of two
49        // custom nodes added by other two rules
50        root.walk(|node, _| {
51            if node.is::<InlineFerris>() || node.is::<BlockFerris>() {
52                counter += 1;
53            }
54        });
55
56        // append a counter to the root as a custom node
57        root.children.push(Node::new(FerrisCounter(counter)))
58    }
Source

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

Execute function f recursively on every member of an 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 an 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 an 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 a 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 Freeze for Node

§

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 T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

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

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

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

Converts &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)

Converts &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 T
where 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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

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

Source§

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 T
where U: TryFrom<T>,

Source§

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.
Source§

impl<T> ErasedDestructor for T
where T: 'static,