Search code examples
javascripthighlight.jsmarkdown-it

Highlight code with Markdown-it.js and Highlight.js


In the current example, a Markdown snippet is ported to HTML and the output is shown in the DIV (ID Content).

The highlight function (hljs.highlight) is set to the options markdown-it (md). However, this is not carried out.

What do I have to change so that the output uses the highlight.js?

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/11.0.1/markdown-it.min.js "></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.1/highlight.min.js"></script>
</head>
<body>
    <div id="content"></div>


    <script>
    var md = window.markdownit();
    md.set({
      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>';
      }
    });

    var result = md.render('# markdown-it rulezz! \n\n```html <pre><code class="js">function test();</code></pre>```');
    document.getElementById('content').innerHTML = result;
    </script>

    
</body>
</html>

Solution

  • Hope it's not too late.

    You must break line (\n) after your fenced code block.

    So this:

    var result = md.render('# markdown-it rulezz! \n\n```html <pre><code class="js">function test();</code></pre>```');
    

    Should be:

    var result = md.render('# markdown-it rulezz! \n\n ```html \n <pre><code class="js">function test();</code></pre>\n```');
    

    This is how everything should be:

    • the .js files should be:

      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/11.0.1/markdown-it.min.js "></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.1/highlight.min.js"></script>
      
    • These are okay.

    • As for the .css, you can use the one you are using or you can use the one that is in the npm:

    • npm install markdown-it-highlight

    • get the .css file at node_modules/markdown-it-highlight/dist/index.css, that has nicer syntax highlighting color and use that.

    • Then you would have to set this defaults object and set this on the defaults.highlight:

      var defaults = {
          html: false, // Enable HTML tags in source
          xhtmlOut: false, // Use '/' to close single tags (<br />)
          breaks: false, // Convert '\n' in paragraphs into <br>
          langPrefix: 'language-', // CSS language prefix for fenced blocks
          linkify: true, // autoconvert URL-like texts to links
          typographer: true, // Enable smartypants and other sweet transforms
          // options below are for demo only
          _highlight: true, // <= THIS IS WHAT YOU NEED
          _strict: false,
          _view: 'html' // html / src / debug
      };
      
      // and then do this:
      
      defaults.highlight = function (str, lang) {
          var esc = md.utils.escapeHtml;
          console.log(str)
          console.log(lang)
          if (lang && hljs.getLanguage(lang)) {
            try {
              return '<pre class="hljs"><code>' +
                     hljs.highlight(lang, str, true).value +
                     '</code></pre>';
            } catch (__) {}
          }else{
            return '<pre class="hljs"><code>' + esc(str) + '</code></pre>';
          }
      
      };
      
      // now set the md:
      
      md = window.markdownit(defaults);
      
      // now this is where you forgot the line break after the fenced code block:
      
      const result = md.render('# markdown-it rulezz! \n ```html \n <pre><code class="js">function test();</code></pre>\n```');
      
      document.querySelector('#content').innerHTML = result;