diff --git a/README.md b/README.md index c8a28fa..912d5f4 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,12 @@ bower install markdown-it --save ## Usage examples -See __[API documentation](https://markdown-it.github.io/markdown-it/)__ for more -info and examples. +See also: + +- __[API documentation](https://markdown-it.github.io/markdown-it/)__ - for more + info and examples. +- [Development info](https://github.com/markdown-it/markdown-it/tree/master/docs) - + for plugins writers. ### Simple @@ -152,6 +156,9 @@ var md = require('markdown-it')({ [API documentation](https://markdown-it.github.io/markdown-it/) +If you are going to write plugins - take a look at +[Development info](https://github.com/markdown-it/markdown-it/tree/master/docs). + ## Syntax extensions diff --git a/docs/architecture.md b/docs/architecture.md index d933962..afe6ad6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,8 +2,8 @@ ## Data flow -Parse process is unified as much as possible. Input data is piped via nestesd -chains of rules. There are 3 "main" chains (core / block / inline): +Input data is piped via nestesd chains of rules. There are 3 nested chains - +`core`, `block` & `inline`: ``` core @@ -44,42 +44,44 @@ data and protect code from clutter. ## Token stream Instead of traditional AST we use more low-level data representation - tokens. -Difference is very simple. +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) +- 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 2 mandatory fields: +Each token has common fields: - __type__ - token name. -- __level__ - nesting level, useful to seek matched pair. +- __level__ - nesting level, useful to seek closeing pair. - __lines__ - [begin, end], for block tokens only. Range of input lines, - compiled to this token + compiled to this token. Inline container (`type === "inline"`) has additional properties: - __content__ - raw text, unparsed inline content. - __children__ - token stream for parsed content. -See [renderer source](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js) -for available tokens and those properties. Currently there are no special -requirements on tokens naming and additional fields. - In total, token stream is: -- Array of paired or single "block" tokens, on top level: - - open/close for headers, lists, blockquotes paragraphs +- 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 -- Inline containers have "substream" Array with inline tags: +- 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 withour renderer and convert token stream +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: diff --git a/docs/development.md b/docs/development.md index 627d5dc..f9b0d8e 100644 --- a/docs/development.md +++ b/docs/development.md @@ -9,14 +9,15 @@ Prior to continue, make sure you've readed: ## General considerations for plugins. -1. Try to understand, where your plugin rule sould be located +1. Try to understand, where your plugin rule sould be located. - Will it conflict with existing markup (by priority)? - If yes - you need to write inline or block rule. - If no - you can morth tokens in core chain. - Remember, that tokens morphing in core is always more simple than writing - block / inline rules. However, block / inline rules are usually faster + block / inline rules (if you don't copy existing one). However, + block & inline rules are usually faster. - Sometime it's enougth to modify renderer only (for example, to add - header IDs or target=_blank for the links) + header IDs or `target="_blank"` for the links). 2. Search existing [plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin) or [rules](https://github.com/markdown-it/markdown-it/tree/master/lib), doing something similar. It can me more simple to modify existing code, @@ -39,6 +40,7 @@ To simplify search: ## FAQ + #### I need async rule, how to do it? Sorry. You can't do it directly. All complex parsers are sync by nature. But you @@ -47,4 +49,18 @@ can use workarounds: 1. On parse phase, replace content by random number and store it in `env`. 2. Do async processing over collected data. 3. Render content and replace those random numbers with text - (or replace first, then render) + (or replace first, then render). + +Or you can render html, then parse is to DOM (or +[cheerio](https://github.com/cheeriojs/cheerio) AST) and apply transformations +in more convenient way. + + +#### How to replace part of text token with link? + +Righ sequence is to split text to several tokens and add link tokens between. +Result will be: `text` + `link_open` + `text` + `link_close` + `text`. + +See implementations of [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js) & [emoji](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/replace.js) - those do similar things. + +__Note.__ Don't try to replace text with html markup! That's not secure.