11# Architecture
22
3- This document explains the internal architecture of the markdown2typst.
4-
53## Overview
4+ Here is an overview of the phases the library has when processing Markdown code to Typst code.
65
76```
87Markdown Input
@@ -28,24 +27,24 @@ The converter uses the unified/remark ecosystem to parse Markdown:
2827- ** remark-parse** : Parses Markdown to MDAST (Markdown Abstract Syntax Tree)
2928- ** remark-gfm** : Adds GitHub Flavored Markdown support (tables, strikethrough, code blocks...)
3029- ** remark-math** : Adds math equation support
31- - ** remark-frontmatter** : Parses YAML frontmatter
30+ - ** remark-frontmatter (and js-yaml) ** : Parses YAML frontmatter
3231
3332### 2. AST Processing
3433
3534After parsing, we process the AST to:
3635
37361 . ** Extract Metadata** :
3837 - Parse YAML frontmatter for title, authors, date, language, region, description and abstract
39- - Find leading H1 as potential title (metadata only in that case)
40- - Merge with user-provided options and in case of conflict options override front-matter
38+ - Find leading H1 as potential title
39+ - Merge with custom options if provided and in case of conflict options override front-matter
4140
42412 . ** Collect Definitions** :
4342 - Link reference definitions: ` [id]: url `
4443 - Footnote definitions: ` [^id]: content `
4544
4645
4746### 3. Rendering
48- The rendering phase walks the AST and converts each node to Typst syntax:
47+ The rendering phase iterates the AST and converts each node to Typst syntax:
4948
5049#### Block-Level Rendering
5150
@@ -70,33 +69,7 @@ The rendering phase walks the AST and converts each node to Typst syntax:
7069- ** Footnotes** : Inline with ` #footnote[] `
7170
7271
73- ## Key Design Decisions
74-
75- ### 1. Function Form for Formatting
76-
77- We use Typst function forms (` #strong[] ` , ` #emph[] ` ) instead of markup forms (` *text* ` , ` _text_ ` ):
78-
79- ** Advantages** :
80- - Unambiguous parsing (no conflicts with ` * ` in comments or math)
81- - Consistent with other Typst features
82- - Easier to nest and compose
83-
84- ** Trade-off** : Slightly more verbose output
85-
86- ### 2. Reference Resolution
87-
88- Link and footnote references are resolved at render time:
89-
90- ``` typescript
91- const definitions = collectDefinitions (tree );
92- const footnoteDefinitions = collectFootnotes (tree );
93- // Later, during rendering:
94- const def = definitions .get (identifier );
95- ```
96-
97- This allows reference-style links to work correctly.
98-
99- ### 3. Indentation Handling
72+ ### Note on indentation handling
10073
10174All rendering functions accept an ` indentLevel ` parameter for proper nesting:
10275
@@ -107,19 +80,14 @@ function renderBlock(node, indentLevel, definitions, footnotes) {
10780}
10881```
10982
110- This ensures nested lists and blockquotes are properly formatted.
111-
112- ### 4. Type Safety
83+ ## Contributing
11384
114- The codebase uses TypeScript with strict mode for maximum type safety:
85+ See [ CONTRIBUTING.md ] ( CONTRIBUTING.md ) for guidelines on extending the code.
11586
116- - All MDAST node types are imported from ` @types/mdast `
117- - Custom node types (math, mark, etc.) extend standard types
118- - Exported options are fully typed
11987
120- ## Extension Points
88+ ### How to add new Markdown features
12189
122- ### Adding New Markdown Features
90+ Here are some hints:
12391
124921 . Add remark plugin to parser:
12593``` typescript
@@ -128,108 +96,19 @@ const processor = unified()
12896 .use (remarkNewFeature )
12997```
13098
131- 2 . Define custom node type if needed:
99+ 1 . Define custom node type if needed:
132100``` typescript
133101interface NewFeatureNode extends Literal {
134102 type: ' newFeature' ;
135103 // additional fields
136104}
137105```
138106
139- 3 . Add rendering logic:
107+ 1 . Add rendering logic:
140108``` typescript
141109function renderNewFeature(node : NewFeatureNode ): string {
142110 // Convert to Typst
143111}
144112```
145113
146- 4 . Update the main switch statement in ` renderBlock ` or ` renderInline `
147-
148- ## Performance Considerations
149-
150- ### Current Performance
151-
152- The converter is designed for ** clarity over performance** , suitable for:
153- - Interactive editors (sub-second conversion for typical documents)
154- - Build processes (hundreds of documents per minute)
155- - Browser environments (client-side conversion)
156-
157- ### Optimization Opportunities
158-
159- If performance becomes critical:
160-
161- 1 . ** Memoization** : Cache rendered subtrees
162- 2 . ** Streaming** : Process large documents in chunks
163- 3 . ** Worker Threads** : Parallelize conversion of multiple files
164- 4 . ** AST Caching** : Cache parsed AST for unchanged documents
165-
166- ## Testing Strategy
167-
168- Currently, the project focuses on:
169-
170- 1 . ** Manual Testing** : Example files in ` examples/ `
171- 2 . ** Type Checking** : TypeScript used for type safety
172- 3 . ** Visual Inspection** : Compare Markdown input with Typst output
173-
174- ### Future Testing
175-
176- Recommended additions:
177-
178- 1 . ** Unit Tests** : Test individual rendering functions
179- 2 . ** Integration Tests** : Full Markdown → Typst conversion
180- 3 . ** Snapshot Tests** : Compare against known-good outputs
181- 4 . ** Fuzz Testing** : Random/malformed input handling
182- 5 . ** Users Testing** : In the work in progress demo website
183-
184- ## Build System
185-
186- The build system uses esbuild for fast bundling:
187-
188- ### Output Formats
189-
190- 1 . ** dist/markdown2typst.min.js** : Production bundle (minified)
191- 2 . ** dist/markdown2typst.js** : Development bundle (readable)
192- 3 . ** Source maps** : For debugging bundled code
193-
194- ### Configuration
195-
196- ``` javascript
197- {
198- format: " esm" , // ES modules
199- target: [" es2020" ], // Modern JavaScript
200- platform: " browser" , // Browser-compatible
201- bundle: true // Single file output
202- }
203- ```
204-
205- ## Dependencies
206-
207- ### Runtime Dependencies
208-
209- - ** unified** : Text processing framework
210- - ** remark-parse** : Markdown parser
211- - ** remark-gfm** : GitHub Flavored Markdown
212- - ** remark-math** : Math equation support
213- - ** remark-frontmatter** : YAML frontmatter parser
214-
215- ### Development Dependencies
216-
217- - ** typescript** : Type checking and definitions
218- - ** esbuild** : Fast bundler
219- - ** @types/mdast ** : MDAST type definitions
220-
221- ## Future Enhancements
222-
223- Potential improvements:
224-
225- 1 . ** CLI Tool** : Command-line interface for file conversion
226- 2 . ** VS Code Extension** : Live preview and conversion
227- 3 . ** Custom Templates** : User-provided template system
228- 4 . ** Plugin System** : Allow third-party extensions
229- 5 . ** Caching** : Improve performance for large documents
230- 6 . ** Validation** : Verify Typst output syntax
231- 7 . ** Source Maps** : Map Typst back to Markdown for errors
232-
233- ## Contributing
234-
235- See [ CONTRIBUTING.md] ( CONTRIBUTING.md ) for guidelines on extending the codebase.
114+ 1 . Update the main switch statement in ` renderBlock ` or ` renderInline `
0 commit comments