element.rs (2450B)
1 //! Markdown elements - the stable output of parsing. 2 3 /// A byte range into the parser's source buffer. Zero-copy reference to content. 4 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 5 pub struct Span { 6 pub start: usize, 7 pub end: usize, 8 } 9 10 impl Span { 11 pub fn new(start: usize, end: usize) -> Self { 12 debug_assert!(start <= end); 13 Self { start, end } 14 } 15 16 pub fn resolve<'a>(&self, buffer: &'a str) -> &'a str { 17 &buffer[self.start..self.end] 18 } 19 20 pub fn is_empty(&self) -> bool { 21 self.start == self.end 22 } 23 24 pub fn len(&self) -> usize { 25 self.end - self.start 26 } 27 } 28 29 /// A complete, stable markdown element ready for rendering. 30 #[derive(Debug, Clone, PartialEq)] 31 pub enum MdElement { 32 /// Heading with level (1-6) and content 33 Heading { level: u8, content: Span }, 34 35 /// Paragraph of text (may contain inline elements) 36 Paragraph(Vec<InlineElement>), 37 38 /// Fenced code block 39 CodeBlock(CodeBlock), 40 41 /// Blockquote (contains nested elements) 42 BlockQuote(Vec<MdElement>), 43 44 /// Unordered list 45 UnorderedList(Vec<ListItem>), 46 47 /// Ordered list (starting number) 48 OrderedList { start: u32, items: Vec<ListItem> }, 49 50 /// Markdown table with headers and data rows 51 Table { 52 headers: Vec<Span>, 53 rows: Vec<Vec<Span>>, 54 }, 55 56 /// Thematic break (---, ***, ___) 57 ThematicBreak, 58 59 /// Raw text (when nothing else matches) 60 Text(Span), 61 } 62 63 /// A fenced code block with optional language. 64 #[derive(Debug, Clone, PartialEq)] 65 pub struct CodeBlock { 66 pub language: Option<Span>, 67 pub content: Span, 68 } 69 70 /// A list item (may contain nested elements). 71 #[derive(Debug, Clone, PartialEq)] 72 pub struct ListItem { 73 pub content: Vec<InlineElement>, 74 pub nested: Option<Box<MdElement>>, // Nested list 75 } 76 77 /// Inline elements within a paragraph or list item. 78 #[derive(Debug, Clone, PartialEq)] 79 pub enum InlineElement { 80 /// Plain text 81 Text(Span), 82 83 /// Styled text (bold, italic, etc.) 84 Styled { style: InlineStyle, content: Span }, 85 86 /// Inline code (`code`) 87 Code(Span), 88 89 /// Link [text](url) 90 Link { text: Span, url: Span }, 91 92 /// Image  93 Image { alt: Span, url: Span }, 94 95 /// Hard line break 96 LineBreak, 97 } 98 99 /// Inline text styles (can be combined). 100 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 101 pub enum InlineStyle { 102 Bold, 103 Italic, 104 BoldItalic, 105 Strikethrough, 106 }