Coder Social home page Coder Social logo

markdown-it-decorate's Introduction

markdown-it-decorate

Add attributes, IDs and classes to Markdown

Annotate your Markdown documents with HTML comments to add classes to HTML elements. Supported for and tested on markdown-it 6.x, 7.x, and 8.x.

Hello, from *Markdown*!
<!-- {.center} -->
<p class='center'>Hello, from <em>Markdown</em>!</p>

Status

Usage

Install the markdown-it-decorate package alongside markdown-it (they are peer dependencies).

yarn add --exact markdown-it markdown-it-decorate
# or:
npm install --save --save-exact markdown-it markdown-it-decorate

markdown-it-decorate can be loaded as a plugin using use().

const md = require('markdown-it')()
  .use(require('markdown-it-decorate'))

Cheatsheet

You can add classes, ID's, or attributes. (See § Annotating elements)

Source Output
Text <!--{.center}--> <p class='center'>Text</p>
Text <!-- {.center} --> <p class='center'>Text</p>
# Hola <!-- {.center.red} --> <h1 class='center red'>Hola</h1>
# Hola <!-- {#top .hide} --> <h1 id='top' class='hide'>Hola</h1>
# Hola <!-- {data-show="true"} --> <h1 data-show='true'>Hola</h1>
![Image](img.jpg)<!-- {width=20} --> <img src='img.jpg' alt='Image' width='20'>

You can specify the element name to decorate. (See § Disambiguating)

Source Output
> > Hi *world* <!-- {.red} --> <blockquote><blockquote>Hi <em class='red'>world...
> > Hi *world* <!-- {blockquote:.red} --> <blockquote><blockquote class='red'>Hi <em>world...
> > Hi *world* <!-- {blockquote^1:.red} --> <blockquote class='red'><blockquote>Hi <em>world...

Annotating elements

Create an HTML comment in the format <!-- {...} -->, where ... can be a .class, #id, key=attr or a combination of any of them. The spaces around {} are optional. Be sure to render markdownIt with html: true to enable parsing of <!--{comments}-->.

<!--{.class}-->
<!-- {.class} -->
<!-- {.class1.class2} -->
<!-- {.class1 .class2} -->
<!-- {#id} -->
<!-- {attr="val"} -->

You can put the comment in the same line or in the next. I recommend keeping it on a separate line, since this will make GitHub ignore it.

# Hello! <!-- {.center} -->
# Hello!
<!-- {.center} -->

Disambiguating

By default, annotations will be applied to the deepest element preceding it. In the case below, .wide will be applied to the link ("Next").

> This is a blockquote
>
> * It has a list.
> * You can specify tag names. [Next](#next)
> <!-- {.wide} -->

Specifying elements

To make it apply to a different element, precede your annotations with the tag name followed by a :.

> * It has a list.
> * You can specify tag names. [Next](#next) <!-- {li:.wide} -->

Combining

You can combine them as you need. In this example, the link gets .button, the list item gets .wide, and the blockquote gets .bordered.

> * [Continue](#continue)
<!-- {a:.button} -->
<!-- {li:.wide} -->
<!-- {blockquote:.bordered} -->
<blockquote class="bordered">
  <ul>
    <li class="wide">
      <a href="#continue" class="button">Continue</a>
    </li>
  </ul>
</blockquote>

Selecting same names

To go back to previous parent with the same name, add ^n after the tag name, where n is how many levels deep to go back to. Using ^0 is the same as not specifying it at all. (This convention is taken from gitrevisions.)

> > > targets 3rd quote <!--{blockquote:.wide}-->
> > > targets 2nd quote <!--{blockquote^1:.wide}-->
> > > targets 1st quote <!--{blockquote^2:.wide}-->

Decorating code blocks

You can decorate code blocks. You may choose to decorate pre, code, or even both.

```
return true;
```
<!-- {code: .lang-javascript} -->

Indented code blocks are only supported in markdown-it 7.x or later.

    // this is a code block
    return true;

<!-- {code: .lang-javascript} -->

Prior art

  • This is initially based off of arve0/markdown-it-attrs which uses text to annotate blocks (eg, {.class #id}). markdown-it-attr's approach was based off of Pandoc's header attributes.

  • Maruku (Ruby Markdown parser) also allows for block-level attributes and classnames with its meta-data syntax. The syntax is similar to PanDoc's syntax ({: .class #id}).

  • Kramdown (Ruby markdown parser) also supports the same syntax, also with a colon ({: .class #id}).

Motivation

markdown-it-decorate is inspired by the design of those features and improves on them:

  • Elements are marked via HTML comments; they'll be invisible to other Markdown parsers like GitHub's.
  • It supports inline elements in addition to block elements.

Thanks

markdown-it-decorate © 2015-2017, Rico Sta. Cruz. Released under the MIT License.
Authored and maintained by Rico Sta. Cruz with help from contributors (list).

ricostacruz.com  ·  GitHub @rstacruz  ·  Twitter @rstacruz

markdown-it-decorate's People

Contributors

arve0 avatar greenkeeperio-bot avatar rstacruz avatar stereoplegic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

markdown-it-decorate's Issues

Error: Unexpected Token

/node_modules/markdown-it-decorate/index.js:71
  omissions.forEach((idx) => { tokens.splice(idx, 1) })
                           ^
 SyntaxError: Unexpected token >

Maybe you added coffeescript directly into an javascript file!

Should that better be:

omissions.forEach((function(_this) {
  return function(idx) {
    return tokens.splice(idx, 1);
  };
})(this));

That's what coffeescript will make out of it.

pre and code tags?

I noticed that neither this module, nor markdown-it-attrs from which it is forked, support adding attributes to pre or code tags.

I see that part of the issue, at least with fenced code blocks using triple backticks, is that a lang-... class is automatically added to the child code tag. Attempting to add the attributes to the top row of backticks results in class="language-<!--", cutting off the rest e.g.:

\``` <!-- {#blah} --> //turns <pre><code> into <pre><code class="language-<!--">
exampleCode();
\```

Adding the decorate tags anywhere else simply adds the full to the markup: In the code block if added after the text, eg:

\```
exampleCode(); <!-- {#blah} --> //adds <!-- {#blah} --> to code's innerHTML
\```

or after the closing pre tag if added after the closing backticks, e.g.:

\```
exampleCode();
\``` <!-- {#blah} --> //adds <!-- {#blah} --> after </code></pre>

Are there any plans to support pre and code in the future?

Decorate children

I really like plugin attrs and decorate, but I'm looking for a way to decorate the children, ex.

Instead of

  - a {.x}
  - b
  {.decor}

I'd like to have something which decorate the children in {.decor} section, something like

  - a 
  - b
  {li: .x}

Kinda like css but it only adds the class name. I first wonder if this is possible in markdown-it, because I have trouble to find the children, not to mention to attach attrs to it.

Fang

Decorating pre/code tags doesn't work with syntax highlighting

Hi @rstacruz! Thanks for the great plugin!!

I am trying to use it to decorate code blocks and it is not working if syntax highlighting (through highlight.js) is being used. I'm configuring markdown-it to use highlight.js like this:

var md = require('markdown-it')({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
               hljs.highlight(lang, str, true).value +
               '</code></pre>';
      } catch (__) {}
    }
  
    return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
  }
});

If I just don't use syntax highlighting on markdown-it (e.g., comment the highlight configuration property), the decoration works just fine.

Do you know if this is something that has some workaround?

Thanks!!!

Escape hyperlinks

The following source renders to the screen rather than adding an attribute to the element. I believe the problem is the hyperlink.

<!-- {a:data-poster="https://img.youtube.com"} -->

Broken with `markdown-it-implicit-figures`

  • I'm trying to use markdown-it-decorate and markdown-it-implicit-figures together

  • The way markdown-it-implicit-figures works is that <img> elements on their own line are wrapped in <figure>'s instead of <p>'s. Also, if enabled in that package's options, any alternate text supplied in the Image Link syntax becomes the <figcaption> within the <figure>.

    So this Markdown syntax

    ![I am the alternate text, which will become the figure caption](/some/link/to/somewhere.jpg "This is the title of the image")

    would be parsed to this html output

    <figure>
      <img src="/some/link/to/somewhere.jpg" alt="I am the alternate text, which will become the figure caption" title="This is the title of the image">
      <figcaption>I am the alternate text, which will become the figure caption</figcaption>
    </figure>
  • I'd like to be able to apply a class of class to the image, like so:

    ![I am the alternate text, which will become the figure caption](/some/link/to/somewhere.jpg "This is the title of the image")
    <!-- {.class} -->

    and get this

    <figure>
      <img src="/some/link/to/somewhere.jpg" alt="I am the alternate text, which will become the figure caption" title="This is the title of the image" class="class">
      <figcaption>I am the alternate text, which will become the figure caption</figcaption>
    </figure>
  • Instead, I get something like this, with the class="class" applied to the <figcaption> (because it's a sibling to the <img> maybe?)

    <figure>
      <img src="/some/link/to/somewhere.jpg" alt="I am the alternate text, which will become the figure caption" title="This is the title of the image">
      <figcaption class="class">I am the alternate text, which will become the figure caption</figcaption>
    </figure>

    or, if I fiddle with the whole disambiguation thing (<!-- {img:.class} -->) and place the HTML comment thingie just to the right of the Image Link syntax, like this

    ![I am the alternate text, which will become the figure caption](/some/link/to/somewhere.jpg "This is the title of the image") <!-- {.class} -->

I get the class applied, but the <figcaption> is gone

<figure>
  <img src="/some/link/to/somewhere.jpg" alt="I am the alternate text, which will become the figure caption" title="This is the title of the image" class="class">
</figure>

Any ideas?

No access to require

I'm not using Node.js or anything like that; my code runs in the browser natively. As a result I don't have access to the require function. Can you add markdown-it-decorate to the window object so I can access it like this?

var markdown = windows.markdownit({html:true})
    .use(window.markdownitInlineComments)
    .use(window.markdownitDecorate)
    .use(window.markdownitContainer, /* blah */)

This is urgent, thanks.

About ops var and possible use case

I'm processing my files server side, so i don't need the use case for markdown parsers like GitHub.

Also, i prefer {:target="_blank"} syntax.

It is possible to add something like:

.use(require('markdown-it-decorate'), {
  open: '{',
  close: '}',
})

and

if (ops.open && ops.close) {
  var tagExpr = new RegExp(ops.open + "?\{(?:([a-z0-9]+)(\^[0-9]*)?: ?)?(.*)\} ?" + ops.close, "g");
} else {
  var tagExpr = /^<!-- ?\{(?:([a-z0-9]+)(\^[0-9]*)?: ?)?(.*)\} ?-->\n?$/
}

Or something like that? I would make a pull-request but i'm unable to achieve it, too complex for me

about "ops"

.use(require('markdown-it-decorate'), opts)

what are the options?

Warning: Unknown DOM property class. Did you mean className?

It looks like version 1.2.2 has an error where it does todo.push([ 'class', m[1], { append: true } ]) where it should be todo.push([ 'className', m[1], { append: true } ]) - this means that you cannot add css classes to a markdown element. The error is at https://github.com/rstacruz/markdown-it-decorate/blob/master/index.js#L171

After looking at the code it seems there is a workaround by doing <!-- {className=foo} --> rather than <!-- {.foo} --> but this is obviously not ideal.

After a little extra investigation this seems to behave differently running a jest test than it does when running in Chrome after compiling from typescript to es5 - in jest the className functionality seems to do the wrong thing while in the real world it's the only way to get this to work...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.