# markdown-it design principles ## Data flow Input data is piped via nestesd chains of rules. There are 3 nested chains - `core`, `block` & `inline`: ``` core core.rule1 ... (none yet, you can patch input string here) block block.rule1 ... block.ruleX core.ruleXX ... (references, abbreviations, footnotes) inline (applyed to each block token with "inline type") inline.rule1 ... inline.ruleX core.ruleYY ... (typographer, linkifier) ``` Mutable data are: - array of tokens - `env` sandbox Tokens are the "main" data, but some rules can be "splitted" to several chains, and need sandbox for exchange. Also, `env` can be used to inject per-render variables for your custom parse and render rules. Each chain (core / block / inline) has independent `state` object, to isolate data and protect code from clutter. ## Token stream Instead of traditional AST we use more low-level data representation - tokens. Difference is simple: - Tokens are sequence (Array). - Opening and closing tags are separate tokens. - There are special token object, "inline containers", having nested token sequences with inline markup (bold, italic, text, ...). Each token has common fields: - __type__ - token name. - __level__ - nesting level, useful to seek closeing pair. - __lines__ - [begin, end], for block tokens only. Range of input lines, compiled to this token. Inline container (`type === "inline"`) has additional properties: - __content__ - raw text, unparsed inline content. - __children__ - token stream for parsed content. In total, token stream is: - On the top level - array of paired or single "block" tokens: - open/close for headers, lists, blockquotes, paragraphs, ... - codes, fenced blocks, horisontal rules, html blocks, inlines containers - Each inline containers have `.children` property with token stream for inline content: - open/close for strong, em, link, code, ... - text, line breaks Why not AST? Because it's not needed for our tasks. We follow KISS principle. If you whish - you can call parser without renderer and convert token stream to AST. Where to search more details about tokens: - [Renderer source](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js) - [Live demo](https://markdown-it.github.io/) - type your text ant click `debug` tab. ## Parse process This was mentioned in [Data flow](#data-flow), but let's repeat sequence again: 1. Blocks are parsed, and top level of token stream filled with block tokens. 2. Content on inline containers is parsed, filling `.children` properties. 3. Rendering happens. And somewhere between you can apply addtional transformations :) . Full content of each chain can be seen on the top of [parser_core.js](https://github.com/markdown-it/markdown-it/blob/master/lib/parser_core.js), [parser_block.js](https://github.com/markdown-it/markdown-it/blob/master/lib/parser_block.js) and [parser_inline.js](https://github.com/markdown-it/markdown-it/blob/master/lib/parser_inline.js) files.