@mdit/plugin-attrs
Plugins to add attrs to Markdown content.
Usage
import MarkdownIt from "markdown-it";
import { attrs } from "@mdit/plugin-attrs";
const mdIt = new MarkdownIt().use(attrs, {
// your options, optional
});
mdIt.render("# Heading 🎉{#heading}");Syntax
You can use {attrs} to add attrs to Markdown content.
For example, if you want a heading2 "Hello World" with a id "say-hello-world", you can write:
## Hello World {#say-hello-world}If you want a image with class "full-width", you can write:
{.full-width}Also, other attrs are supported, so:
A paragraph with some text. {#p .a .b align=center customize-attr="content with spaces"}will be rendered into:
<p id="p" class="a b" align="center" customize-attr="content with spaces">
A paragraph with some text.
</p>Escaping can be done by adding \ to escape the delimiter:
### Heading \{#heading}will be
Heading {#heading}
Advanced
You can pass options to @mdit/plugin-attrs to customize plugin behavior.
rule
- Type:
"all" | boolean | MarkdownItAttrRuleName[]
type MarkdownItAttrRuleName =
| "fence"
| "inline"
| "table"
| "list"
| "hr"
| "heading"
| "softbreak"
| "blockInfo"
| "blockEnd"
// legacy alias of "blockEnd"
| "block"
// opt-in, excluded from "all"
| "tasklist"
| "dl";Default:
"all"Details: Rules to enable.
The default is
"all", which enables all rules. This is the most important option, as it controls which Markdown elements will have attrs enabled and affects the performance of the plugin.If you only need id attrs for headings (for most cases), you shall set
rule: ["heading"]to only enable attrs for headings.The
fencerule only applies to fenced code blocks, while theblockInforule covers other block tokens carrying attributes on their info line (e.g.: containers from@mdit/plugin-container). TheblockEndrule applies attributes written at the end of a block element -blockis its legacy alias.The
tasklistrule supports task list plugins that wrap item contents in a label (e.g.@mdit/plugin-tasklist). Task lists are not part of core markdown-it, so this rule must be enabled explicitly in the rule array and is excluded from"all". Thedlrule does the same for definition lists (e.g.@mdit/plugin-dl), whose paragraph-wrapped definitions hide attributes from the other rules.
allowed
Type:
(string \| RegExp)[] \| AllowedAttrEntry[]interface AllowedAttrEntry { name: string | RegExp; value?: (string | RegExp)[]; }Default:
[]Details: Allowed attributes.
An empty list means allowing all attributes.
You can use the simple format
(string \| RegExp)[]to only filter by attribute name:// Only allow class and id attributes allowed: ["class", "id"];Or use the entry format
AllowedAttrEntry[]to constrain allowed values per attribute:allowed: [ { name: "referrerpolicy", value: ["no-referrer", "no-referrer-when-downgrade"] }, { name: /^data-/, value: ["true", "false"] }, { name: "class" }, // allow class, any value ];
fenceAttrsOnPre
Type:
booleanDefault:
trueDetails: Place fence attributes on
<pre>instead of<code>.When enabled, attributes on fenced code blocks (e.g.
```js {data-file="index.js"}) are moved from<code>to the outer<pre>tag. This is skipped when a custom fence renderer is already installed.
left
- Type:
string - Default:
'{' - Details: Left delimiter for attributes.
right
- Type:
string - Default:
'}' - Details: Right delimiter for attributes.
Programmatic Parsing
The package exports a parseAttrs helper so that other tools (e.g.: shiki transformers) can reuse the attrs parsing logic:
import { parseAttrs } from "@mdit/plugin-attrs";
parseAttrs("foo {.bar #baz data-a=b}");
// [["class", "bar"], ["id", "baz"], ["data-a", "b"]]
parseAttrs("foo"); // nullparseAttrs(content, options) returns the parsed attrs as [key, value] tuples, or null when no valid attrs section is found. A valid section yielding no attrs (e.g.: all filtered out by allowed) returns an empty array. Besides left, right and allowed which behave the same as the plugin options, an extra where option is supported:
where
- Type:
"start" | "end" | "only" - Default:
"end" - Details: Where the attrs section shall be located in the content: at the start, at the end, or the content shall only contain the attrs section.
Demo
All classes are styled with
margin: 4px;padding: 4px;border: 1px solid red;to show the effect.
Inline
Text with inline code and , also supporting emphasis and bold.
Text with `inline code`{.inline-code} and {.image}, also supporting _emphasis_{.inline-emphasis} and **bold**{.inline-bold}.Block
block content
block content {.block}Fence
const a = 1;```js {.fence}
const a = 1;
```No red border here: the syntax highlighter used by these docs replaces the fence renderer and drops the attributes, as most code highlighting setups do.
Table
| A | B | C | D |
|---|---|---|---|
| A1 | B1 | C1 | D1 |
| A2 | C2 | ||
| C3 | |||
| A | B | C | D |
| ------------------------ | --- | --- | -------------- |
| A1 | B1 | C1 | D1 {rowspan=3} |
| A2 {colspan=2 rowspan=2} | B2 | C2 | D2 |
| A3 | B3 | C3 | D3 |
{.table border=1}List
- list item
- nested list item
- list item{.list-item}
- nested list item
{.nested}
{.list-wrapper}Horizontal Rule
--- {.horizontal}Softbreak
A line with break
A line with break
{.break}