From 706eb5f52a4f06c97ecb04abe9e060d3ef60b78b Mon Sep 17 00:00:00 2001 From: Aster Date: Tue, 2 Apr 2024 18:00:23 +0800 Subject: [PATCH] Supports recursive parsing of markdown tables --- .../src/reader/{code.rs => blocks.rs} | 17 +---- projects/panduck-markdown/src/reader/html.rs | 9 --- .../panduck-markdown/src/reader/inline.rs | 15 +---- projects/panduck-markdown/src/reader/list.rs | 26 ++++---- projects/panduck-markdown/src/reader/mod.rs | 27 +++----- projects/panduck-markdown/src/reader/table.rs | 36 ++++++----- projects/panduck-markdown/src/utils/mod.rs | 62 ++++++++++++++----- 7 files changed, 92 insertions(+), 100 deletions(-) rename projects/panduck-markdown/src/reader/{code.rs => blocks.rs} (87%) diff --git a/projects/panduck-markdown/src/reader/code.rs b/projects/panduck-markdown/src/reader/blocks.rs similarity index 87% rename from projects/panduck-markdown/src/reader/code.rs rename to projects/panduck-markdown/src/reader/blocks.rs index 4453b05..8a00270 100644 --- a/projects/panduck-markdown/src/reader/code.rs +++ b/projects/panduck-markdown/src/reader/blocks.rs @@ -23,12 +23,6 @@ impl NoteBlock for Node { Node::Break(_) => { todo!() } - Node::InlineCode(_) => { - todo!() - } - Node::InlineMath(_) => { - todo!() - } Node::Delete(_) => { todo!() } @@ -59,9 +53,6 @@ impl NoteBlock for Node { Node::LinkReference(_) => { todo!() } - Node::Strong(_) => { - todo!() - } Node::Text(_) => { todo!() } @@ -75,16 +66,10 @@ impl NoteBlock for Node { Node::Heading(_) => { todo!() } - Node::ThematicBreak(_) => { todo!() } Node::Table(table) => table.note_down_block(state), - Node::TableRow(table) => table.note_down_block(state), - Node::TableCell(table) => table.note_down_block(state), - Node::ListItem(_) => { - todo!() - } Node::Definition(_) => { todo!() } @@ -100,7 +85,7 @@ impl NoteBlock for Paragraph { match x.note_down_inline(state) { Ok(o) => blocks.push(o), Err(e) => { - state.errors.push(e); + state.note_error(e); } } } diff --git a/projects/panduck-markdown/src/reader/html.rs b/projects/panduck-markdown/src/reader/html.rs index 619ebad..e69de29 100644 --- a/projects/panduck-markdown/src/reader/html.rs +++ b/projects/panduck-markdown/src/reader/html.rs @@ -1,9 +0,0 @@ -use super::*; -use comrak::nodes::NodeHtmlBlock; - -impl ToNotedown for NodeHtmlBlock { - fn into_notedown(self) -> ASTNode { - let html = String::from_utf8_lossy(&self.literal); - ASTKind::code_block(html, "html", None) - } -} diff --git a/projects/panduck-markdown/src/reader/inline.rs b/projects/panduck-markdown/src/reader/inline.rs index e58d3b8..b52b6ea 100644 --- a/projects/panduck-markdown/src/reader/inline.rs +++ b/projects/panduck-markdown/src/reader/inline.rs @@ -1,3 +1,4 @@ +use wasi_notedown::exports::notedown::core::syntax_tree::TableRow; use super::*; impl NoteInline for Node { @@ -135,6 +136,8 @@ impl NoteInline for InlineCode { } } + + impl NoteInline for InlineMath { fn note_down_inline(self, _: &mut ReadState) -> Result { let content = MathContent::Tex(self.value); @@ -143,15 +146,3 @@ impl NoteInline for InlineMath { } } -fn paragraph_items(children: Vec, state: &mut ReadState) -> Result, NotedownError> { - let mut items = Vec::with_capacity(children.len()); - for x in children { - match x.note_down_inline(state) { - Ok(o) => items.push(o), - Err(e) => { - state.errors.push(e); - } - } - } - Ok(items) -} diff --git a/projects/panduck-markdown/src/reader/list.rs b/projects/panduck-markdown/src/reader/list.rs index e8b4b3b..4c7ac66 100644 --- a/projects/panduck-markdown/src/reader/list.rs +++ b/projects/panduck-markdown/src/reader/list.rs @@ -1,28 +1,28 @@ use super::*; -use markdown::mdast::BlockQuote; -use wasi_notedown::exports::notedown::core::syntax_tree::{ListEnvironment, ListItem}; -impl NoteBlock for List { +impl NoteBlock for BlockQuote { fn note_down_block(self, state: &mut ReadState) -> Result { let list = ListEnvironment { items: vec![], range: self.position.as_range() }; + Ok(RootItem::List(list)) + } +} + +impl NoteBlock for List { + fn note_down_block(self, state: &mut ReadState) -> Result { + let mut items = Vec::with_capacity(self.children.len()); for x in self.children { match x { - Node::ListItem(v) => { - let items = root_items(v.children, state)?; - ListItem { level: 0, checked: v.checked, range: v.position.as_range() }; - } + Node::ListItem(v) => items.extend(list_item(v, state)), _ => unreachable!(), }; } + let list = ListEnvironment { items, range: self.position.as_range() }; Ok(RootItem::List(list)) } } -impl NoteBlock for BlockQuote { - fn note_down_block(self, state: &mut ReadState) -> Result { - let list = ListEnvironment { items: vec![], range: self.position.as_range() }; - - Ok(RootItem::List(list)) - } +fn list_item(item: markdown::mdast::ListItem, state: &mut ReadState) -> Option { + let items = root_items(item.children, state).unwrap(); + Some(ListItem { level: 0, checked: item.checked, range: item.position.as_range() }) } diff --git a/projects/panduck-markdown/src/reader/mod.rs b/projects/panduck-markdown/src/reader/mod.rs index a4e8f48..bba4213 100644 --- a/projects/panduck-markdown/src/reader/mod.rs +++ b/projects/panduck-markdown/src/reader/mod.rs @@ -1,17 +1,21 @@ -use crate::utils::{GetTextRange, NoteBlock, NoteInline, NoteRoot, ReadState}; +use crate::utils::{paragraph_items, root_items, GetTextRange, NoteBlock, NoteInline, NoteRoot, ReadState}; use markdown::{ - mdast::{Code, Delete, Emphasis, InlineCode, InlineMath, List, Math, Node, Paragraph, Root, Strong, Table, Text}, + mdast::{ + BlockQuote, Code, Delete, Emphasis, InlineCode, InlineMath, List, Math, Node, Paragraph, Root, Strong, Table, Text, + }, to_mdast, Constructs, ParseOptions, }; use wasi_notedown::exports::notedown::core::{ syntax_tree::{ - CodeAction, CodeEnvironment, CodeHighlight, MathContent, MathDisplay, MathEnvironment, NormalText, NotedownRoot, - ParagraphBlock, ParagraphItem, RootItem, StyleType, StyledText, + CodeAction, CodeEnvironment, CodeHighlight, ListEnvironment, ListItem, MathContent, MathDisplay, MathEnvironment, + NormalText, NotedownRoot, ParagraphBlock, ParagraphItem, RootItem, StyleType, StyledText, TableCell, TableEnvironment, + TableRow, }, types::{NotedownError, TextRange}, }; -mod code; +mod blocks; +mod html; mod inline; mod list; mod table; @@ -100,19 +104,6 @@ impl NoteRoot for Root { } } -fn root_items(children: Vec, state: &mut ReadState) -> Result, NotedownError> { - let mut blocks = Vec::with_capacity(children.len()); - for x in children { - match x.note_down_block(state) { - Ok(o) => blocks.push(o), - Err(e) => { - state.errors.push(e); - } - } - } - Ok(blocks) -} - #[test] fn ready() { println!("it works!") diff --git a/projects/panduck-markdown/src/reader/table.rs b/projects/panduck-markdown/src/reader/table.rs index 15c1642..19eb0ac 100644 --- a/projects/panduck-markdown/src/reader/table.rs +++ b/projects/panduck-markdown/src/reader/table.rs @@ -1,29 +1,31 @@ -use markdown::mdast::{TableCell, TableRow}; use super::*; -use wasi_notedown::exports::notedown::core::syntax_tree::TableEnvironment; impl NoteBlock for Table { fn note_down_block(self, state: &mut ReadState) -> Result { - let items = root_items(self.children, state)?; - - - let table = TableEnvironment { rows: vec![], range: self.position.as_range() }; + let mut rows = Vec::with_capacity(self.children.len()); + for x in self.children { + match x { + Node::TableRow(x) => rows.extend(table_row(x, state)), + _ => unreachable!(), + } + } + let table = TableEnvironment { rows, range: self.position.as_range() }; Ok(RootItem::Table(table)) } } -impl NoteBlock for TableRow { - fn note_down_block(self, state: &mut ReadState) -> Result { - let items = root_items(self.children, state)?; - let table = TableEnvironment { rows: vec![], range: self.position.as_range() }; - Ok(RootItem::Table(table)) +fn table_row(row: markdown::mdast::TableRow, state: &mut ReadState) -> Option { + let mut cells = Vec::with_capacity(row.children.len()); + for x in row.children { + match x { + Node::TableCell(x) => cells.extend(table_cell(x, state)), + _ => unreachable!(), + } } + Some(TableRow { cells, range: row.position.as_range() }) } -impl NoteBlock for TableCell { - fn note_down_block(self, state: &mut ReadState) -> Result { - let items = root_items(self.children, state)?; - let table = TableEnvironment { rows: vec![], range: self.position.as_range() }; - Ok(RootItem::Table(table)) - } +fn table_cell(cell: markdown::mdast::TableCell, state: &mut ReadState) -> Option { + let items = paragraph_items(cell.children, state).unwrap(); + Some(TableCell { range: cell.position.as_range() }) } diff --git a/projects/panduck-markdown/src/utils/mod.rs b/projects/panduck-markdown/src/utils/mod.rs index f71db76..3ebed79 100644 --- a/projects/panduck-markdown/src/utils/mod.rs +++ b/projects/panduck-markdown/src/utils/mod.rs @@ -1,10 +1,27 @@ -use markdown::unist::Position; -use wasi_notedown::exports::notedown::core::syntax_tree::{NotedownRoot, ParagraphItem, RootItem}; -use wasi_notedown::exports::notedown::core::types::{NotedownError, TextRange}; +use markdown::{mdast::Node, unist::Position}; +use wasi_notedown::exports::notedown::core::{ + syntax_tree::{NotedownRoot, ParagraphItem, RootItem}, + types::{NotedownError, TextRange}, +}; #[derive(Default)] pub struct ReadState { - pub errors: Vec, + errors: Vec, +} + +impl ReadState { + pub fn note_error(&mut self, e: NotedownError) { + self.errors.push(e) + } + pub fn take_errors(&mut self, r: Result) -> Option { + match r { + Ok(o) => Some(o), + Err(e) => { + self.note_error(e); + None + } + } + } } pub trait NoteRoot { @@ -26,18 +43,33 @@ pub trait GetTextRange { impl GetTextRange for Option { fn as_range(&self) -> TextRange { match self { - Some(s) => { - TextRange { - head_offset: s.start.offset as u32, - tail_offset: s.end.offset as u32, - } + Some(s) => TextRange { head_offset: s.start.offset as u32, tail_offset: s.end.offset as u32 }, + None => TextRange { head_offset: 0, tail_offset: 0 }, + } + } +} + +pub fn root_items(children: Vec, state: &mut ReadState) -> Result, NotedownError> { + let mut blocks = Vec::with_capacity(children.len()); + for x in children { + match x.note_down_block(state) { + Ok(o) => blocks.push(o), + Err(e) => { + state.errors.push(e); } - None => { - TextRange { - head_offset: 0, - tail_offset: 0, - } + } + } + Ok(blocks) +} +pub fn paragraph_items(children: Vec, state: &mut ReadState) -> Result, NotedownError> { + let mut items = Vec::with_capacity(children.len()); + for x in children { + match x.note_down_inline(state) { + Ok(o) => items.push(o), + Err(e) => { + state.errors.push(e); } } } -} \ No newline at end of file + Ok(items) +}