Rules are functions, doing "magic" with parser `state` objects. A rule is associated with one or more *chains* and is unique. For instance, a `blockquote` token is associated with the `blockquote`, `paragraph`, `heading`, and `list` chains.
Rules are managed by name via [`Ruler`](https://markdown-it.github.io/markdown-it/#Ruler) instances and can be enabled and disabled from [`MarkdownIt`](https://markdown-it.github.io/markdown-it/#MarkdownIt)'s methods.
Rules are managed by name via [`Ruler`](https://markdown-it.github.io/markdown-it/classes/Ruler.html) instances and can be enabled and disabled from [`MarkdownIt`](https://markdown-it.github.io/markdown-it/classes/MarkdownIt.html)'s methods.
Note that some rules have a `validation mode` -- in this mode, rules do not
modify the token stream and only look ahead for the end of a token. It's one
@ -97,7 +98,7 @@ and tried to do something yourself. We never reject with help to real developers
## Renderer
After the token stream is generated, it's passed to a [`Renderer`](https://markdown-it.github.io/markdown-it/#Renderer).
After the token stream is generated, it's passed to a [`Renderer`](https://markdown-it.github.io/markdown-it/classes/Renderer.html).
It then iterates through all the tokens, passing each to a rule with the same name as its token type.
Renderer rules are located in `md.renderer.rules[name]` and are simple functions
@ -188,4 +189,4 @@ Source code for each chain can be seen in the following files:
@ -10,7 +10,7 @@ The output document will be surrounded by `<section>` tags. Second-level heading
The top-level rule pipeline turning raw Markdown into a token array consists of **core rules**.
The *block* and *inline* rule pipelines are run within a single "wrapper" rule in the core pipeline.
The wrapper rules appear relatively early in the [core pipeline](https://github.com/markdown-it/markdown-it/blob/0fe7ccb4b7f30236fb05f623be6924961d296d3d/lib/parser_core.mjs#L19).
The wrapper rules appear relatively early in the [core pipeline](https://github.com/markdown-it/markdown-it/blob/master/src/parser_core.ts#L12-L25).
@ -53,7 +53,10 @@ Now take a closer look at the first element in the resulting list:
"hidden": false
}
```
This is a [Token](https://markdown-it.github.io/markdown-it/#Token). Its corresponding HTML `tag` is `ul` and its nesting is `1`. This means this specific token represents the opening tag of the HTML list we want to generate from markdown.
This is a [Token](https://markdown-it.github.io/markdown-it/classes/Token.html).
Its corresponding HTML `tag` is `ul` and its nesting is `1`. This means this
specific token represents the opening tag of the HTML list we want to generate
from markdown.
* `{ nesting: 1}` is an opening tag: `<ul>`
* `{ nesting: -1}` is a closing tag: `</ul>`
@ -62,7 +65,7 @@ This is a [Token](https://markdown-it.github.io/markdown-it/#Token). Its corresp
## Adding new rules
### To add a default CSS class to an element
Let's set ourself a goal:
Let's set ourself a goal:
```
Create a rule to add the CSS class "lorem_ipsum" to every <ul>
```
@ -105,7 +108,11 @@ Earlier we noticed that `renderer.rules.bullet_list_open` is undefined by defaul
CSS classes are attributes on HTML elements. If we think back to the object representation of the `ul` element we looked at, we might remember that it contained an `attrs` key with the value `null`. This means this token had no attributes. `attrs` can be an array of `[key, value]` pairs which describe attributes to be added to the token.
Looking at [the API documention for Token objects](https://markdown-it.github.io/markdown-it/#Token.attrJoin) we find the `attrJoin` method. This method allows us to join an existing attributes value with a new value or create the attribute if it doens't exist yet. Simply pushing the value (for example with `token.attr.push(["key", "value"]`) would overwrite any previous change:
Looking at [the API documention for Token objects](https://markdown-it.github.io/markdown-it/classes/Token.html#attrjoin)
we find the `attrJoin` method. This method allows us to join an existing
attributes value with a new value or create the attribute if it doens't exist
yet. Simply pushing the value (for example with `token.attr.push(["key", "value"]`)