1use cdoc_parser::ast::Ast;
2use cdoc_parser::document::Document;
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6use crate::preprocessors::{AstPreprocessor, AstPreprocessorConfig, PreprocessorContext};
7
8#[derive(Serialize, Deserialize, Debug, Clone, Default)]
9pub struct Parser {
10 #[serde(default = "default_preprocessors")]
11 pub preprocessors: Vec<Box<dyn AstPreprocessorConfig>>,
12 #[serde(default, flatten)]
13 pub settings: ParserSettings,
14}
15
16fn default_preprocessors() -> Vec<Box<dyn AstPreprocessorConfig>> {
17 vec![]
18}
19
20#[derive(Serialize, Deserialize, Debug, Clone, Default)]
22pub struct ParserSettings {
23 #[serde(default)]
25 pub solutions: bool,
26}
27
28impl Parser {
29 pub fn parse(
30 &self,
31 doc: Document<Ast>,
32 ctx: &PreprocessorContext,
33 ) -> Result<Document<Ast>, anyhow::Error> {
34 let doc_ast = self.run_ast_processors(doc.clone(), ctx)?;
35
36 Ok(doc_ast)
37 }
38
39 pub fn run_ast_processors(
40 &self,
41 doc: Document<Ast>,
42 ctx: &PreprocessorContext,
43 ) -> Result<Document<Ast>, anyhow::Error> {
44 let mut built = self
45 .preprocessors
46 .iter()
47 .map(|p| p.build(ctx, &self.settings))
48 .collect::<anyhow::Result<Vec<Box<dyn AstPreprocessor>>>>()?;
49
50 let doc = built
51 .iter_mut()
52 .try_fold(doc, |c, ast_processor| ast_processor.process(c))?;
53
54 Ok(doc)
55 }
56}
57
58#[allow(unused)]
59struct HeadingNode {
60 id: String,
61 children: Vec<HeadingNode>,
62}
63
64#[derive(Error, Debug)]
65pub enum ParserError {
66 #[error("IO Error: ")]
67 IoError(#[from] std::io::Error),
68
69 #[error("Error in template")]
70 TemplateError(#[from] tera::Error),
71
72 #[error("JSON Error: ")]
73 JSONError(#[from] serde_json::error::Error),
74
75 #[error("Error parsing frontmatter: ")]
76 FrontMatter(#[from] serde_yaml::Error),
77
78 #[error(transparent)]
79 ExtensionError(#[from] crate::preprocessors::Error),
80
81 #[cfg(feature = "katex")]
82 #[error(transparent)]
83 KaTeX(#[from] katex::Error),
84
85 #[error(transparent)]
86 Std(#[from] Box<dyn std::error::Error>),
87
88 #[error(transparent)]
89 Anyhow(#[from] anyhow::Error),
90}
91
92#[cfg(test)]
93mod tests {
94
95 }