Skip to main content

rushdown/
ast.rs

1//! AST (Abstract Syntax Tree) module for the document representation.
2//!
3//! This module defines the core structures and functionalities for representing
4//! and manipulating the AST of a document. It includes definitions for nodes,
5//! node types, attributes, and various node operations.
6//!
7//! # Related macros
8//!
9//! rushdown provides several helper macros for working with AST nodes:
10//!
11//! - [`crate::matches_kind!`] - Helper macro to match kind data.
12//! - [`crate::as_type_data!`] - Helper macro to downcast type data.
13//! - [`crate::as_type_data_mut!`] - Helper macro to downcast mutable type data.
14//! - [`crate::as_kind_data!`] - Helper macro to downcast kind data.
15//! - [`crate::as_kind_data_mut!`] - Helper macro to downcast mutable kind data.
16//! - [`crate::matches_extension_kind!`] - Helper macro to match extension kind.
17//! - [`crate::as_extension_data!`] - Helper macro to downcast extension data.
18//! - [`crate::as_extension_data_mut!`] - Helper macro to downcast mutable extension data.
19//!
20//! # Basic usage
21//! ```rust
22//!
23//! use rushdown::ast::*;
24//! use rushdown::{as_type_data_mut, as_type_data, as_kind_data};
25//! use rushdown::text::Segment;
26//!
27//! let mut arena = Arena::new();
28//! let source = "Hello, World!";
29//! let doc_ref = arena.new_node(Document::new());
30//! let paragraph_ref = arena.new_node(Paragraph::new());
31//! let seg = Segment::new(0, source.len());
32//! as_type_data_mut!(&mut arena[paragraph_ref], Block).append_source_line(seg);
33//! let text_ref = arena.new_node(Text::new(seg));
34//! paragraph_ref.append_child(&mut arena, text_ref);
35//! doc_ref.append_child(&mut arena, paragraph_ref);
36//!
37//! assert_eq!(arena[paragraph_ref].first_child().unwrap(), text_ref);
38//! assert_eq!(
39//!     as_kind_data!(&arena[text_ref], Text).str(source),
40//!     "Hello, World!"
41//! );
42//! assert_eq!(
43//!     as_type_data!(&arena[paragraph_ref], Block)
44//!         .source()
45//!         .first()
46//!         .unwrap()
47//!         .str(source),
48//!     "Hello, World!"
49//! );
50//! ```
51//!
52//! Nodes are stored in an arena for efficient memory management and access.
53//! Each node is identified by a [`NodeRef`], which contains the index and unique ID of the node.
54//!
55//! You can get and manipulate nodes using the [`Arena`] and its methods.
56//!
57//! ```should_panic
58//! use rushdown::ast::*;
59//!
60//! let mut arena = Arena::new();
61//! let source = "Hello, World!";
62//! let doc_ref = arena.new_node(Document::new());
63//! let paragraph_ref = arena.new_node(Paragraph::new());
64//! paragraph_ref.delete(&mut arena);
65//!
66//! let p = &arena[paragraph_ref]; // panics
67//! ```
68//!
69//! ```rust
70//! use rushdown::ast::*;
71//!
72//! let mut arena = Arena::new();
73//! let source = "Hello, World!";
74//! let doc_ref = arena.new_node(Document::new());
75//! let paragraph_ref = arena.new_node(Paragraph::default());
76//!
77//! assert!(arena.get(paragraph_ref).is_some());
78//!
79//! paragraph_ref.delete(&mut arena);
80//!
81//! assert!(arena.get(paragraph_ref).is_none());
82//! ```
83//!
84//! Each node belongs to a specific type and kind.
85//!
86//! ```text
87//! - Node
88//!    - type_data: node type(block or inline) specific data
89//!    - kind_data: node kind(e.g. Text, Paragraph) specific data
90//!    - parent, first_child, next_sibling... : relationships
91//! ```
92//!
93//!
94
95extern crate alloc;
96
97use alloc::borrow::Cow;
98use alloc::boxed::Box;
99use alloc::format;
100use alloc::string::String;
101use alloc::vec;
102use alloc::vec::Vec;
103use core::any::Any;
104use core::error::Error as CoreError;
105use core::fmt::{self, Debug, Display, Formatter, Write};
106use core::iter::IntoIterator;
107use core::ops::{Index, IndexMut};
108use core::result::Result as CoreResult;
109
110use crate::error::*;
111use crate::text;
112use crate::util::{StringMap, TinyVec};
113
114use bitflags::bitflags;
115
116// NodeRef {{{
117
118/// Represents a referene to a node in the document.
119#[derive(Default, Debug, Clone, Copy)]
120pub struct NodeRef {
121    cell: usize,
122    id: usize,
123}
124
125impl NodeRef {
126    /// Creates a new NodeRef with the given index and id.
127    pub const fn new(cell: usize, id: usize) -> Self {
128        Self { cell, id }
129    }
130}
131
132impl PartialEq for NodeRef {
133    fn eq(&self, other: &Self) -> bool {
134        self.id == other.id
135    }
136}
137
138impl Eq for NodeRef {}
139
140/// An undefined NodeRef constant.
141pub const NODE_REF_UNDEFINED: NodeRef = NodeRef {
142    cell: usize::MAX,
143    id: usize::MAX,
144};
145
146impl Display for NodeRef {
147    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
148        write!(f, "NodeRef(cell:{}, id:{})", self.cell, self.id)
149    }
150}
151
152impl NodeRef {
153    /// Appends a child node to this node.
154    /// This is a fast version that does not check for existing parent.
155    pub(crate) fn append_child_fast(self, arena: &mut Arena, child_ref: NodeRef) {
156        let lastref_opt = arena[self].last_child;
157        {
158            let s = &mut arena[self];
159            s.last_child = Some(child_ref);
160            if lastref_opt.is_none() {
161                s.first_child = Some(child_ref);
162            }
163        }
164        {
165            let child = &mut arena[child_ref];
166            child.parent = Some(self);
167            child.previous_sibling = lastref_opt;
168        }
169        if let Some(lastref) = lastref_opt {
170            arena[lastref].next_sibling = Some(child_ref);
171        } else {
172            arena[self].first_child = Some(child_ref);
173        }
174    }
175
176    /// Appends a child node to this node.
177    ///
178    /// # Panics
179    /// Panics if the operation fails(e.g. due to invalid NodeRef).
180    #[inline(always)]
181    pub fn append_child(self, arena: &mut Arena, child_ref: NodeRef) {
182        self.try_append_child(arena, child_ref).unwrap();
183    }
184
185    /// Appends a child node to this node.
186    pub fn try_append_child(self, arena: &mut Arena, child_ref: NodeRef) -> Result<()> {
187        if arena[child_ref].parent().is_some() {
188            child_ref.try_remove(arena)?;
189        }
190        let lastref_opt = arena.try_get(self)?.last_child;
191        arena[self].last_child = Some(child_ref);
192        if lastref_opt.is_none() {
193            arena[self].first_child = Some(child_ref);
194        }
195        {
196            let child = arena.try_get_mut(child_ref)?;
197            child.parent = Some(self);
198            child.previous_sibling = lastref_opt;
199        }
200        if let Some(lastref) = lastref_opt {
201            arena.try_get_mut(lastref)?.next_sibling = Some(child_ref);
202        } else {
203            arena[self].first_child = Some(child_ref);
204        }
205        Ok(())
206    }
207
208    /// Replace a child node with another node.
209    /// Replaced child will be hard removed.
210    ///
211    /// # Panics
212    /// Panics if the operation fails(e.g. due to invalid NodeRef).
213    #[inline(always)]
214    pub fn replace_child(self, arena: &mut Arena, target_ref: NodeRef, replacer_ref: NodeRef) {
215        self.try_replace_child(arena, target_ref, replacer_ref)
216            .unwrap();
217    }
218
219    /// Replace a child node with another node.
220    /// Replaced child will be hard removed.
221    pub fn try_replace_child(
222        self,
223        arena: &mut Arena,
224        target_ref: NodeRef,
225        replacer_ref: NodeRef,
226    ) -> Result<()> {
227        if arena.try_get(target_ref)?.parent != Some(self) {
228            return Err(Error::invalid_node_operation(format!(
229                "Target node {:?} is not a child of node {:?}",
230                target_ref, self
231            )));
232        }
233        let previous_ref_opt = arena[target_ref].previous_sibling;
234        let next_ref_opt = arena[target_ref].next_sibling;
235
236        {
237            let replacer = arena.try_get_mut(replacer_ref)?;
238            replacer.parent = Some(self);
239            replacer.previous_sibling = previous_ref_opt;
240            replacer.next_sibling = next_ref_opt;
241        }
242
243        if let Some(prev_ref) = previous_ref_opt {
244            arena.try_get_mut(prev_ref)?.next_sibling = Some(replacer_ref);
245        } else {
246            arena.try_get_mut(self)?.first_child = Some(replacer_ref);
247        }
248
249        if let Some(next_ref) = next_ref_opt {
250            arena.try_get_mut(next_ref)?.previous_sibling = Some(replacer_ref);
251        } else {
252            arena.try_get_mut(self)?.last_child = Some(replacer_ref);
253        }
254
255        // Clear the target node in the arena
256        arena.arena[target_ref.cell] = None;
257        arena.free_indicies.push(target_ref.cell);
258        Ok(())
259    }
260
261    /// Inserts a child node before a target node.
262    ///
263    /// # Panics
264    /// Panics if the operation fails(e.g. due to invalid NodeRef).
265    #[inline(always)]
266    pub fn insert_before(self, arena: &mut Arena, target_ref: NodeRef, insertee_ref: NodeRef) {
267        self.try_insert_before(arena, target_ref, insertee_ref)
268            .unwrap();
269    }
270
271    /// Inserts a child node before a target node.
272    pub fn try_insert_before(
273        self,
274        arena: &mut Arena,
275        target_ref: NodeRef,
276        insertee_ref: NodeRef,
277    ) -> Result<()> {
278        if arena[insertee_ref].parent().is_some() {
279            insertee_ref.try_remove(arena)?;
280        }
281        if arena.try_get(target_ref)?.parent != Some(self) {
282            return Err(Error::invalid_node_operation(format!(
283                "Target node {:?} is not a child of node {:?}",
284                target_ref, self
285            )));
286        }
287        let prev = arena[target_ref].previous_sibling;
288        {
289            let insertee = arena.try_get_mut(insertee_ref)?;
290            insertee.parent = Some(self);
291            insertee.next_sibling = Some(target_ref);
292            insertee.previous_sibling = prev;
293        }
294
295        if let Some(prev_ref) = arena[target_ref].previous_sibling {
296            arena.try_get_mut(prev_ref)?.next_sibling = Some(insertee_ref);
297        } else {
298            arena.try_get_mut(self)?.first_child = Some(insertee_ref);
299        }
300
301        arena[target_ref].previous_sibling = Some(insertee_ref);
302        if let Some(fc_ref) = arena.try_get(self)?.first_child {
303            if fc_ref == target_ref {
304                arena.try_get_mut(self)?.first_child = Some(insertee_ref);
305            }
306        }
307        Ok(())
308    }
309
310    /// Inserts a child node after a target node.
311    ///
312    /// # Panics
313    /// Panics if the operation fails(e.g. due to invalid NodeRef).
314    #[inline(always)]
315    pub fn insert_after(self, arena: &mut Arena, target_ref: NodeRef, insertee_ref: NodeRef) {
316        self.try_insert_after(arena, target_ref, insertee_ref)
317            .unwrap();
318    }
319
320    /// Inserts a child node after a target node.
321    pub fn try_insert_after(
322        self,
323        arena: &mut Arena,
324        target_ref: NodeRef,
325        insertee_ref: NodeRef,
326    ) -> Result<()> {
327        if arena[insertee_ref].parent().is_some() {
328            insertee_ref.try_remove(arena)?;
329        }
330        if arena.try_get(target_ref)?.parent != Some(self) {
331            return Err(Error::invalid_node_operation(format!(
332                "Target node {:?} is not a child of node {:?}",
333                target_ref, self
334            )));
335        }
336        let next = arena[target_ref].next_sibling;
337        {
338            let insertee = arena.try_get_mut(insertee_ref)?;
339            insertee.parent = Some(self);
340            insertee.previous_sibling = Some(target_ref);
341            insertee.next_sibling = next;
342        }
343
344        if let Some(next_ref) = arena[target_ref].next_sibling {
345            arena.try_get_mut(next_ref)?.previous_sibling = Some(insertee_ref);
346        } else {
347            arena.try_get_mut(self)?.last_child = Some(insertee_ref);
348        }
349
350        arena[target_ref].next_sibling = Some(insertee_ref);
351        if let Some(lc_ref) = arena.try_get(self)?.last_child {
352            if lc_ref == target_ref {
353                arena.try_get_mut(self)?.last_child = Some(insertee_ref);
354            }
355        }
356        Ok(())
357    }
358
359    /// Removes this node from the document.
360    /// This does not remove its children.
361    /// This does not remove the node from Arena.
362    ///
363    /// # Panics
364    /// Panics if the operation fails(e.g. due to invalid NodeRef).
365    #[inline(always)]
366    pub fn remove(self, arena: &mut Arena) {
367        self.try_remove(arena).unwrap();
368    }
369
370    /// Removes this node from the document.
371    /// This does not remove its children.
372    /// This does not remove the node from Arena.
373    pub fn try_remove(self, arena: &mut Arena) -> Result<()> {
374        let parent_ref_opt;
375        let previous_ref_opt;
376        let next_ref_opt;
377        {
378            let node = arena.try_get(self)?;
379            parent_ref_opt = node.parent;
380            previous_ref_opt = node.previous_sibling;
381            next_ref_opt = node.next_sibling;
382        }
383        if let Some(parent_ref) = parent_ref_opt {
384            let mparent = arena.try_get_mut(parent_ref)?;
385            if mparent.first_child == Some(self) {
386                mparent.first_child = next_ref_opt;
387            }
388            if mparent.last_child == Some(self) {
389                mparent.last_child = previous_ref_opt;
390            }
391        }
392        if let Some(previous_ref) = previous_ref_opt {
393            let mprevious = arena.try_get_mut(previous_ref)?;
394            mprevious.next_sibling = next_ref_opt;
395        }
396        if let Some(next_ref) = next_ref_opt {
397            let mnext = arena.try_get_mut(next_ref)?;
398            mnext.previous_sibling = previous_ref_opt;
399        }
400        let node = arena.try_get_mut(self)?;
401        node.parent = None;
402        node.previous_sibling = None;
403        node.next_sibling = None;
404        Ok(())
405    }
406
407    /// Deletes this node from the document, including all its children.
408    /// This removes the node from Arena.
409    ///
410    /// # Panics
411    ///
412    /// Panics if the operation fails(e.g. due to invalid NodeRef).
413    #[inline(always)]
414    pub fn delete(self, arena: &mut Arena) {
415        self.try_delete(arena).unwrap();
416    }
417
418    /// Removes this node from the document, including all its children.
419    /// This removes the node from Arena.
420    pub fn try_delete(self, arena: &mut Arena) -> Result<()> {
421        let parent_ref_opt;
422        let previous_ref_opt;
423        let next_ref_opt;
424        let first_ref_opt;
425        {
426            let node = arena.try_get(self)?;
427            parent_ref_opt = node.parent;
428            previous_ref_opt = node.previous_sibling;
429            next_ref_opt = node.next_sibling;
430            first_ref_opt = node.first_child;
431        }
432        if let Some(parent_ref) = parent_ref_opt {
433            let mparent = arena.try_get_mut(parent_ref)?;
434            if mparent.first_child == Some(self) {
435                mparent.first_child = next_ref_opt;
436            }
437            if mparent.last_child == Some(self) {
438                mparent.last_child = previous_ref_opt;
439            }
440        }
441        if let Some(previous_ref) = previous_ref_opt {
442            let mprevious = arena.try_get_mut(previous_ref)?;
443            mprevious.next_sibling = next_ref_opt;
444        }
445        if let Some(next_ref) = next_ref_opt {
446            let mnext = arena.try_get_mut(next_ref)?;
447            mnext.previous_sibling = previous_ref_opt;
448        }
449        if first_ref_opt.is_some() {
450            let mut currentref_opt = first_ref_opt;
451            while let Some(current_ref) = currentref_opt {
452                let current = arena.try_get_mut(current_ref)?;
453                let nextref_opt = current.next_sibling;
454                current_ref.try_delete(arena)?;
455                currentref_opt = nextref_opt;
456            }
457        }
458        // Clear the node in the arena
459        arena.arena[self.cell] = None;
460        arena.free_indicies.push(self.cell);
461        Ok(())
462    }
463
464    // Merges a given index into the last child of this node if
465    // it can be merged, otherwise creates a new Text node and appends it to after current
466    // last child.
467    //
468    // # Panics
469    // Panics if the operation fails(e.g. due to invalid NodeRef).
470    #[inline(always)]
471    pub fn merge_or_append_text(self, arena: &mut Arena, index: text::Index) {
472        self.try_merge_or_append_text(arena, index).unwrap();
473    }
474
475    // Merges a given index into the last child of this node if
476    // it can be merged, otherwise creates a new Text node and appends it to after current
477    // last child.
478    pub fn try_merge_or_append_text(self, arena: &mut Arena, index: text::Index) -> Result<()> {
479        if let Some(last_child_ref) = arena.try_get(self)?.last_child {
480            if let KindData::Text(text_node) = arena.try_get_mut(last_child_ref)?.kind_data_mut() {
481                if let Some(s) = text_node.index() {
482                    if s.stop() == index.start()
483                        && !text_node.has_qualifiers(TextQualifier::SOFT_LINE_BREAK)
484                        && !text_node.has_qualifiers(TextQualifier::TEMP)
485                    {
486                        text_node.value = (s.start(), index.stop()).into();
487                        return Ok(());
488                    }
489                }
490            }
491        }
492        let new_node_ref = arena.new_node(Text::new(index));
493        self.try_append_child(arena, new_node_ref)?;
494        Ok(())
495    }
496
497    /// Merges a given index into the text node after the target node if
498    /// it can be merged, otherwise creates a new Text node and inserts it after the target node.
499    ///
500    // # Panics
501    /// Panics if the operation fails(e.g. due to invalid NodeRef).
502    #[inline(always)]
503    pub fn merge_or_insert_after_text(
504        self,
505        arena: &mut Arena,
506        target_ref: NodeRef,
507        index: text::Index,
508    ) {
509        self.try_merge_or_insert_after_text(arena, target_ref, index)
510            .unwrap();
511    }
512
513    /// Merges a given index into the text node after the target node if
514    /// it can be merged, otherwise creates a new Text node and inserts it after the target node.
515    pub fn try_merge_or_insert_after_text(
516        self,
517        arena: &mut Arena,
518        target_ref: NodeRef,
519        index: text::Index,
520    ) -> Result<()> {
521        if let KindData::Text(text_node) = arena.try_get_mut(target_ref)?.kind_data_mut() {
522            if let Some(s) = text_node.index() {
523                if s.stop() == index.start()
524                    && !text_node.has_qualifiers(TextQualifier::SOFT_LINE_BREAK)
525                    && !text_node.has_qualifiers(TextQualifier::TEMP)
526                {
527                    text_node.value = (s.start(), index.stop()).into();
528                    return Ok(());
529                }
530            }
531        }
532        let new_node_ref = arena.new_node(Text::new(index));
533        self.try_insert_after(arena, target_ref, new_node_ref)?;
534        Ok(())
535    }
536
537    /// Merges a given index into the text node before the target node if
538    /// it can be merged, otherwise creates a new Text node and inserts it before the target node.
539    ///
540    /// # Panics
541    /// Panics if the operation fails(e.g. due to invalid NodeRef).
542    #[inline(always)]
543    pub fn merge_or_insert_before_text(
544        self,
545        arena: &mut Arena,
546        target_ref: NodeRef,
547        index: text::Index,
548    ) {
549        self.try_merge_or_insert_before_text(arena, target_ref, index)
550            .unwrap();
551    }
552
553    /// Merges a given index into the text node before the target node if
554    /// it can be merged, otherwise creates a new Text node and inserts it before the target node.
555    pub fn try_merge_or_insert_before_text(
556        self,
557        arena: &mut Arena,
558        target_ref: NodeRef,
559        index: text::Index,
560    ) -> Result<()> {
561        if let KindData::Text(text_node) = arena.try_get_mut(target_ref)?.kind_data_mut() {
562            if let Some(s) = text_node.index() {
563                if s.start() == index.stop() && !text_node.has_qualifiers(TextQualifier::TEMP) {
564                    text_node.value = (index.start(), s.stop()).into();
565                    return Ok(());
566                }
567            }
568        }
569        let new_node_ref = arena.new_node(Text::new(index));
570        self.try_insert_before(arena, target_ref, new_node_ref)?;
571        Ok(())
572    }
573}
574
575// }}}
576
577// Arena {{{
578
579/// Options for creating a new arena.
580#[derive(Debug, Clone, Copy)]
581pub struct ArenaOptions {
582    /// Size of the initial arena for nodes.
583    /// This defaults to 1024.
584    pub initial_size: usize,
585}
586
587impl Default for ArenaOptions {
588    fn default() -> Self {
589        Self { initial_size: 1024 }
590    }
591}
592
593/// Represents an arena for storing nodes in the single document.
594#[derive(Debug)]
595pub struct Arena {
596    /// The arena of nodes.
597    arena: Vec<Option<Node>>,
598
599    /// Unused (freed) indices in the arena.
600    free_indicies: Vec<usize>,
601
602    id_seq: usize,
603}
604
605impl Default for Arena {
606    fn default() -> Self {
607        Self::with_options(ArenaOptions::default())
608    }
609}
610
611impl Arena {
612    /// Creates a new arena with default options.
613    pub fn new() -> Self {
614        Self::default()
615    }
616
617    /// Creates a new arena with the specified options.
618    pub fn with_options(options: ArenaOptions) -> Self {
619        Self {
620            arena: Vec::with_capacity(options.initial_size),
621            free_indicies: Vec::with_capacity(options.initial_size / 16),
622            id_seq: 0,
623        }
624    }
625
626    /// Returns a Node for the given NodeRef.
627    #[inline(always)]
628    pub fn get(&self, id: NodeRef) -> Option<&Node> {
629        self.arena.get(id.cell).and_then(|node| node.as_ref())
630    }
631
632    #[inline(always)]
633    fn try_get(&self, id: NodeRef) -> Result<&Node> {
634        self.arena
635            .get(id.cell)
636            .and_then(|node| node.as_ref())
637            .ok_or_else(|| Error::invalid_node_ref(id))
638    }
639
640    /// Returns a mutable node to a Node for the given NodeRef.
641    #[inline(always)]
642    pub fn get_mut(&mut self, id: NodeRef) -> Option<&mut Node> {
643        self.arena.get_mut(id.cell).and_then(|node| node.as_mut())
644    }
645
646    #[inline(always)]
647    fn try_get_mut(&mut self, id: NodeRef) -> Result<&mut Node> {
648        self.arena
649            .get_mut(id.cell)
650            .and_then(|node| node.as_mut())
651            .ok_or_else(|| Error::invalid_node_ref(id))
652    }
653
654    /// Creates a new node ref with the given data.
655    /// `kind` must consistent with the type of `data`.
656    pub fn new_node<T: Into<KindData> + 'static>(&mut self, data: T) -> NodeRef {
657        let node = Node::new(data);
658
659        let cell = if let Some(index) = self.free_indicies.pop() {
660            self.arena[index] = Some(node);
661            index
662        } else {
663            let index = self.arena.len();
664            self.arena.push(Some(node));
665            index
666        };
667
668        let node_ref = NodeRef::new(cell, self.id_seq);
669        self.id_seq += 1;
670        node_ref
671    }
672}
673
674/// Implements indexing for Arena to access nodes by NodeRef.
675/// This panics if the NodeRef is invalid.
676impl Index<NodeRef> for Arena {
677    type Output = Node;
678    fn index(&self, node_ref: NodeRef) -> &Self::Output {
679        self.arena[node_ref.cell]
680            .as_ref()
681            .expect("Invalid node reference")
682    }
683}
684
685/// Implements mutable indexing for Arena to access nodes by NodeRef.
686/// This panics if the NodeRef is invalid.
687impl IndexMut<NodeRef> for Arena {
688    fn index_mut(&mut self, node_ref: NodeRef) -> &mut Self::Output {
689        self.arena[node_ref.cell]
690            .as_mut()
691            .expect("Invalid node reference")
692    }
693}
694
695// }}}
696
697// Metadata & Attributes {{{
698
699/// A value type for metadata.
700#[derive(Debug, Clone, Default, PartialEq)]
701pub enum Meta {
702    #[default]
703    Null,
704    Bool(bool),
705    Int(i64),
706    Float(f64),
707    String(String),
708    Sequence(Vec<Meta>),
709    Mapping(StringMap<Meta>),
710}
711
712macro_rules! impl_meta_as {
713    ($name: ident, $variant:ident, $ty:ty) => {
714        /// Returns the value if this Meta is a $variant, otherwise returns None.
715        pub fn $name(&self) -> Option<&$ty> {
716            let Meta::$variant(v) = self else { return None };
717            Some(v)
718        }
719    };
720}
721
722impl Meta {
723    /// Takes the value of this Meta, leaving Null in its place.
724    pub fn take(&mut self) -> Meta {
725        core::mem::replace(self, Meta::Null)
726    }
727
728    /// Returns a mutable reference to the value if this Meta is a Mapping, otherwise returns None.
729    pub fn as_mapping_mut(&mut self) -> Option<&mut StringMap<Meta>> {
730        let Meta::Mapping(m) = self else { return None };
731        Some(m)
732    }
733
734    /// Returns a mutable reference to the value if this Meta is a Sequence, otherwise returns
735    /// None.
736    pub fn as_sequence_mut(&mut self) -> Option<&mut Vec<Meta>> {
737        let Meta::Sequence(s) = self else { return None };
738        Some(s)
739    }
740
741    impl_meta_as!(as_bool, Bool, bool);
742    impl_meta_as!(as_int, Int, i64);
743    impl_meta_as!(as_float, Float, f64);
744    impl_meta_as!(as_str, String, str);
745    impl_meta_as!(as_sequence, Sequence, Vec<Meta>);
746    impl_meta_as!(as_mapping, Mapping, StringMap<Meta>);
747}
748
749/// Metadata associated with a document.
750pub type Metadata = StringMap<Meta>;
751
752/// Attributes associated with a node.
753pub type Attributes = StringMap<text::MultilineValue>;
754
755// }}} Metadata & Attributes
756
757// Node & Data {{{
758
759/// Represents the data of a node in the document.
760/// This is an enum that can hold different types of node data.
761#[derive(Debug)]
762#[non_exhaustive]
763pub enum KindData {
764    Document(Document),
765    Paragraph(Paragraph),
766    Heading(Heading),
767    ThematicBreak(ThematicBreak),
768    CodeBlock(CodeBlock),
769    Blockquote(Blockquote),
770    List(List),
771    ListItem(ListItem),
772    HtmlBlock(HtmlBlock),
773    Text(Text),
774    CodeSpan(CodeSpan),
775    Emphasis(Emphasis),
776    Link(Link),
777    Image(Image),
778    RawHtml(RawHtml),
779    LinkReferenceDefinition(LinkReferenceDefinition),
780
781    Table(Table),
782    TableHeader(TableHeader),
783    TableBody(TableBody),
784    TableRow(TableRow),
785    TableCell(TableCell),
786
787    Strikethrough(Strikethrough),
788
789    Extension(Box<dyn ExtensionData>),
790}
791
792impl KindData {
793    /// Returns the type of the node.
794    pub fn typ(&self) -> NodeType {
795        match self {
796            KindData::Document(n) => n.typ(),
797            KindData::Paragraph(n) => n.typ(),
798            KindData::Heading(n) => n.typ(),
799            KindData::ThematicBreak(n) => n.typ(),
800            KindData::CodeBlock(n) => n.typ(),
801            KindData::Blockquote(n) => n.typ(),
802            KindData::List(n) => n.typ(),
803            KindData::ListItem(n) => n.typ(),
804            KindData::HtmlBlock(n) => n.typ(),
805            KindData::Text(n) => n.typ(),
806            KindData::CodeSpan(n) => n.typ(),
807            KindData::Emphasis(n) => n.typ(),
808            KindData::Link(n) => n.typ(),
809            KindData::Image(n) => n.typ(),
810            KindData::RawHtml(n) => n.typ(),
811            KindData::LinkReferenceDefinition(n) => n.typ(),
812
813            KindData::Table(n) => n.typ(),
814            KindData::TableHeader(n) => n.typ(),
815            KindData::TableBody(n) => n.typ(),
816            KindData::TableRow(n) => n.typ(),
817            KindData::TableCell(n) => n.typ(),
818
819            KindData::Strikethrough(n) => n.typ(),
820
821            KindData::Extension(n) => n.typ(),
822        }
823    }
824
825    /// Returns the kind name of the node.
826    pub fn kind_name(&self) -> &'static str {
827        match self {
828            KindData::Document(n) => n.kind_name(),
829            KindData::Paragraph(n) => n.kind_name(),
830            KindData::Heading(n) => n.kind_name(),
831            KindData::ThematicBreak(n) => n.kind_name(),
832            KindData::CodeBlock(n) => n.kind_name(),
833            KindData::Blockquote(n) => n.kind_name(),
834            KindData::List(n) => n.kind_name(),
835            KindData::ListItem(n) => n.kind_name(),
836            KindData::HtmlBlock(n) => n.kind_name(),
837            KindData::Text(n) => n.kind_name(),
838            KindData::CodeSpan(n) => n.kind_name(),
839            KindData::Emphasis(n) => n.kind_name(),
840            KindData::Link(n) => n.kind_name(),
841            KindData::Image(n) => n.kind_name(),
842            KindData::RawHtml(n) => n.kind_name(),
843            KindData::LinkReferenceDefinition(n) => n.kind_name(),
844
845            KindData::Table(n) => n.kind_name(),
846            KindData::TableHeader(n) => n.kind_name(),
847            KindData::TableBody(n) => n.kind_name(),
848            KindData::TableRow(n) => n.kind_name(),
849            KindData::TableCell(n) => n.kind_name(),
850
851            KindData::Strikethrough(n) => n.kind_name(),
852
853            KindData::Extension(n) => n.kind_name(),
854        }
855    }
856
857    /// Pretty prints the node data.
858    pub fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
859        match self {
860            KindData::Document(n) => n.pretty_print(w, source, level),
861            KindData::Paragraph(n) => n.pretty_print(w, source, level),
862            KindData::Heading(n) => n.pretty_print(w, source, level),
863            KindData::ThematicBreak(n) => n.pretty_print(w, source, level),
864            KindData::CodeBlock(n) => n.pretty_print(w, source, level),
865            KindData::Blockquote(n) => n.pretty_print(w, source, level),
866            KindData::List(n) => n.pretty_print(w, source, level),
867            KindData::ListItem(n) => n.pretty_print(w, source, level),
868            KindData::HtmlBlock(n) => n.pretty_print(w, source, level),
869            KindData::Text(n) => n.pretty_print(w, source, level),
870            KindData::CodeSpan(n) => n.pretty_print(w, source, level),
871            KindData::Emphasis(n) => n.pretty_print(w, source, level),
872            KindData::Link(n) => n.pretty_print(w, source, level),
873            KindData::Image(n) => n.pretty_print(w, source, level),
874            KindData::RawHtml(n) => n.pretty_print(w, source, level),
875            KindData::LinkReferenceDefinition(n) => n.pretty_print(w, source, level),
876
877            KindData::Table(n) => n.pretty_print(w, source, level),
878            KindData::TableHeader(n) => n.pretty_print(w, source, level),
879            KindData::TableBody(n) => n.pretty_print(w, source, level),
880            KindData::TableRow(n) => n.pretty_print(w, source, level),
881            KindData::TableCell(n) => n.pretty_print(w, source, level),
882
883            KindData::Strikethrough(n) => n.pretty_print(w, source, level),
884
885            KindData::Extension(n) => n.pretty_print(w, source, level),
886        }
887    }
888}
889
890/// An enum representing the type of a node: Block or Inline.
891#[derive(Debug, PartialEq, Eq, Copy, Clone)]
892#[non_exhaustive]
893pub enum NodeType {
894    ContainerBlock,
895    LeafBlock,
896    Inline,
897}
898
899impl From<NodeType> for TypeData {
900    fn from(t: NodeType) -> Self {
901        match t {
902            NodeType::ContainerBlock => TypeData::Block(Block {
903                btype: BlockType::Container,
904                ..Default::default()
905            }),
906            NodeType::LeafBlock => TypeData::Block(Block {
907                btype: BlockType::Leaf,
908                ..Default::default()
909            }),
910            NodeType::Inline => TypeData::Inline(Inline::default()),
911        }
912    }
913}
914
915/// A Data associated with its [`NodeType`].
916#[derive(Debug)]
917#[non_exhaustive]
918pub enum TypeData {
919    Block(Block),
920    Inline(Inline),
921}
922
923/// Types of blocks.
924#[derive(Debug, PartialEq, Eq)]
925#[non_exhaustive]
926pub enum BlockType {
927    Container,
928    Leaf,
929}
930
931/// A Data associated with block type nodes.
932#[derive(Debug)]
933pub struct Block {
934    btype: BlockType,
935
936    source: Option<Vec<text::Segment>>,
937
938    has_blank_previous_line: bool,
939}
940
941impl Default for Block {
942    fn default() -> Self {
943        Self {
944            btype: BlockType::Container,
945            source: None,
946            has_blank_previous_line: false,
947        }
948    }
949}
950
951impl Block {
952    /// Returns true if this block is a container block.
953    #[inline(always)]
954    pub fn is_container(&self) -> bool {
955        self.btype == BlockType::Container
956    }
957
958    /// Returns true if this block is a leaf block.
959    #[inline(always)]
960    pub fn is_leaf(&self) -> bool {
961        self.btype == BlockType::Leaf
962    }
963
964    /// Takes the source of this block, leaving None in its place.
965    pub fn take_source(&mut self) -> Vec<text::Segment> {
966        self.source.take().unwrap_or_default()
967    }
968
969    /// Puts back the source of this block.
970    pub fn put_back_source(&mut self, source: Vec<text::Segment>) {
971        self.source = Some(source);
972    }
973
974    /// Returns the source of this block.
975    /// This value will be parsed into children inline nodes of this block.
976    #[inline(always)]
977    pub fn source(&self) -> &text::Block {
978        self.source.as_deref().unwrap_or(&[])
979    }
980
981    /// Appends a source line to this block.
982    #[inline(always)]
983    pub fn append_source_line(&mut self, line: text::Segment) {
984        if let Some(source) = &mut self.source {
985            source.push(line);
986        } else {
987            self.source = Some(Vec::with_capacity(16));
988            self.source.as_mut().unwrap().push(line);
989        }
990    }
991
992    /// Appends source lines to this block.
993    #[inline(always)]
994    pub fn append_source_lines(&mut self, lines: &text::Block) {
995        if let Some(source) = &mut self.source {
996            source.extend_from_slice(lines);
997        } else {
998            self.source = Some(lines.to_vec());
999        }
1000    }
1001
1002    /// Replaces a source line at the given index with the given line.
1003    #[inline(always)]
1004    pub fn replace_source_line(&mut self, index: usize, line: text::Segment) {
1005        if let Some(source) = &mut self.source {
1006            if index < source.len() {
1007                source[index] = line;
1008            }
1009        }
1010    }
1011
1012    /// Removes a source line at the given index.
1013    #[inline(always)]
1014    pub fn remove_source_line(&mut self, index: usize) {
1015        if let Some(source) = &mut self.source {
1016            if index < source.len() {
1017                source.remove(index);
1018            }
1019        }
1020    }
1021
1022    /// Returns true if this block has a blank line before it.
1023    #[inline(always)]
1024    pub fn has_blank_previous_line(&self) -> bool {
1025        self.has_blank_previous_line
1026    }
1027
1028    /// Sets whether this block has a blank line before it.
1029    #[inline(always)]
1030    pub fn set_blank_previous_line(&mut self, value: bool) {
1031        self.has_blank_previous_line = value;
1032    }
1033}
1034
1035/// A Data associated with inline type nodes.
1036#[derive(Debug, Default)]
1037pub struct Inline {}
1038
1039/// Represents a node in the document.
1040#[derive(Debug)]
1041pub struct Node {
1042    kind_data: KindData,
1043    type_data: TypeData,
1044    parent: Option<NodeRef>,
1045    first_child: Option<NodeRef>,
1046    next_sibling: Option<NodeRef>,
1047    previous_sibling: Option<NodeRef>,
1048    last_child: Option<NodeRef>,
1049    attributes: Attributes,
1050    pos: Option<usize>,
1051}
1052
1053impl Node {
1054    pub fn new<T: Into<KindData> + 'static>(data: T) -> Self {
1055        let d: KindData = data.into();
1056        let t: NodeType = d.typ();
1057        Self {
1058            kind_data: d,
1059            type_data: t.into(),
1060            parent: None,
1061            first_child: None,
1062            next_sibling: None,
1063            previous_sibling: None,
1064            last_child: None,
1065            attributes: Attributes::new(),
1066            pos: None,
1067        }
1068    }
1069
1070    /// Returns the data of the node.
1071    pub fn kind_data(&self) -> &KindData {
1072        &self.kind_data
1073    }
1074
1075    /// Returns mutable data of the node.
1076    pub fn kind_data_mut(&mut self) -> &mut KindData {
1077        &mut self.kind_data
1078    }
1079
1080    /// Returns the data of the node for its type.
1081    pub fn type_data(&self) -> &TypeData {
1082        &self.type_data
1083    }
1084
1085    /// Returns mutable data of the node for its type.
1086    pub fn type_data_mut(&mut self) -> &mut TypeData {
1087        &mut self.type_data
1088    }
1089
1090    /// Returns the parent of the node.
1091    #[inline(always)]
1092    pub fn parent(&self) -> Option<NodeRef> {
1093        self.parent
1094    }
1095
1096    /// Sets the parent of the node.
1097    #[inline(always)]
1098    pub fn set_parent(&mut self, parent: NodeRef) {
1099        self.parent = Some(parent);
1100    }
1101
1102    /// Returns the first child of the node.
1103    #[inline(always)]
1104    pub fn first_child(&self) -> Option<NodeRef> {
1105        self.first_child
1106    }
1107
1108    /// Returns true if has any child.
1109    #[inline(always)]
1110    pub fn has_children(&self) -> bool {
1111        self.first_child.is_some()
1112    }
1113
1114    /// Sets the first child of the node.
1115    #[inline(always)]
1116    pub fn set_first_child(&mut self, child: NodeRef) {
1117        self.first_child = Some(child);
1118    }
1119
1120    /// Returns the next sibling of the node.
1121    #[inline(always)]
1122    pub fn next_sibling(&self) -> Option<NodeRef> {
1123        self.next_sibling
1124    }
1125
1126    /// Sets the next sibling of the node.
1127    #[inline(always)]
1128    pub fn set_next_sibling(&mut self, sibling: NodeRef) {
1129        self.next_sibling = Some(sibling);
1130    }
1131
1132    /// Returns the previous sibling of the node.
1133    #[inline(always)]
1134    pub fn previous_sibling(&self) -> Option<NodeRef> {
1135        self.previous_sibling
1136    }
1137
1138    /// Sets the previous sibling of the node.
1139    #[inline(always)]
1140    pub fn set_previous_sibling(&mut self, sibling: NodeRef) {
1141        self.previous_sibling = Some(sibling);
1142    }
1143
1144    /// Returns the last child of the node.
1145    #[inline(always)]
1146    pub fn last_child(&self) -> Option<NodeRef> {
1147        self.last_child
1148    }
1149
1150    /// Sets the last child of the node.
1151    #[inline(always)]
1152    pub fn set_last_child(&mut self, child: NodeRef) {
1153        self.last_child = Some(child);
1154    }
1155
1156    /// Returns the last child of the node.
1157    /// Since this method keeps arena reference,
1158    /// you can not mutate the node data through this method.
1159    /// Mutating the node data requires a mutable reference to the arena.
1160    #[inline(always)]
1161    pub fn children<'a>(&self, arena: &'a Arena) -> Siblings<'a> {
1162        Siblings {
1163            arena,
1164            front: self.first_child,
1165            back: self.last_child,
1166        }
1167    }
1168
1169    /// Returns the children of the node as a vector.
1170    /// Since this method does keep arena reference,
1171    /// you can mutate the node data through this method.
1172    #[inline(always)]
1173    pub fn children_mut(&self, arena: &Arena) -> NodesMut {
1174        NodesMut::with_vec(self.children(arena).collect())
1175    }
1176
1177    /// Returns the attributes of the node.
1178    #[inline(always)]
1179    pub fn attributes(&self) -> &Attributes {
1180        &self.attributes
1181    }
1182
1183    /// Returns mutable attributes of the node.
1184    #[inline(always)]
1185    pub fn attributes_mut(&mut self) -> &mut Attributes {
1186        &mut self.attributes
1187    }
1188
1189    /// Sets the position of the node in the source text.
1190    #[inline(always)]
1191    pub fn set_pos(&mut self, pos: usize) {
1192        self.pos = Some(pos);
1193    }
1194
1195    pub(crate) fn has_pos(&self) -> bool {
1196        self.pos.is_some()
1197    }
1198
1199    /// Returns the position of the node in the source text if available, otherwise returns None.
1200    #[inline(always)]
1201    pub fn pos(&self) -> Option<usize> {
1202        match &self.kind_data() {
1203            KindData::Text(n) => n.index().map(|i| i.start()),
1204            _ => self.pos,
1205        }
1206    }
1207
1208    /// Returns the owner document of the node if available, otherwise returns None.
1209    pub fn owner_document(&self, arena: &Arena) -> Option<NodeRef> {
1210        let mut current = self.parent?;
1211        while let Some(parent) = arena.get(current)?.parent {
1212            current = parent;
1213        }
1214        if matches!(arena[current].kind_data(), KindData::Document(_)) {
1215            Some(current)
1216        } else {
1217            None
1218        }
1219    }
1220}
1221
1222/// An iterator over the siblings of a node in the arena.
1223pub struct Siblings<'a> {
1224    arena: &'a Arena,
1225    front: Option<NodeRef>,
1226    back: Option<NodeRef>,
1227}
1228
1229impl Iterator for Siblings<'_> {
1230    type Item = NodeRef;
1231    fn next(&mut self) -> Option<Self::Item> {
1232        if let Some(current) = self.front {
1233            let node = self.arena.get(current)?;
1234            self.front = node.next_sibling;
1235            if self.back.is_none() {
1236                self.back = Some(current);
1237            }
1238            Some(current)
1239        } else {
1240            None
1241        }
1242    }
1243}
1244
1245impl DoubleEndedIterator for Siblings<'_> {
1246    fn next_back(&mut self) -> Option<Self::Item> {
1247        if let Some(current) = self.back {
1248            let node = self.arena.get(current)?;
1249            self.back = node.previous_sibling;
1250            if self.front.is_none() {
1251                self.front = Some(current);
1252            }
1253            Some(current)
1254        } else {
1255            None
1256        }
1257    }
1258}
1259
1260/// A mutable iterator over nodes in the arena.
1261pub struct NodesMut {
1262    iter: vec::IntoIter<NodeRef>,
1263}
1264
1265impl NodesMut {
1266    /// Creates a new NodesMut from a vector of NodeRefs.
1267    fn with_vec(vec: Vec<NodeRef>) -> Self {
1268        NodesMut {
1269            iter: vec.into_iter(),
1270        }
1271    }
1272}
1273
1274impl Iterator for NodesMut {
1275    type Item = NodeRef;
1276    fn next(&mut self) -> Option<Self::Item> {
1277        self.iter.next()
1278    }
1279}
1280
1281impl DoubleEndedIterator for NodesMut {
1282    fn next_back(&mut self) -> Option<Self::Item> {
1283        self.iter.next_back()
1284    }
1285}
1286
1287/// Trait for pretty printing nodes.
1288pub trait PrettyPrint {
1289    /// Pretty prints the node data.
1290    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result;
1291}
1292
1293/// Trait for node kinds.
1294pub trait NodeKind {
1295    /// Returns the type of this kind belongs to.
1296    fn typ(&self) -> NodeType;
1297
1298    /// Returns the kind name.
1299    fn kind_name(&self) -> &'static str;
1300}
1301
1302fn pp(
1303    w: &mut dyn Write,
1304    arena: &Arena,
1305    node_ref: NodeRef,
1306    source: &str,
1307    level: usize,
1308) -> fmt::Result {
1309    let indent = pp_indent(level);
1310    {
1311        let node = arena.get(node_ref).ok_or(fmt::Error)?;
1312
1313        writeln!(w, "{}{} {{", indent, node.kind_data.kind_name())?;
1314        node.kind_data.pretty_print(w, source, level + 1)?;
1315    }
1316    let indent2 = pp_indent(level + 1);
1317    let indent3 = pp_indent(level + 2);
1318    writeln!(w, "{}Ref: {}", indent2, node_ref)?;
1319    writeln!(
1320        w,
1321        "{}Pos: {}",
1322        indent2,
1323        arena[node_ref]
1324            .pos()
1325            .map_or(String::from("None"), |p| format!("{}", p))
1326    )?;
1327    if let TypeData::Block(block) = arena[node_ref].type_data() {
1328        if block.source().is_empty() {
1329            writeln!(w, "{}Source: []", indent2)?;
1330        } else {
1331            writeln!(w, "{}Source: [", indent2)?;
1332            let mut nr = false;
1333            for line in block.source() {
1334                let l = line.str(source);
1335                write!(w, "{}{}", indent3, l)?;
1336                nr = l.ends_with('\n') || l.ends_with('\r');
1337            }
1338            if !nr {
1339                writeln!(w)?;
1340            }
1341            writeln!(w, "{}]", indent2)?;
1342        }
1343        if block.has_blank_previous_line() {
1344            writeln!(w, "{}HasBlankPreviousLine: true", indent2)?;
1345        } else {
1346            writeln!(w, "{}HasBlankPreviousLine: false", indent2)?;
1347        }
1348    }
1349
1350    if !arena[node_ref].attributes().is_empty() {
1351        write!(w, "{}Attributes ", indent2)?;
1352        writeln!(w, "{{")?;
1353        for (key, value) in arena[node_ref].attributes() {
1354            write!(w, "{}{}: ", indent3, key)?;
1355            writeln!(w, "{}", value.str(source))?;
1356        }
1357        write!(w, "{}", indent2)?;
1358        writeln!(w, "}}")?;
1359    }
1360
1361    for child in arena[node_ref].children(arena) {
1362        pp(w, arena, child, source, level + 1)?;
1363    }
1364
1365    write!(w, "{}", indent)?;
1366    writeln!(w, "}}")
1367}
1368
1369/// Pretty prints the AST.
1370pub fn pretty_print(
1371    w: &mut dyn Write,
1372    arena: &Arena,
1373    node_ref: NodeRef,
1374    source: &str,
1375) -> fmt::Result {
1376    pp(w, arena, node_ref, source, 0)
1377}
1378
1379/// Returns a string with indentation for pretty printing.
1380pub fn pp_indent(level: usize) -> String {
1381    "  ".repeat(level)
1382}
1383
1384// }}}
1385
1386// Walk {{{
1387
1388/// Status for walking the AST.
1389#[derive(Debug, PartialEq, Eq)]
1390#[non_exhaustive]
1391pub enum WalkStatus {
1392    /// Indicates no more walking needed.
1393    Stop,
1394
1395    /// Indicates that Walk wont walk on children of current node.
1396    SkipChildren,
1397
1398    /// Indicates that Walk should continue walking.
1399    Continue,
1400
1401    /// Indicates that Walk is done.
1402    Ok,
1403}
1404
1405/// Trait for walking the AST.
1406/// You can not mutate the AST while walking it.
1407/// If you want to mutate the AST, collect the node refs and mutate them after walking.
1408pub trait Walk<E> {
1409    fn walk(
1410        &mut self,
1411        arena: &Arena,
1412        node_ref: NodeRef,
1413        entering: bool,
1414    ) -> CoreResult<WalkStatus, E>;
1415}
1416
1417impl<F, E> Walk<E> for F
1418where
1419    F: FnMut(&Arena, NodeRef, bool) -> CoreResult<WalkStatus, E>,
1420{
1421    fn walk(
1422        &mut self,
1423        arena: &Arena,
1424        node_ref: NodeRef,
1425        entering: bool,
1426    ) -> CoreResult<WalkStatus, E> {
1427        self(arena, node_ref, entering)
1428    }
1429}
1430
1431/// Walks the AST starting from the given node reference.
1432/// You can not mutate the AST while walking it.
1433/// If you want to mutate the AST, collect the node refs and mutate them after walking.
1434///
1435/// # Examples
1436///
1437/// ```rust
1438/// use core::result::Result;
1439/// use core::error::Error;
1440/// use core::fmt::{self, Display, Formatter};
1441/// use rushdown::ast::*;
1442/// use rushdown::matches_kind;
1443///
1444/// #[derive(Debug)]
1445/// enum UserError { SomeError(&'static str) }
1446///
1447/// impl Error for UserError {}
1448///
1449/// impl Display for UserError {
1450///     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1451///         match self { UserError::SomeError(msg) => write!(f, "UserError: {}", msg) }
1452///     }
1453/// }
1454///
1455/// let mut arena = Arena::default();
1456/// let doc_ref = arena.new_node(Document::new());
1457/// let paragraph_ref1 = arena.new_node(Paragraph::default());
1458/// let text1 = arena.new_node(Text::new("Hello, World!"));
1459/// let paragraph_ref2 = arena.new_node(Paragraph::default());
1460/// let text2 = arena.new_node(Text::new("This is a test."));
1461///
1462/// doc_ref.append_child(&mut arena, paragraph_ref1);
1463/// paragraph_ref1.append_child(&mut arena, text1);
1464/// doc_ref.append_child(&mut arena, paragraph_ref2);
1465/// paragraph_ref2.append_child(&mut arena, text2);
1466///
1467/// let mut target: Option<NodeRef> = None;
1468///
1469/// walk(&arena, doc_ref, &mut |arena: &Arena,
1470///                             node_ref: NodeRef,
1471///                             entering: bool| -> Result<WalkStatus, UserError > {
1472///     if entering {
1473///         if let Some(fc) = arena[node_ref].first_child() {
1474///             if let KindData::Text(t) = &arena[fc].kind_data() {
1475///                 if t.str("").contains("test") {
1476///                     target = Some(node_ref);
1477///                 }
1478///                 if t.str("").contains("error") {
1479///                     return Err(UserError::SomeError("Some error occurred"));
1480///                 }
1481///             }
1482///         }
1483///     }
1484///     Ok(WalkStatus::Continue)
1485/// }).ok();
1486/// assert_eq!(target, Some(paragraph_ref2));
1487/// ```
1488///
1489pub fn walk<E: CoreError + 'static>(
1490    arena: &Arena,
1491    node_ref: NodeRef,
1492    walker: &mut impl Walk<E>,
1493) -> CoreResult<WalkStatus, CallbackError<E>> {
1494    let status = walker
1495        .walk(arena, node_ref, true)
1496        .map_err(CallbackError::Callback)?;
1497    if status == WalkStatus::Stop {
1498        return Ok(WalkStatus::Stop);
1499    }
1500
1501    if status != WalkStatus::SkipChildren {
1502        let node = arena.try_get(node_ref).map_err(CallbackError::Internal)?;
1503        let mut child_opt = node.first_child();
1504        while let Some(child_ref) = child_opt {
1505            let child_node = arena.try_get(child_ref).map_err(CallbackError::Internal)?;
1506            if walk(arena, child_ref, walker)? == WalkStatus::Stop {
1507                return Ok(WalkStatus::Stop);
1508            }
1509            child_opt = child_node.next_sibling();
1510        }
1511    }
1512
1513    if walker
1514        .walk(arena, node_ref, false)
1515        .map_err(CallbackError::Callback)?
1516        == WalkStatus::Stop
1517    {
1518        return Ok(WalkStatus::Stop);
1519    }
1520
1521    Ok(WalkStatus::Ok)
1522}
1523
1524// }}} Walk
1525
1526// Blocks {{{
1527
1528//   Document {{{
1529
1530/// Represents the root document node.
1531#[derive(Debug)]
1532pub struct Document {
1533    meta: Metadata,
1534}
1535
1536impl Default for Document {
1537    fn default() -> Self {
1538        Self {
1539            meta: Metadata::new(),
1540        }
1541    }
1542}
1543
1544impl Document {
1545    /// Creates a new [`Document`] node.
1546    pub fn new() -> Self {
1547        Self::default()
1548    }
1549
1550    /// Returns the metadata of the document.
1551    #[inline(always)]
1552    pub fn metadata(&self) -> &Metadata {
1553        &self.meta
1554    }
1555
1556    /// Returns mutable attributes of the document.
1557    #[inline(always)]
1558    pub fn metadata_mut(&mut self) -> &mut Metadata {
1559        &mut self.meta
1560    }
1561}
1562
1563impl NodeKind for Document {
1564    fn typ(&self) -> NodeType {
1565        NodeType::ContainerBlock
1566    }
1567
1568    fn kind_name(&self) -> &'static str {
1569        "Document"
1570    }
1571}
1572
1573impl PrettyPrint for Document {
1574    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
1575        Ok(())
1576    }
1577}
1578
1579impl From<Document> for KindData {
1580    fn from(data: Document) -> Self {
1581        KindData::Document(data)
1582    }
1583}
1584
1585//   }}}
1586
1587//   Paragraph {{{
1588
1589/// Represents a paragraph node.
1590#[derive(Debug, Default)]
1591pub struct Paragraph {}
1592
1593impl Paragraph {
1594    /// Creates a new [`Paragraph`] node.
1595    pub fn new() -> Self {
1596        Self::default()
1597    }
1598}
1599
1600impl NodeKind for Paragraph {
1601    fn typ(&self) -> NodeType {
1602        NodeType::LeafBlock
1603    }
1604
1605    fn kind_name(&self) -> &'static str {
1606        "Paragraph"
1607    }
1608}
1609
1610impl PrettyPrint for Paragraph {
1611    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
1612        Ok(())
1613    }
1614}
1615
1616impl From<Paragraph> for KindData {
1617    fn from(data: Paragraph) -> Self {
1618        KindData::Paragraph(data)
1619    }
1620}
1621
1622//   }}} Paragraph
1623
1624//   Heading {{{
1625
1626/// Kinds of headings.
1627#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
1628#[non_exhaustive]
1629pub enum HeadingKind {
1630    #[default]
1631    Atx,
1632    Setext,
1633}
1634
1635/// Represents a heading node.
1636#[derive(Debug, Default)]
1637pub struct Heading {
1638    heading_kind: HeadingKind,
1639    level: u8,
1640}
1641
1642impl Heading {
1643    /// Creates a new [`Heading`] with the given level.
1644    pub fn new(heading_kind: HeadingKind, level: u8) -> Self {
1645        Self {
1646            heading_kind,
1647            level,
1648        }
1649    }
1650
1651    /// Returns the level of the heading.
1652    #[inline(always)]
1653    pub fn level(&self) -> u8 {
1654        self.level
1655    }
1656
1657    /// Returns the kind of the heading.
1658    #[inline(always)]
1659    pub fn heading_kind(&self) -> HeadingKind {
1660        self.heading_kind
1661    }
1662}
1663
1664impl NodeKind for Heading {
1665    fn typ(&self) -> NodeType {
1666        NodeType::LeafBlock
1667    }
1668
1669    fn kind_name(&self) -> &'static str {
1670        "Heading"
1671    }
1672}
1673
1674impl PrettyPrint for Heading {
1675    fn pretty_print(&self, w: &mut dyn Write, _source: &str, level: usize) -> fmt::Result {
1676        writeln!(w, "{}Level: {}", pp_indent(level), self.level())
1677    }
1678}
1679
1680impl From<Heading> for KindData {
1681    fn from(data: Heading) -> Self {
1682        KindData::Heading(data)
1683    }
1684}
1685
1686//   }}} Heading
1687
1688//   ThematicBreak {{{
1689
1690/// Represents a thematic break node.
1691#[derive(Debug, Default)]
1692pub struct ThematicBreak {}
1693
1694impl ThematicBreak {
1695    /// Creates a new [`ThematicBreak`] node.
1696    pub fn new() -> Self {
1697        Self::default()
1698    }
1699}
1700
1701impl NodeKind for ThematicBreak {
1702    fn typ(&self) -> NodeType {
1703        NodeType::LeafBlock
1704    }
1705
1706    fn kind_name(&self) -> &'static str {
1707        "ThematicBreak"
1708    }
1709}
1710
1711impl PrettyPrint for ThematicBreak {
1712    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
1713        Ok(())
1714    }
1715}
1716
1717impl From<ThematicBreak> for KindData {
1718    fn from(data: ThematicBreak) -> Self {
1719        KindData::ThematicBreak(data)
1720    }
1721}
1722
1723//   }}} ThematicBreak
1724
1725//   CodeBlock {{{
1726
1727/// Kinds of code blocks.
1728#[derive(Debug, PartialEq, Eq, Copy, Clone)]
1729#[non_exhaustive]
1730pub enum CodeBlockKind {
1731    Indented,
1732    Fenced,
1733}
1734
1735#[derive(Debug)]
1736pub(crate) struct FenceData {
1737    pub char: u8,
1738    pub indent: usize,
1739    pub length: usize,
1740}
1741
1742/// Represents a code block node.
1743#[derive(Debug)]
1744pub struct CodeBlock {
1745    code_block_kind: CodeBlockKind,
1746    info: Option<text::Value>,
1747    fdata: Option<FenceData>,
1748    value: text::Lines,
1749}
1750
1751impl CodeBlock {
1752    /// Creates a new [`CodeBlock`] node.
1753    pub fn new(code_block_kind: CodeBlockKind, info: Option<text::Value>) -> Self {
1754        Self {
1755            code_block_kind,
1756            info,
1757            fdata: None,
1758            value: text::Lines::default(),
1759        }
1760    }
1761
1762    /// Returns the kind of the code block.
1763    #[inline(always)]
1764    pub fn code_block_kind(&self) -> CodeBlockKind {
1765        self.code_block_kind
1766    }
1767
1768    /// Returns the value of the code block.
1769    #[inline(always)]
1770    pub fn value(&self) -> &text::Lines {
1771        &self.value
1772    }
1773
1774    /// Sets the value of the code block.
1775    #[inline(always)]
1776    pub fn set_value(&mut self, value: impl Into<text::Lines>) {
1777        self.value = value.into();
1778    }
1779
1780    pub(crate) fn fence_data(&self) -> Option<&FenceData> {
1781        self.fdata.as_ref()
1782    }
1783
1784    pub(crate) fn set_fence_data(&mut self, fdata: FenceData) {
1785        self.fdata = Some(fdata);
1786    }
1787
1788    /// Returns the info string of the fenced code block.
1789    #[inline(always)]
1790    pub fn info_str<'a>(&'a self, source: &'a str) -> Option<&'a str> {
1791        match &self.info {
1792            Some(info) => Some(info.str(source)),
1793            None => None,
1794        }
1795    }
1796
1797    /// Returns the info value of the fenced code block.
1798    #[inline(always)]
1799    pub fn info(&self) -> Option<&text::Value> {
1800        self.info.as_ref()
1801    }
1802
1803    /// Returns the language of the fenced code block, if specified.
1804    pub fn language_str<'a>(&'a self, source: &'a str) -> Option<&'a str> {
1805        match &self.info {
1806            Some(info) => {
1807                let info_str = info.str(source);
1808                info_str
1809                    .find(' ')
1810                    .map(|i| &info_str[..i])
1811                    .or(Some(info_str))
1812            }
1813            None => None,
1814        }
1815    }
1816}
1817
1818impl NodeKind for CodeBlock {
1819    fn typ(&self) -> NodeType {
1820        NodeType::LeafBlock
1821    }
1822
1823    fn kind_name(&self) -> &'static str {
1824        "CodeBlock"
1825    }
1826}
1827
1828impl PrettyPrint for CodeBlock {
1829    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
1830        writeln!(
1831            w,
1832            "{}CodeBlockKind: {}",
1833            pp_indent(level),
1834            match self.code_block_kind {
1835                CodeBlockKind::Indented => "Indented",
1836                CodeBlockKind::Fenced => "Fenced",
1837            }
1838        )?;
1839        writeln!(
1840            w,
1841            "{}Info: {}",
1842            pp_indent(level),
1843            match self.info_str(source) {
1844                Some(info) => info,
1845                None => &"<none>",
1846            }
1847        )?;
1848        write!(w, "{}Value: ", pp_indent(level))?;
1849        writeln!(w, "[ ")?;
1850        for line in self.value.iter(source) {
1851            write!(w, "{}{}", pp_indent(level + 1), line)?;
1852        }
1853        writeln!(w)?;
1854        writeln!(w, "{}]", pp_indent(level))
1855    }
1856}
1857
1858impl From<CodeBlock> for KindData {
1859    fn from(data: CodeBlock) -> Self {
1860        KindData::CodeBlock(data)
1861    }
1862}
1863
1864//   }}} CodeBlock
1865
1866//   Blockquote {{{
1867
1868/// Represents a block quote node.
1869#[derive(Debug, Default)]
1870pub struct Blockquote {}
1871
1872impl Blockquote {
1873    /// Creates a new [`Blockquote`] node.
1874    pub fn new() -> Self {
1875        Self::default()
1876    }
1877}
1878
1879impl NodeKind for Blockquote {
1880    fn typ(&self) -> NodeType {
1881        NodeType::ContainerBlock
1882    }
1883
1884    fn kind_name(&self) -> &'static str {
1885        "Blockquote"
1886    }
1887}
1888
1889impl PrettyPrint for Blockquote {
1890    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
1891        Ok(())
1892    }
1893}
1894
1895impl From<Blockquote> for KindData {
1896    fn from(data: Blockquote) -> Self {
1897        KindData::Blockquote(data)
1898    }
1899}
1900
1901//   }}} Blockquote
1902
1903//   List {{{
1904
1905/// Represents a list node.
1906#[derive(Debug, Default)]
1907pub struct List {
1908    marker: u8,
1909
1910    is_tight: bool,
1911
1912    start: u32,
1913}
1914
1915impl List {
1916    /// Creates a new [`List`] node.
1917    pub fn new(marker: u8) -> Self {
1918        Self {
1919            marker,
1920            is_tight: true,
1921            start: 0,
1922        }
1923    }
1924
1925    /// Returns true if this list is an ordered list.
1926    #[inline(always)]
1927    pub fn is_ordered(&self) -> bool {
1928        self.marker == b'.' || self.marker == b')'
1929    }
1930
1931    /// Returns true if this list can continue with
1932    /// the given mark and a list type, otherwise false.
1933    pub fn can_continue(&self, marker: u8, is_ordered: bool) -> bool {
1934        marker == self.marker && is_ordered == self.is_ordered()
1935    }
1936
1937    /// Returns the list marker character like '-', '+', ')' and '.'..
1938    #[inline(always)]
1939    pub fn marker(&self) -> u8 {
1940        self.marker
1941    }
1942
1943    // Returns a true if this list is a 'tight' list.
1944    // See <https://spec.commonmark.org/0.30/#loose> for details.
1945    #[inline(always)]
1946    pub fn is_tight(&self) -> bool {
1947        self.is_tight
1948    }
1949
1950    /// Sets whether the list is tight.
1951    #[inline(always)]
1952    pub fn set_tight(&mut self, tight: bool) {
1953        self.is_tight = tight;
1954    }
1955
1956    /// Returns  an initial number of this ordered list.
1957    /// If this list is not an ordered list, start is 0.
1958    #[inline(always)]
1959    pub fn start(&self) -> u32 {
1960        self.start
1961    }
1962
1963    /// Sets the initial number of this ordered list.
1964    #[inline(always)]
1965    pub fn set_start(&mut self, start: u32) {
1966        self.start = start;
1967    }
1968}
1969
1970impl NodeKind for List {
1971    fn typ(&self) -> NodeType {
1972        NodeType::ContainerBlock
1973    }
1974
1975    fn kind_name(&self) -> &'static str {
1976        "List"
1977    }
1978}
1979
1980impl PrettyPrint for List {
1981    fn pretty_print(&self, w: &mut dyn Write, _source: &str, level: usize) -> fmt::Result {
1982        writeln!(w, "{}Marker: '{}'", pp_indent(level), self.marker() as char)?;
1983        writeln!(w, "{}IsTight: {}", pp_indent(level), self.is_tight())?;
1984        writeln!(w, "{}Start: {}", pp_indent(level), self.start())
1985    }
1986}
1987
1988impl From<List> for KindData {
1989    fn from(data: List) -> Self {
1990        KindData::List(data)
1991    }
1992}
1993
1994//   }}} List
1995
1996//   ListItem {{{
1997
1998/// Task status for list items.
1999#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2000#[non_exhaustive]
2001pub enum Task {
2002    Unchecked,
2003    Checked,
2004}
2005
2006impl Display for Task {
2007    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2008        match self {
2009            Task::Unchecked => write!(f, "Unchecked"),
2010            Task::Checked => write!(f, "Checked"),
2011        }
2012    }
2013}
2014
2015/// Represents a list item node.
2016#[derive(Debug, Default)]
2017pub struct ListItem {
2018    offset: usize,
2019    task: Option<Task>,
2020}
2021
2022impl ListItem {
2023    /// Creates a new [`ListItem`] node.
2024    pub fn new() -> Self {
2025        Self::default()
2026    }
2027
2028    /// Creates a new [`ListItem`] with the given offset.
2029    pub(crate) fn with_offset(offset: usize) -> Self {
2030        Self { offset, task: None }
2031    }
2032
2033    /// Returns an offset position of this item.
2034    #[inline(always)]
2035    pub(crate) fn offset(&self) -> usize {
2036        self.offset
2037    }
2038
2039    /// Returns true if this item is a task.
2040    #[inline(always)]
2041    pub fn is_task(&self) -> bool {
2042        self.task.is_some()
2043    }
2044
2045    /// Returns a task of this item.
2046    #[inline(always)]
2047    pub fn task(&self) -> Option<Task> {
2048        self.task
2049    }
2050
2051    /// Sets a task of this item.
2052    #[inline(always)]
2053    pub fn set_task(&mut self, task: Option<Task>) {
2054        self.task = task;
2055    }
2056}
2057
2058impl NodeKind for ListItem {
2059    fn typ(&self) -> NodeType {
2060        NodeType::ContainerBlock
2061    }
2062
2063    fn kind_name(&self) -> &'static str {
2064        "ListItem"
2065    }
2066}
2067
2068impl PrettyPrint for ListItem {
2069    fn pretty_print(&self, w: &mut dyn Write, _source: &str, level: usize) -> fmt::Result {
2070        if self.offset() > 0 {
2071            writeln!(w, "{}Offset: {}", pp_indent(level), self.offset())?;
2072        }
2073        if self.is_task() {
2074            writeln!(w, "{}Task: {}", pp_indent(level), self.task().unwrap())
2075        } else {
2076            Ok(())
2077        }
2078    }
2079}
2080
2081impl From<ListItem> for KindData {
2082    fn from(data: ListItem) -> Self {
2083        KindData::ListItem(data)
2084    }
2085}
2086
2087//   }}} ListItem
2088
2089//   HtmlBlock {{{
2090
2091/// HTMLBlockKind represents kinds of an html blocks.
2092/// See <https://spec.commonmark.org/0.30/#html-blocks>
2093#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2094#[non_exhaustive]
2095pub enum HtmlBlockKind {
2096    Kind1,
2097    Kind2,
2098    Kind3,
2099    Kind4,
2100    Kind5,
2101    Kind6,
2102    Kind7,
2103}
2104
2105impl Display for HtmlBlockKind {
2106    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2107        match self {
2108            HtmlBlockKind::Kind1 => write!(f, "Kind1"),
2109            HtmlBlockKind::Kind2 => write!(f, "Kind2"),
2110            HtmlBlockKind::Kind3 => write!(f, "Kind3"),
2111            HtmlBlockKind::Kind4 => write!(f, "Kind4"),
2112            HtmlBlockKind::Kind5 => write!(f, "Kind5"),
2113            HtmlBlockKind::Kind6 => write!(f, "Kind6"),
2114            HtmlBlockKind::Kind7 => write!(f, "Kind7"),
2115        }
2116    }
2117}
2118
2119/// Represents an HTML block node.
2120#[derive(Debug)]
2121pub struct HtmlBlock {
2122    html_block_kind: HtmlBlockKind,
2123    value: text::Lines,
2124}
2125
2126impl HtmlBlock {
2127    /// Creates a new [`HtmlBlock`] with the given type.
2128    pub fn new(typ: HtmlBlockKind) -> Self {
2129        Self {
2130            html_block_kind: typ,
2131            value: text::Lines::default(),
2132        }
2133    }
2134
2135    /// Returns the value of the html block.
2136    #[inline(always)]
2137    pub fn value(&self) -> &text::Lines {
2138        &self.value
2139    }
2140
2141    /// Sets the value of the html block.
2142    #[inline(always)]
2143    pub fn set_value(&mut self, value: impl Into<text::Lines>) {
2144        self.value = value.into();
2145    }
2146
2147    /// Returns an html block kind of this item.
2148    #[inline(always)]
2149    pub fn html_block_kind(&self) -> HtmlBlockKind {
2150        self.html_block_kind
2151    }
2152}
2153
2154impl NodeKind for HtmlBlock {
2155    fn typ(&self) -> NodeType {
2156        NodeType::LeafBlock
2157    }
2158
2159    fn kind_name(&self) -> &'static str {
2160        "HtmlBlock"
2161    }
2162}
2163
2164impl PrettyPrint for HtmlBlock {
2165    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
2166        writeln!(
2167            w,
2168            "{}HtmlBlockKind: {}",
2169            pp_indent(level),
2170            self.html_block_kind()
2171        )?;
2172        write!(w, "{}Value: ", pp_indent(level))?;
2173        writeln!(w, "[ ")?;
2174        for line in self.value.iter(source) {
2175            write!(w, "{}{}", pp_indent(level + 1), line)?;
2176        }
2177        writeln!(w)?;
2178        writeln!(w, "{}]", pp_indent(level))
2179    }
2180}
2181
2182impl From<HtmlBlock> for KindData {
2183    fn from(data: HtmlBlock) -> Self {
2184        KindData::HtmlBlock(data)
2185    }
2186}
2187
2188//   }}} HtmlBlock
2189
2190//   LinkReferenceDefinition {{{
2191
2192/// Represents a link reference definition node.
2193#[derive(Debug)]
2194pub struct LinkReferenceDefinition {
2195    label: text::MultilineValue,
2196    destination: text::Value,
2197    title: Option<text::MultilineValue>,
2198}
2199
2200impl LinkReferenceDefinition {
2201    /// Creates a new [`LinkReferenceDefinition`] node.
2202    pub fn new(
2203        label: impl Into<text::MultilineValue>,
2204        destination: impl Into<text::Value>,
2205    ) -> Self {
2206        Self {
2207            label: label.into(),
2208            destination: destination.into(),
2209            title: None,
2210        }
2211    }
2212
2213    /// Creates a new [`LinkReferenceDefinition`] node with a title.
2214    pub fn with_title(
2215        label: impl Into<text::MultilineValue>,
2216        destination: impl Into<text::Value>,
2217        title: impl Into<text::MultilineValue>,
2218    ) -> Self {
2219        Self {
2220            label: label.into(),
2221            destination: destination.into(),
2222            title: Some(title.into()),
2223        }
2224    }
2225
2226    /// Returns the label of the link reference definition.
2227    #[inline(always)]
2228    pub fn label(&self) -> &text::MultilineValue {
2229        &self.label
2230    }
2231
2232    /// Returns the string representation of the label of the link reference definition.
2233    #[inline(always)]
2234    pub fn label_str<'a>(&'a self, source: &'a str) -> Cow<'a, str> {
2235        self.label.str(source)
2236    }
2237
2238    /// Returns the destination of the link reference definition.
2239    #[inline(always)]
2240    pub fn destination(&self) -> &text::Value {
2241        &self.destination
2242    }
2243
2244    /// Returns the string representation of the destination of the link reference definition.
2245    #[inline(always)]
2246    pub fn destination_str<'a>(&'a self, source: &'a str) -> &'a str {
2247        self.destination.str(source)
2248    }
2249
2250    /// Returns the title of the link reference definition.
2251    #[inline(always)]
2252    pub fn title(&self) -> Option<&text::MultilineValue> {
2253        self.title.as_ref()
2254    }
2255
2256    /// Returns the string representation of the title of the link reference definition.
2257    #[inline(always)]
2258    pub fn title_str<'a>(&'a self, source: &'a str) -> Option<Cow<'a, str>> {
2259        self.title.as_ref().map(|t| t.str(source))
2260    }
2261}
2262
2263impl NodeKind for LinkReferenceDefinition {
2264    fn typ(&self) -> NodeType {
2265        NodeType::LeafBlock
2266    }
2267
2268    fn kind_name(&self) -> &'static str {
2269        "LinkReferenceDefinition"
2270    }
2271}
2272
2273impl PrettyPrint for LinkReferenceDefinition {
2274    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
2275        writeln!(w, "{}Label: {}", pp_indent(level), self.label.str(source))?;
2276        writeln!(
2277            w,
2278            "{}Destination: {}",
2279            pp_indent(level),
2280            self.destination.str(source)
2281        )?;
2282        writeln!(
2283            w,
2284            "{}Title: {}",
2285            pp_indent(level),
2286            self.title_str(source).as_deref().unwrap_or("<None>")
2287        )
2288    }
2289}
2290
2291impl From<LinkReferenceDefinition> for KindData {
2292    fn from(data: LinkReferenceDefinition) -> Self {
2293        KindData::LinkReferenceDefinition(data)
2294    }
2295}
2296
2297//   }}} LinkReferenceDefinition
2298
2299// GFM {{{
2300//   Table {{{
2301
2302/// Alignment of table cells.
2303#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2304#[non_exhaustive]
2305pub enum TableCellAlignment {
2306    Left,
2307    Center,
2308    Right,
2309    None,
2310}
2311
2312impl TableCellAlignment {
2313    /// Returns the string representation of the alignment.
2314    pub fn as_str(&self) -> &'static str {
2315        match self {
2316            TableCellAlignment::Left => "left",
2317            TableCellAlignment::Center => "center",
2318            TableCellAlignment::Right => "right",
2319            TableCellAlignment::None => "none",
2320        }
2321    }
2322}
2323
2324/// Represents a table node.
2325#[derive(Debug, Default)]
2326pub struct Table {}
2327
2328impl Table {
2329    /// Creates a new [`Table`] node.
2330    pub fn new() -> Self {
2331        Self {}
2332    }
2333}
2334
2335impl NodeKind for Table {
2336    fn typ(&self) -> NodeType {
2337        NodeType::ContainerBlock
2338    }
2339
2340    fn kind_name(&self) -> &'static str {
2341        "Table"
2342    }
2343}
2344
2345impl PrettyPrint for Table {
2346    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2347        Ok(())
2348    }
2349}
2350
2351impl From<Table> for KindData {
2352    fn from(e: Table) -> Self {
2353        KindData::Table(e)
2354    }
2355}
2356
2357/// Represents a table row node.
2358#[derive(Debug, Default)]
2359pub struct TableRow {}
2360
2361impl TableRow {
2362    /// Creates a new [`TableRow`] node.
2363    pub fn new() -> Self {
2364        Self {}
2365    }
2366}
2367
2368impl NodeKind for TableRow {
2369    fn typ(&self) -> NodeType {
2370        NodeType::ContainerBlock
2371    }
2372
2373    fn kind_name(&self) -> &'static str {
2374        "TableRow"
2375    }
2376}
2377
2378impl PrettyPrint for TableRow {
2379    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2380        Ok(())
2381    }
2382}
2383
2384impl From<TableRow> for KindData {
2385    fn from(e: TableRow) -> Self {
2386        KindData::TableRow(e)
2387    }
2388}
2389
2390/// Represents a table header node.
2391#[derive(Debug, Default)]
2392pub struct TableHeader {}
2393
2394impl TableHeader {
2395    /// Creates a new [`TableHeader`] node.
2396    pub fn new() -> Self {
2397        Self {}
2398    }
2399}
2400
2401impl NodeKind for TableHeader {
2402    fn typ(&self) -> NodeType {
2403        NodeType::ContainerBlock
2404    }
2405
2406    fn kind_name(&self) -> &'static str {
2407        "TableHeader"
2408    }
2409}
2410
2411impl PrettyPrint for TableHeader {
2412    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2413        Ok(())
2414    }
2415}
2416
2417impl From<TableHeader> for KindData {
2418    fn from(e: TableHeader) -> Self {
2419        KindData::TableHeader(e)
2420    }
2421}
2422
2423/// Represents a table body node.
2424#[derive(Debug, Default)]
2425pub struct TableBody {}
2426
2427impl TableBody {
2428    /// Creates a new [`TableBody`] node.
2429    pub fn new() -> Self {
2430        Self {}
2431    }
2432}
2433
2434impl NodeKind for TableBody {
2435    fn typ(&self) -> NodeType {
2436        NodeType::ContainerBlock
2437    }
2438
2439    fn kind_name(&self) -> &'static str {
2440        "TableBody"
2441    }
2442}
2443
2444impl PrettyPrint for TableBody {
2445    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2446        Ok(())
2447    }
2448}
2449
2450impl From<TableBody> for KindData {
2451    fn from(e: TableBody) -> Self {
2452        KindData::TableBody(e)
2453    }
2454}
2455
2456/// Represents a table cell node.
2457#[derive(Debug)]
2458pub struct TableCell {
2459    alignment: TableCellAlignment,
2460}
2461
2462impl Default for TableCell {
2463    fn default() -> Self {
2464        Self {
2465            alignment: TableCellAlignment::None,
2466        }
2467    }
2468}
2469
2470impl TableCell {
2471    /// Creates a new [`TableCell`] node with no alignment.
2472    pub fn new() -> Self {
2473        Self::default()
2474    }
2475
2476    /// Creates a new [`TableCell`] with the given alignment.
2477    pub fn with_alignment(alignment: TableCellAlignment) -> Self {
2478        Self { alignment }
2479    }
2480
2481    /// Returns the alignment of the table cell.
2482    #[inline(always)]
2483    pub fn alignment(&self) -> TableCellAlignment {
2484        self.alignment
2485    }
2486}
2487
2488impl NodeKind for TableCell {
2489    fn typ(&self) -> NodeType {
2490        NodeType::ContainerBlock
2491    }
2492
2493    fn kind_name(&self) -> &'static str {
2494        "TableCell"
2495    }
2496}
2497
2498impl PrettyPrint for TableCell {
2499    fn pretty_print(&self, w: &mut dyn Write, _source: &str, level: usize) -> fmt::Result {
2500        writeln!(w, "{}Alignment: {:?}", pp_indent(level), self.alignment,)
2501    }
2502}
2503
2504impl From<TableCell> for KindData {
2505    fn from(e: TableCell) -> Self {
2506        KindData::TableCell(e)
2507    }
2508}
2509
2510//   }}} Table
2511// }}} GFM
2512
2513// }}} Blocks
2514
2515// Inlines {{{
2516
2517//   Text {{{
2518
2519bitflags! {
2520    /// Qualifiers for textual nodes.
2521    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
2522    pub struct TextQualifier: u16 {
2523        /// Indicates given text has soft line break at the end.
2524        const SOFT_LINE_BREAK = 1 << 0;
2525
2526        /// Indicates given text has hard line break at the end.
2527        const HARD_LINE_BREAK = 1 << 1;
2528
2529        /// Indicates given text is temporary and might be removed
2530        /// later during processing.
2531        const TEMP = 1 << 2;
2532    }
2533}
2534
2535/// Represents a text node in the document.
2536#[derive(Debug)]
2537pub struct Text {
2538    value: text::Value,
2539
2540    qualifiers: TextQualifier,
2541}
2542
2543impl Text {
2544    /// Creates a new [`Text`] node with the given textual content.
2545    pub fn new(textual: impl Into<text::Value>) -> Self {
2546        let qualifiers = TextQualifier::default();
2547        Self {
2548            value: textual.into(),
2549            qualifiers,
2550        }
2551    }
2552
2553    /// Creates a new [`Text`] node with the given textual content and qualifiers.
2554    pub fn with_qualifiers(textual: impl Into<text::Value>, qualifiers: TextQualifier) -> Self {
2555        Self {
2556            value: textual.into(),
2557            qualifiers,
2558        }
2559    }
2560
2561    /// Returns the index of the textual content of this text, if it is an index.
2562    #[inline(always)]
2563    pub fn index(&self) -> Option<&text::Index> {
2564        match &self.value {
2565            text::Value::Index(idx) => Some(idx),
2566            _ => None,
2567        }
2568    }
2569
2570    /// Sets the textual content of this text.
2571    #[inline(always)]
2572    pub fn set(&mut self, value: impl Into<text::Value>) {
2573        self.value = value.into();
2574    }
2575
2576    /// Adds the qualifiers to this text.
2577    pub fn add_qualifiers(&mut self, qualifiers: TextQualifier) {
2578        self.qualifiers |= qualifiers;
2579    }
2580
2581    /// Returns true if this text has given qualifiers.
2582    pub fn has_qualifiers(&self, qualifiers: TextQualifier) -> bool {
2583        self.qualifiers.contains(qualifiers)
2584    }
2585
2586    /// Returns the bytes of this text.
2587    pub fn bytes<'a>(&'a self, source: &'a str) -> &'a [u8] {
2588        self.value.bytes(source)
2589    }
2590
2591    /// Returns the UTF-8 string  of this text.
2592    pub fn str<'a>(&'a self, source: &'a str) -> &'a str {
2593        self.value.str(source)
2594    }
2595}
2596
2597impl NodeKind for Text {
2598    fn typ(&self) -> NodeType {
2599        NodeType::Inline
2600    }
2601
2602    fn kind_name(&self) -> &'static str {
2603        "Text"
2604    }
2605}
2606
2607impl PrettyPrint for Text {
2608    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
2609        writeln!(w, "{}Qualifiers: {:?}", pp_indent(level), self.qualifiers)?;
2610        writeln!(w, "{}Content: '{}'", pp_indent(level), self.str(source))
2611    }
2612}
2613
2614impl From<Text> for KindData {
2615    fn from(data: Text) -> Self {
2616        KindData::Text(data)
2617    }
2618}
2619
2620//   }}} Text
2621
2622//   CodeSpan {{{
2623
2624#[derive(Debug)]
2625enum CodeSpanValue {
2626    Indices(TinyVec<text::Index>),
2627    String(String),
2628}
2629
2630/// Represents an inline code span in the document.
2631#[derive(Debug)]
2632pub struct CodeSpan {
2633    value: CodeSpanValue,
2634}
2635
2636impl CodeSpan {
2637    /// Creates a new empty [`CodeSpan`] node.
2638    pub fn empty() -> Self {
2639        Self {
2640            value: CodeSpanValue::Indices(TinyVec::empty()),
2641        }
2642    }
2643
2644    /// Creates a new [`CodeSpan`] node from the given indices.
2645    pub fn from_indices(indices: impl Into<TinyVec<text::Index>>) -> Self {
2646        Self {
2647            value: CodeSpanValue::Indices(indices.into()),
2648        }
2649    }
2650
2651    /// Creates a new [`CodeSpan`] node from the given string.
2652    pub fn from_string(value: impl Into<String>) -> Self {
2653        Self {
2654            value: CodeSpanValue::String(value.into()),
2655        }
2656    }
2657
2658    pub(crate) fn indices(&self) -> Option<&[text::Index]> {
2659        match &self.value {
2660            CodeSpanValue::Indices(indices) => Some(indices.as_slice()),
2661            _ => None,
2662        }
2663    }
2664
2665    /// Returns the string representation of the code span value of this code span.
2666    /// If the value contains a newline character, it will be replaced with a space character.
2667    pub fn value_str<'a>(&'a self, source: &'a str) -> Cow<'a, str> {
2668        match &self.value {
2669            CodeSpanValue::Indices(indices) => {
2670                if indices.is_empty() {
2671                    Cow::Borrowed("")
2672                } else if indices.len() == 1 {
2673                    let idx = indices[0];
2674                    if source.as_bytes()[idx.stop() - 1] != b'\n' {
2675                        Cow::Borrowed(idx.str(source))
2676                    } else {
2677                        let idx: text::Index = (idx.start(), idx.stop() - 1).into();
2678                        let s = idx.str(source);
2679                        let mut st = String::with_capacity(s.len() + 1);
2680                        st.push_str(s);
2681                        st.push(' ');
2682                        Cow::Owned(st)
2683                    }
2684                } else {
2685                    let mut s = String::new();
2686                    for idx in indices.iter() {
2687                        s.push_str(idx.str(source));
2688                    }
2689                    Cow::Owned(s.replace('\n', " "))
2690                }
2691            }
2692            CodeSpanValue::String(s) => {
2693                if memchr::memchr(b'\n', s.as_bytes()).is_some() {
2694                    Cow::Owned(s.replace('\n', " "))
2695                } else {
2696                    Cow::Borrowed(s)
2697                }
2698            }
2699        }
2700    }
2701}
2702
2703impl NodeKind for CodeSpan {
2704    fn typ(&self) -> NodeType {
2705        NodeType::Inline
2706    }
2707
2708    fn kind_name(&self) -> &'static str {
2709        "CodeSpan"
2710    }
2711}
2712
2713impl PrettyPrint for CodeSpan {
2714    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2715        Ok(())
2716    }
2717}
2718
2719impl From<CodeSpan> for KindData {
2720    fn from(data: CodeSpan) -> Self {
2721        KindData::CodeSpan(data)
2722    }
2723}
2724
2725//   }}} CodeSpan
2726
2727//   Emphasis {{{
2728
2729/// Represents an emphasis node in the document.
2730#[derive(Debug)]
2731pub struct Emphasis {
2732    level: u8,
2733}
2734
2735impl Emphasis {
2736    /// Creates a new Emphasis.
2737    pub fn new(level: u8) -> Self {
2738        Self { level }
2739    }
2740
2741    /// Returns the level of emphasis.
2742    #[inline(always)]
2743    pub fn level(&self) -> u8 {
2744        self.level
2745    }
2746}
2747
2748impl NodeKind for Emphasis {
2749    fn typ(&self) -> NodeType {
2750        NodeType::Inline
2751    }
2752
2753    fn kind_name(&self) -> &'static str {
2754        "Emphasis"
2755    }
2756}
2757
2758impl PrettyPrint for Emphasis {
2759    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
2760        Ok(())
2761    }
2762}
2763
2764impl From<Emphasis> for KindData {
2765    fn from(data: Emphasis) -> Self {
2766        KindData::Emphasis(data)
2767    }
2768}
2769
2770//   }}} Emphasis
2771
2772//   Link {{{
2773
2774/// Kinds of links.
2775#[derive(Debug)]
2776#[non_exhaustive]
2777pub enum LinkKind {
2778    Inline,
2779    Reference(LinkReference),
2780    Auto(AutoLink),
2781}
2782
2783/// Kinds of link references.
2784#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2785#[non_exhaustive]
2786pub enum LinkReferenceKind {
2787    Full,
2788    Collapsed,
2789    Shortcut,
2790}
2791
2792/// Represents a link reference in the document.
2793#[derive(Debug)]
2794pub struct LinkReference {
2795    value: text::MultilineValue,
2796    link_reference_kind: LinkReferenceKind,
2797}
2798
2799impl LinkReference {
2800    /// Returns the string representation of the reference value of this link reference.
2801    #[inline(always)]
2802    pub fn value_str<'a>(&'a self, source: &'a str) -> Cow<'a, str> {
2803        self.value.str(source)
2804    }
2805
2806    /// Returns the reference value of this link reference.
2807    #[inline(always)]
2808    pub fn value(&self) -> &text::MultilineValue {
2809        &self.value
2810    }
2811
2812    /// Returns the kind of this link reference.
2813    #[inline(always)]
2814    pub fn link_reference_kind(&self) -> LinkReferenceKind {
2815        self.link_reference_kind
2816    }
2817}
2818
2819/// Represents an auto link in the document.
2820#[derive(Debug)]
2821pub struct AutoLink {
2822    text: text::Value,
2823}
2824
2825impl AutoLink {
2826    /// Returns the string representation of the auto link text of this auto link.
2827    #[inline(always)]
2828    pub fn text_str<'a>(&'a self, source: &'a str) -> &'a str {
2829        self.text.str(source)
2830    }
2831
2832    /// Returns the auto link text of this auto link.
2833    #[inline(always)]
2834    pub fn text(&self) -> &text::Value {
2835        &self.text
2836    }
2837}
2838
2839/// Represents a link in the document.
2840#[derive(Debug)]
2841pub struct Link {
2842    destination: text::Value,
2843
2844    title: Option<text::MultilineValue>,
2845
2846    link_kind: LinkKind,
2847}
2848
2849impl Link {
2850    /// Creates a new inline link with the given destination.
2851    pub fn inline(destination: impl Into<text::Value>) -> Self {
2852        Self {
2853            destination: destination.into(),
2854            title: None,
2855            link_kind: LinkKind::Inline,
2856        }
2857    }
2858
2859    /// Creates a new inline link with the given destination and title.
2860    pub fn inline_with_title(
2861        destination: impl Into<text::Value>,
2862        title: impl Into<text::MultilineValue>,
2863    ) -> Self {
2864        Self {
2865            destination: destination.into(),
2866            title: Some(title.into()),
2867            link_kind: LinkKind::Inline,
2868        }
2869    }
2870
2871    /// Creates a new reference link with the given destination and reference value.
2872    pub fn reference(
2873        destination: impl Into<text::Value>,
2874        value: impl Into<text::MultilineValue>,
2875        reference_kind: LinkReferenceKind,
2876    ) -> Self {
2877        Self {
2878            destination: destination.into(),
2879            title: None,
2880            link_kind: LinkKind::Reference(LinkReference {
2881                value: value.into(),
2882                link_reference_kind: reference_kind,
2883            }),
2884        }
2885    }
2886
2887    /// Creates a new reference link with the given destination, reference value and title.
2888    pub fn reference_with_title(
2889        destination: impl Into<text::Value>,
2890        value: impl Into<text::MultilineValue>,
2891        reference_kind: LinkReferenceKind,
2892        title: impl Into<text::MultilineValue>,
2893    ) -> Self {
2894        Self {
2895            destination: destination.into(),
2896            title: Some(title.into()),
2897            link_kind: LinkKind::Reference(LinkReference {
2898                value: value.into(),
2899                link_reference_kind: reference_kind,
2900            }),
2901        }
2902    }
2903
2904    /// Creates a new auto link with the given destination and auto link text.
2905    pub fn auto(destination: impl Into<text::Value>, text: impl Into<text::Value>) -> Self {
2906        Self {
2907            destination: destination.into(),
2908            title: None,
2909            link_kind: LinkKind::Auto(AutoLink { text: text.into() }),
2910        }
2911    }
2912
2913    /// Returns the destination of the link.
2914    #[inline(always)]
2915    pub fn destination(&self) -> &text::Value {
2916        &self.destination
2917    }
2918
2919    /// Returns the string representation of the destination of the link.
2920    #[inline(always)]
2921    pub fn destination_str<'a>(&'a self, source: &'a str) -> &'a str {
2922        self.destination.str(source)
2923    }
2924
2925    /// Returns the title of the link, if it exists.
2926    #[inline(always)]
2927    pub fn title(&self) -> Option<&text::MultilineValue> {
2928        self.title.as_ref()
2929    }
2930
2931    /// Returns the string representation of the title of the link, if it exists.
2932    #[inline(always)]
2933    pub fn title_str<'a>(&'a self, source: &'a str) -> Option<Cow<'a, str>> {
2934        self.title.as_ref().map(|t| t.str(source))
2935    }
2936
2937    /// Returns the kind of this link.
2938    #[inline(always)]
2939    pub fn link_kind(&self) -> &LinkKind {
2940        &self.link_kind
2941    }
2942}
2943
2944impl NodeKind for Link {
2945    fn typ(&self) -> NodeType {
2946        NodeType::Inline
2947    }
2948
2949    fn kind_name(&self) -> &'static str {
2950        "Link"
2951    }
2952}
2953
2954impl PrettyPrint for Link {
2955    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
2956        match self.link_kind() {
2957            LinkKind::Inline => writeln!(w, "{}LinkKind: Inline", pp_indent(level))?,
2958            LinkKind::Reference(reference) => {
2959                writeln!(w, "{}LinkKind: Reference", pp_indent(level))?;
2960                writeln!(
2961                    w,
2962                    "{}ReferenceLabel: {}",
2963                    pp_indent(level),
2964                    reference.value.str(source)
2965                )?;
2966                writeln!(
2967                    w,
2968                    "{}ReferenceKind: {:?}",
2969                    pp_indent(level),
2970                    reference.link_reference_kind
2971                )?;
2972            }
2973            LinkKind::Auto(auto) => {
2974                writeln!(w, "{}LinkKind: Auto", pp_indent(level))?;
2975                writeln!(
2976                    w,
2977                    "{}AutoLinkText: {}",
2978                    pp_indent(level),
2979                    auto.text.str(source)
2980                )?;
2981            }
2982        }
2983        writeln!(
2984            w,
2985            "{}Destination: {}",
2986            pp_indent(level),
2987            self.destination.str(source)
2988        )?;
2989        if let Some(title) = &self.title {
2990            writeln!(w, "{}Title: {}", pp_indent(level), title.str(source))?;
2991        }
2992        Ok(())
2993    }
2994}
2995
2996impl From<Link> for KindData {
2997    fn from(data: Link) -> Self {
2998        KindData::Link(data)
2999    }
3000}
3001
3002//   }}} Link
3003
3004//   Image {{{
3005
3006/// Represents an image in the document.
3007#[derive(Debug)]
3008pub struct Image {
3009    destination: text::Value,
3010
3011    title: Option<text::MultilineValue>,
3012
3013    link_kind: LinkKind,
3014}
3015
3016impl Image {
3017    pub(crate) fn from_link(link: Link) -> Self {
3018        Self {
3019            destination: link.destination,
3020            title: link.title,
3021            link_kind: link.link_kind,
3022        }
3023    }
3024
3025    /// Creates a new inline image with the given destination.
3026    pub fn inline(destination: impl Into<text::Value>) -> Self {
3027        Self {
3028            destination: destination.into(),
3029            title: None,
3030            link_kind: LinkKind::Inline,
3031        }
3032    }
3033
3034    /// Creates a new inline image with the given destination and title.
3035    pub fn inline_with_title(
3036        destination: impl Into<text::Value>,
3037        title: impl Into<text::MultilineValue>,
3038    ) -> Self {
3039        Self {
3040            destination: destination.into(),
3041            title: Some(title.into()),
3042            link_kind: LinkKind::Inline,
3043        }
3044    }
3045
3046    /// Creates a new reference image with the given destination and reference value.
3047    pub fn reference(
3048        destination: impl Into<text::Value>,
3049        value: impl Into<text::MultilineValue>,
3050        reference_kind: LinkReferenceKind,
3051    ) -> Self {
3052        Self {
3053            destination: destination.into(),
3054            title: None,
3055            link_kind: LinkKind::Reference(LinkReference {
3056                value: value.into(),
3057                link_reference_kind: reference_kind,
3058            }),
3059        }
3060    }
3061
3062    /// Creates a new reference image with the given destination, reference value and title.
3063    pub fn reference_with_title(
3064        destination: impl Into<text::Value>,
3065        value: impl Into<text::MultilineValue>,
3066        reference_kind: LinkReferenceKind,
3067        title: impl Into<text::MultilineValue>,
3068    ) -> Self {
3069        Self {
3070            destination: destination.into(),
3071            title: Some(title.into()),
3072            link_kind: LinkKind::Reference(LinkReference {
3073                value: value.into(),
3074                link_reference_kind: reference_kind,
3075            }),
3076        }
3077    }
3078
3079    /// Returns the destination of the link.
3080    #[inline(always)]
3081    pub fn destination(&self) -> &text::Value {
3082        &self.destination
3083    }
3084
3085    /// Returns the string representation of the destination of the link.
3086    #[inline(always)]
3087    pub fn destination_str<'a>(&'a self, source: &'a str) -> &'a str {
3088        self.destination.str(source)
3089    }
3090
3091    /// Returns the title of the link, if it exists.
3092    #[inline(always)]
3093    pub fn title(&self) -> Option<&text::MultilineValue> {
3094        self.title.as_ref()
3095    }
3096
3097    /// Returns the string representation of the title of the link, if it exists.
3098    #[inline(always)]
3099    pub fn title_str<'a>(&'a self, source: &'a str) -> Option<Cow<'a, str>> {
3100        self.title.as_ref().map(|t| t.str(source))
3101    }
3102
3103    /// Returns the link kind of this image.
3104    #[inline(always)]
3105    pub fn link_kind(&self) -> &LinkKind {
3106        &self.link_kind
3107    }
3108}
3109
3110impl NodeKind for Image {
3111    fn typ(&self) -> NodeType {
3112        NodeType::Inline
3113    }
3114
3115    fn kind_name(&self) -> &'static str {
3116        "Image"
3117    }
3118}
3119
3120impl PrettyPrint for Image {
3121    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
3122        writeln!(
3123            w,
3124            "{}Destination: {}",
3125            pp_indent(level),
3126            self.destination.str(source)
3127        )?;
3128        if let Some(title) = &self.title {
3129            writeln!(w, "{}Title: {}", pp_indent(level), title.str(source))?;
3130        }
3131        Ok(())
3132    }
3133}
3134
3135impl From<Image> for KindData {
3136    fn from(data: Image) -> Self {
3137        KindData::Image(data)
3138    }
3139}
3140
3141//   }}} Image
3142
3143//   RawHtml {{{
3144
3145/// Represents an inline raw HTML node.
3146#[derive(Debug)]
3147pub struct RawHtml {
3148    value: text::MultilineValue,
3149}
3150
3151impl RawHtml {
3152    /// Creates a new RawHtml
3153    pub fn new(value: text::MultilineValue) -> Self {
3154        Self { value }
3155    }
3156
3157    /// Returns the value of this raw HTML.
3158    #[inline(always)]
3159    pub fn value(&self) -> &text::MultilineValue {
3160        &self.value
3161    }
3162
3163    /// Returns the string representation of this raw HTML.
3164    pub fn str<'a>(&'a self, source: &'a str) -> Cow<'a, str> {
3165        self.value.str(source)
3166    }
3167
3168    /// Returns the bytes of this raw HTML.
3169    pub fn bytes<'a>(&'a self, source: &'a str) -> Cow<'a, [u8]> {
3170        self.value.bytes(source)
3171    }
3172}
3173
3174impl NodeKind for RawHtml {
3175    fn typ(&self) -> NodeType {
3176        NodeType::Inline
3177    }
3178
3179    fn kind_name(&self) -> &'static str {
3180        "RawHtml"
3181    }
3182}
3183
3184impl PrettyPrint for RawHtml {
3185    fn pretty_print(&self, w: &mut dyn Write, source: &str, level: usize) -> fmt::Result {
3186        writeln!(w, "{}Value: {}", pp_indent(level), self.str(source))?;
3187        Ok(())
3188    }
3189}
3190
3191impl From<RawHtml> for KindData {
3192    fn from(data: RawHtml) -> Self {
3193        KindData::RawHtml(data)
3194    }
3195}
3196
3197//   }}} RawHtml
3198
3199// GFM {{{
3200
3201/// Represents a strikethrough node.
3202#[derive(Debug, Default)]
3203pub struct Strikethrough {}
3204
3205impl Strikethrough {
3206    /// Creates a new Strikethrough node.
3207    pub fn new() -> Self {
3208        Self {}
3209    }
3210}
3211
3212impl NodeKind for Strikethrough {
3213    fn typ(&self) -> NodeType {
3214        NodeType::Inline
3215    }
3216
3217    fn kind_name(&self) -> &'static str {
3218        "Strikethrough"
3219    }
3220}
3221
3222impl PrettyPrint for Strikethrough {
3223    fn pretty_print(&self, _w: &mut dyn Write, _source: &str, _level: usize) -> fmt::Result {
3224        Ok(())
3225    }
3226}
3227
3228impl From<Strikethrough> for KindData {
3229    fn from(e: Strikethrough) -> Self {
3230        KindData::Strikethrough(e)
3231    }
3232}
3233// }}} GFM
3234
3235// }}} Inlines
3236
3237// ExtensionData {{{
3238
3239/// A composite trait for nodes will be added from outside of this library.
3240pub trait ExtensionData: Debug + PrettyPrint + NodeKind + Any {
3241    fn as_any(&self) -> &dyn Any;
3242}
3243
3244impl<T: PrettyPrint + NodeKind + Debug + Any> ExtensionData for T {
3245    fn as_any(&self) -> &dyn Any {
3246        self
3247    }
3248}
3249// }}}