1pub mod attr;
2pub mod ext;
3pub mod liteval;
4pub mod partial;
5pub mod pretty;
6
7mod config;
8mod utils;
9
10pub use attr::AttrStore;
11pub use config::Config;
12use pretty::{prelude::*, PrettyPrinter};
13use thiserror::Error;
14use typst_syntax::{Source, SyntaxNode};
15
16use crate::utils::indent_4_to_2;
17
18#[derive(Error, Debug)]
19pub enum Error {
20 #[error("The document has syntax errors")]
21 SyntaxError,
22 #[error("An error occurred while rendering the document")]
23 RenderError,
24}
25
26#[derive(Debug, Clone, Default)]
28pub struct Typstyle {
29 config: Config,
30}
31
32impl Typstyle {
33 pub fn new(config: Config) -> Self {
35 Self { config }
36 }
37
38 pub fn format_text(&self, text: impl Into<String>) -> Formatter<'_> {
40 self.format_source(Source::detached(text.into()))
42 }
43
44 pub fn format_source(&self, source: Source) -> Formatter<'_> {
46 Formatter::new(self.config.clone(), source)
47 }
48}
49
50pub struct Formatter<'a> {
52 source: Source,
53 printer: PrettyPrinter<'a>,
54}
55
56impl<'a> Formatter<'a> {
57 fn new(config: Config, source: Source) -> Self {
58 let attr_store = AttrStore::new(source.root());
59 let printer = PrettyPrinter::new(config, attr_store);
60 Self { source, printer }
61 }
62
63 pub fn render_ir(&'a self) -> Result<String, Error> {
65 let doc = self.build_doc()?;
66 Ok(indent_4_to_2(&format!("{doc:#?}")))
67 }
68
69 pub fn render(&'a self) -> Result<String, Error> {
71 let doc = self.build_doc()?;
72 let mut buf = String::new();
73 doc.render_fmt(self.printer.config().max_width, &mut buf)
74 .map_err(|_| Error::RenderError)?;
75 let result = utils::strip_trailing_whitespace(&buf);
76 Ok(result)
77 }
78
79 fn build_doc(&'a self) -> Result<ArenaDoc<'a>, Error> {
80 let root = self.source.root();
81 if root.erroneous() {
82 return Err(Error::SyntaxError);
83 }
84 let markup = root.cast().unwrap();
85 let doc = self.printer.convert_markup(Default::default(), markup);
86 Ok(doc)
87 }
88}
89
90pub fn format_ast(root: &SyntaxNode) -> String {
92 indent_4_to_2(&format!("{root:#?}"))
93}