Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highlight.js custom language definition

I'm trying to create language definition for highlight.js. But it doesn't work. I've got an example.

In this example i'm trying to create custom "aaa" language, which is the same as JSON. registerLanguage function receives same function as a default JSON highlight function (from highlight.js sources).

hljs.listLanguages() shows, that language is registered.

After, i'm calling hljs.highlightBlock(block).

<code class="aaa"> forces to use custom "aaa" language, and in this case hljs.highlightBlock(block) doesn't changes content.

$(document).ready(function() {
  // registering aaa language (JSON alias)
  // code from https://github.com/isagalaev/highlight.js/blob/master/src/languages/json.js
  hljs.registerLanguage("aaa", function(hljs) {
    var LITERALS = {
      literal: 'true false null'
    };
    var TYPES = [
      hljs.QUOTE_STRING_MODE,
      hljs.C_NUMBER_MODE
    ];
    var VALUE_CONTAINER = {
      className: 'value',
      end: ',',
      endsWithParent: true,
      excludeEnd: true,
      contains: TYPES,
      keywords: LITERALS
    };
    var OBJECT = {
      begin: '{',
      end: '}',
      contains: [{
        className: 'attribute',
        begin: '\\s*"',
        end: '"\\s*:\\s*',
        excludeBegin: true,
        excludeEnd: true,
        contains: [hljs.BACKSLASH_ESCAPE],
        illegal: '\\n',
        starts: VALUE_CONTAINER
      }],
      illegal: '\\S'
    };
    var ARRAY = {
      begin: '\\[',
      end: '\\]',
      contains: [hljs.inherit(VALUE_CONTAINER, {
        className: null
      })], // inherit is also a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents
      illegal: '\\S'
    };
    TYPES.splice(TYPES.length, 0, OBJECT, ARRAY);
    return {
      contains: TYPES,
      keywords: LITERALS,
      illegal: '\\S'
    };
  });
  console.log(hljs.listLanguages()); // aaa in the list
  $('pre code').each(function(i, block) {
    hljs.highlightBlock(block);
  });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/tomorrow.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js"></script>
<pre><code class="aaa"> 
{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
</code></pre>
like image 478
Mark Birger Avatar asked Feb 20 '15 13:02

Mark Birger


1 Answers

Highlight.js have a minification/packing process during build that renames the fields of the language definition objects. This means that the objects they describe in http://highlightjs.readthedocs.org/en/latest/language-guide.html won't work with the distributed library. Only languages defined before build time will work this way.

You could look in the minified highlightjs file for usages of registerLanguage to try and reverse engineer the names of fields.

like image 172
Steven Miles Avatar answered Nov 18 '22 20:11

Steven Miles