Add MVP table support
Dependencies
- [2]
I3NG5A4WAdd support for content sequences - [3]
2N3KOCP7Create MVP Pandoc->Rust compiler - [4]
I5IZPMTHHandle empty expressions - [5]
BA5Y6VSEOutput Rust code using `syn` - [6]
BSJYWOYSImplement MVP Typst embedding - [7]
JCYJWUI3Add support for various text formats - [8]
MPTQGIIJImprove `typst_rust_gen` function names - [9]
YKL5NCLHImport items from `syn` - [10]
CQEA2ZDIParse evaluated Typst code instead of AST - [11]
HEIF2O2EMigrate from `pandoc` to `typst` for AST processing
Change contents
- replacement in docs/test.typ at line 1
#let add(x, y) = x + y#let verbose_add(x, y) = {[the number is] + repr(add(x, y))};Sum is #add(2, 3)Verbose: #verbose_add(3, 4)[3.242]#table(columns: 2,rows: 2,[1],[2],[3],[4]) - replacement in crates/typser/src/lib.rs at line 168
dbg!(typst_ast.scope());dbg!(typst_ast.scope(), typst_ast.clone().content()); - edit in crates/typser/src/lib.rs at line 320[3.669]→[3.1959:1961](∅→∅),[3.3798]→[3.1959:1961](∅→∅),[3.4305]→[3.1959:1961](∅→∅),[3.1959]→[3.1959:1961](∅→∅),[3.4011]→[3.2142:2143](∅→∅),[3.2142]→[3.2142:2143](∅→∅),[3.2143]→[3.41:115](∅→∅),[3.115]→[3.209:227](∅→∅),[3.209]→[3.209:227](∅→∅),[3.227]→[3.116:214](∅→∅),[3.214]→[3.319:369](∅→∅),[3.319]→[3.319:369](∅→∅),[3.242]→[3.242:373](∅→∅),[3.373]→[3.2211:2221](∅→∅),[3.390]→[3.2211:2221](∅→∅),[3.510]→[3.2211:2221](∅→∅),[3.1942]→[3.2211:2221](∅→∅),[3.4145]→[3.2211:2221](∅→∅),[3.2211]→[3.2211:2221](∅→∅),[3.2221]→[3.1943:1958](∅→∅),[3.1958]→[3.511:536](∅→∅),[3.536]→[3.1988:2008](∅→∅),[3.1988]→[3.1988:2008](∅→∅),[3.448]→[3.2380:2390](∅→∅),[3.2008]→[3.2380:2390](∅→∅),[3.4310]→[3.2380:2390](∅→∅),[3.2380]→[3.2380:2390](∅→∅),[3.2390]→[3.2009:2015](∅→∅)
}fn typst_expr_to_xilem(value: &typst::eval::Value) -> Option<syn::Expr> {match value {typst::eval::Value::Str(string) => Some(syn::Expr::Lit(literal_string(string.as_str()))),typst::eval::Value::Content(content) => {let supported_content = content::SupportedContent::downcast(content)?;Some(supported_content.to_xilem()?)}_ => {dbg!(value);todo!()}} - replacement in crates/typser/src/lib.rs at line 331[3.604]→[3.604:729](∅→∅),[3.729]→[3.374:411](∅→∅),[3.411]→[3.747:792](∅→∅),[3.747]→[3.747:792](∅→∅),[3.792]→[3.2339:2355](∅→∅),[3.2339]→[3.2339:2355](∅→∅),[3.2389]→[3.412:461](∅→∅),[3.461]→[2.146:187](∅→∅)
let children = if let Some(typst::eval::Value::Array(array)) = root.get_by_name("children") {array} else {dbg!(root);todo!();};let xilem_expressions = children.iter()// Remove any empty expressions (`None`).filter_map(typst_expr_to_xilem)let typed_content = content::SupportedContent::downcast(&root);let xilem_expressions = typed_content.to_xilem().into_iter() - edit in crates/typser/src/content.rs at line 2
use typst_library::layout::TableElem; - replacement in crates/typser/src/content.rs at line 6
use crate::{literal_string, split_tuple, xilem_html_element};use crate::{literal_string, xilem_html_element}; - edit in crates/typser/src/content.rs at line 14
Table(&'a TableElem), - replacement in crates/typser/src/content.rs at line 18
pub fn downcast(value: &'a Content) -> Option<Self> {if value.is_empty() {None} else if let Some(sequence) = value.to_sequence() {pub fn downcast(value: &'a Content) -> Self {if let Some(sequence) = value.to_sequence() { - replacement in crates/typser/src/content.rs at line 21
.filter_map(|child| SupportedContent::downcast(child)).map(|child| SupportedContent::downcast(child)) - replacement in crates/typser/src/content.rs at line 23
Some(Self::Sequence(children))Self::Sequence(children) - replacement in crates/typser/src/content.rs at line 25
Some(Self::Heading(heading))Self::Heading(heading) - replacement in crates/typser/src/content.rs at line 27
Some(Self::Text(text))Self::Text(text) - replacement in crates/typser/src/content.rs at line 29
Some(Self::Space(space))Self::Space(space)} else if let Some(table) = value.to::<TableElem>() {Self::Table(table) - replacement in crates/typser/src/content.rs at line 38
pub fn to_xilem(&self) -> Option<syn::Expr> {Some(match self {SupportedContent::Sequence(sequence) => {let children = split_tuple(sequence.iter().filter_map(SupportedContent::to_xilem).collect::<Vec<_>>(),);syn::Expr::Tuple(syn::ExprTuple {pub fn to_xilem(&self) -> Vec<syn::Expr> {match self {SupportedContent::Sequence(sequence) => sequence.iter().map(SupportedContent::to_xilem).flatten().collect::<Vec<_>>(),SupportedContent::Heading(heading) => {let body_text = Self::downcast(heading.body());vec![xilem_html_element("h1", body_text.to_xilem())]}SupportedContent::Text(text) => {vec![syn::Expr::Lit(literal_string(text.text().as_str()))]}SupportedContent::Space(_space) => vec![syn::Expr::Lit(literal_string(" "))],SupportedContent::Table(table) => vec![xilem_html_element("table",vec![syn::Expr::Tuple(syn::ExprTuple { - replacement in crates/typser/src/content.rs at line 58
elems: syn::punctuated::Punctuated::from_iter(children.into_iter()),})}SupportedContent::Heading(heading) => {let body_text = Self::downcast(heading.body())?;xilem_html_element("h1", vec![body_text.to_xilem()?])}SupportedContent::Text(text) => syn::Expr::Lit(literal_string(text.text().as_str())),SupportedContent::Space(_space) => syn::Expr::Lit(literal_string(" ")),})elems: syn::punctuated::Punctuated::from_iter(table.children().into_iter().map(|content| SupportedContent::downcast(content)).map(|supported| supported.to_xilem()).flatten().collect::<Vec<_>>().chunks(2) // TODO: a slightly more sophisticated layout algorithm.map(|chunk| {xilem_html_element("tr",vec![syn::Expr::Tuple(syn::ExprTuple {attrs: Vec::new(),paren_token: syn::token::Paren::default(),elems: syn::punctuated::Punctuated::from_iter(chunk.into_iter().map(|item| item.to_owned()),),})],)}),),})],)],}