#[derive(Debug, Clone)]
pub struct Document {
pub blocks: Vec<BlockNode>,
pub line_count: u32,
}
#[derive(Debug, Clone)]
pub struct BlockNode {
pub kind: BlockKind,
pub line_start: u32,
pub line_end: u32,
pub utf16_start: u32,
pub utf16_end: u32,
pub byte_start: u32,
pub byte_end: u32,
pub list_marker: Option<ListMarkerMeta>,
pub inline_spans: Vec<InlineSpan>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ListMarkerMeta {
pub indent: u32,
pub marker_utf16_start: u32,
pub marker_utf16_end: u32,
pub marker_byte_start: u32,
pub marker_byte_end: u32,
pub content_byte_start: u32,
pub marker_source: String,
pub unordered_marker: String,
pub ordered_delimiter: String,
pub ordered_raw_number: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BlockKind {
Heading {
level: u8,
text: String,
},
Paragraph {
text: String,
},
CodeBlock {
language: Option<String>,
code: String,
},
MermaidDiagram {
diagram_type: MermaidDiagramType,
source: String,
},
Blockquote {
text: String,
},
BulletList {
items: Vec<ListItem>,
},
OrderedList {
start: u32,
items: Vec<ListItem>,
},
Checkbox {
checked: bool,
text: String,
},
Table {
headers: Vec<String>,
rows: Vec<Vec<String>>,
alignments: Vec<ColumnAlignment>,
},
HorizontalRule,
Empty,
FootnoteDefinition {
label: String,
text: String,
},
ImageMarker {
uuid: String,
},
Callout {
kind: CalloutKind,
title: Option<String>,
text: String,
},
BulletItem {
text: String,
},
NumberedItem {
number: u32,
text: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum MermaidDiagramType {
Unknown = 0,
Flowchart = 1,
Graph = 2,
SequenceDiagram = 3,
ClassDiagram = 4,
StateDiagram = 5,
ErDiagram = 6,
Gantt = 7,
Mindmap = 8,
Pie = 9,
Journey = 10,
Timeline = 11,
GitGraph = 12,
C4 = 13,
RequirementDiagram = 14,
Quadrant = 15,
Sankey = 16,
XYChart = 17,
Block = 18,
Packet = 19,
Architecture = 20,
Kanban = 21,
Radar = 22,
}
impl MermaidDiagramType {
pub fn from_source(source: &str) -> Self {
let mut lines = source.lines().peekable();
loop {
match lines.peek().copied() {
Some(line) if line.trim().is_empty() => {
lines.next();
}
Some(line) if line.trim() == "---" => {
lines.next();
for l in lines.by_ref() {
if l.trim() == "---" {
break;
}
}
}
_ => break,
}
}
let first_line = lines
.find(|l| !l.trim().is_empty())
.map(str::trim)
.unwrap_or("");
let keyword = first_line.split_whitespace().next().unwrap_or("");
let k = keyword.to_ascii_lowercase();
match k.as_str() {
"flowchart" => Self::Flowchart,
"graph" => Self::Graph,
"sequencediagram" => Self::SequenceDiagram,
"classdiagram" | "classdiagram-v2" => Self::ClassDiagram,
"statediagram" | "statediagram-v2" => Self::StateDiagram,
"erdiagram" => Self::ErDiagram,
"gantt" => Self::Gantt,
"mindmap" => Self::Mindmap,
"pie" => Self::Pie,
"journey" => Self::Journey,
"timeline" => Self::Timeline,
"gitgraph" => Self::GitGraph,
"c4context" | "c4container" | "c4component" | "c4dynamic" | "c4deployment" => Self::C4,
"requirementdiagram" => Self::RequirementDiagram,
"quadrantchart" => Self::Quadrant,
"sankey" | "sankey-beta" => Self::Sankey,
"xychart" | "xychart-beta" => Self::XYChart,
"block" | "block-beta" => Self::Block,
"packet" | "packet-beta" => Self::Packet,
"architecture" | "architecture-beta" => Self::Architecture,
"kanban" => Self::Kanban,
"radar" | "radar-beta" => Self::Radar,
_ => Self::Unknown,
}
}
pub fn as_u8(self) -> u8 {
self as u8
}
}
pub fn is_mermaid_info_string(info: &str) -> bool {
info.eq_ignore_ascii_case("mermaid")
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CalloutKind {
Note = 0,
Tip = 1,
Warning = 2,
Important = 3,
Caution = 4,
}
impl CalloutKind {
pub fn from_name(s: &str) -> Option<Self> {
match s.to_ascii_lowercase().as_str() {
"note" => Some(Self::Note),
"tip" => Some(Self::Tip),
"warning" => Some(Self::Warning),
"important" => Some(Self::Important),
"caution" => Some(Self::Caution),
_ => None,
}
}
pub fn as_u8(self) -> u8 {
self as u8
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ListItem {
pub text: String,
pub inline_spans: Vec<InlineSpan>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct InlineSpan {
pub kind: InlineKind,
pub utf16_start: u32,
pub utf16_end: u32,
pub content_utf16_start: u32,
pub content_utf16_end: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub enum InlineKind {
Bold,
Italic,
BoldItalic,
Strikethrough,
UnderlineTilde,
UnderlineHtml,
InlineCode,
Highlight,
HighlightColor(u8),
HighlightHex {
hex: String,
},
Link {
url: String,
},
AutoLink {
url: String,
},
WikiLink,
FootnoteRef,
Comment,
HexColor {
hex: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColumnAlignment {
Default,
Left,
Center,
Right,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseMode {
Grouped,
Editable,
}