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