Transform a JSON grammar into a syntax-highlight mode for Highlight.js
A simple and light-weight (~ 44kB minified, ~ 15kB zipped) Highlight.js add-on
to generate highlightjs-compatible modes from a grammar specification in JSON format.
see also:
- Abacus advanced Combinatorics and Algebraic Number Theory Symbolic Computation library for JavaScript, Python
- Plot.js simple and small library which can plot graphs of functions and various simple charts and can render to Canvas, SVG and plain HTML
- HAAR.js image feature detection based on Haar Cascades in JavaScript (Viola-Jones-Lienhart et al Algorithm)
- HAARPHP image feature detection based on Haar Cascades in PHP (Viola-Jones-Lienhart et al Algorithm)
- FILTER.js video and image processing and computer vision Library in pure JavaScript (browser and node)
- Xpresion a simple and flexible eXpression parser engine (with custom functions and variables support), based on GrammarTemplate, for PHP, JavaScript, Python
- Regex Analyzer/Composer Regular Expression Analyzer and Composer for PHP, JavaScript, Python
- GrammarTemplate grammar-based templating for PHP, JavaScript, Python
- codemirror-grammar transform a formal grammar in JSON format into a syntax-highlight parser for CodeMirror editor
- ace-grammar transform a formal grammar in JSON format into a syntax-highlight parser for ACE editor
- prism-grammar transform a formal grammar in JSON format into a syntax-highlighter for Prism code highlighter
- highlightjs-grammar transform a formal grammar in JSON format into a syntax-highlight mode for Highlight.js code highlighter
- syntaxhighlighter-grammar transform a formal grammar in JSON format to a highlight brush for SyntaxHighlighter code highlighter
- SortingAlgorithms implementations of Sorting Algorithms in JavaScript
- PatternMatchingAlgorithms implementations of Pattern Matching Algorithms in JavaScript
Note: The invariant codebase for all the *-grammar
add-ons resides at editor-grammar repository (used as a git submodule
)
see Modularity and Future Directions
- enable grammar add-on to pre-compile a grammar specification directly into mode source code, so it can be used without the add-on as standalone mode [TODO, maybe]
- A
Grammar
can extend otherGrammars
(so arbitraryvariations
anddialects
can be handled more easily) Grammar
includes:Style Model
,Lex Model
andSyntax Model
(optional), plus a couple of settings (see examples)Grammar
specification can be minimal, defaults will be used (see example grammars)Grammar.Syntax Model
can enable highlight in a more context-specific way, plus detect possible syntax errorsGrammar.Syntax Model
can contain recursive referencesGrammar.Syntax Model
can be (fully) specificed usingPEG
-like notation orBNF
-like notation (NEW feature)Grammar.Syntax Model
implements positive / negative lookahead tokens (analogous toPEG
and-
/not-
predicates) (NEW feature)Grammar.Syntax Model
can include external (sub-)grammars so that new multiplexed / mixed grammars are created easily and intuitively (see test examples) (NEW feature)Grammar
can define action tokens to perform complex context-specific parsing functionality, including associated tag matching and duplicate identifiers (see for examplexml.grammar
example) (NEW feature)- Generated highlighters are optimized for speed and size
- Can generate a syntax-highlighter from a grammar interactively and on-the-fly ( see example, http://foo123.github.io/examples/highlightjs-grammar )
- see also Modularity and Future Directions
An example for XML:
// 1. a partial xml grammar in simple JSON format var xml_grammar = { // prefix ID for regular expressions, represented as strings, used in the grammar "RegExpID" : "RE::", // Style model "Style" : { "declaration" : "section" ,"doctype" : "template-tag" ,"meta" : "meta" ,"comment" : "comment" ,"cdata" : "literal" ,"atom" : "literal" ,"tag" : "meta" ,"attribute" : "built_in" ,"string" : "string" ,"number" : "number" }, // Lexical model "Lex" : { "comment:comment" : ["<!--", "-->"] ,"declaration:block" : ["<?xml", "?>"] ,"doctype:block" : ["RE::/<!doctype\\b/i", ">"] ,"meta:block" : ["RE::/<\\?[_a-zA-Z][\\w\\._\\-]*/", "?>"] ,"cdata:block" : ["<![CDATA[", "]]>"] ,"open_tag" : "RE::/<([_a-zA-Z][_a-zA-Z0-9\\-]*)/" ,"close_tag" : "RE::/<\\/([_a-zA-Z][_a-zA-Z0-9\\-]*)>/" ,"attribute" : "RE::/[_a-zA-Z][_a-zA-Z0-9\\-]*/" ,"string:line-block" : [["\""], ["'"]] ,"number" : ["RE::/[0-9]\\d*/", "RE::/#[0-9a-fA-F]+/"] ,"atom" : ["RE::/&#x[a-fA-F\\d]+;/", "RE::/&#[\\d]+;/", "RE::/&[a-zA-Z][a-zA-Z0-9]*;/"] ,"text" : "RE::/[^<&]+/" // actions ,"tag_ctx:action" : {"context":true} ,"\\tag_ctx:action" : {"context":false} ,"unique_id:action" : {"unique":["xml", "$1"],"msg":"Duplicate id value \"$0\""} ,"unique_att:action" : {"unique":["tag", "$0"],"msg":"Duplicate attribute \"$0\"","in-context":true} ,"tag_opened:action" : {"push":"<$1>","ci":true} ,"tag_closed:action" : {"pop":"<$1>","ci":true,"msg":"Tags \"$0\" and \"$1\" do not match"} ,"tag_autoclosed:action" : {"pop":null} ,"out_of_place:error" : "\"$2$3\" can only be at the beginning of XML document" }, // Syntax model (optional) "Syntax" : { "tag_att" : "'id'.attribute unique_att '=' string unique_id | attribute unique_att '=' (string | number)" ,"start_tag" : "open_tag.tag tag_ctx tag_opened tag_att* ('>'.tag | '/>'.tag tag_autoclosed) \\tag_ctx" ,"end_tag" : "close_tag.tag tag_closed" ,"xml" : "(^^1 declaration? doctype?) (declaration.error out_of_place | doctype.error out_of_place | comment | meta | cdata | start_tag | end_tag | atom | text)*" }, // what to parse and in what order "Parser" : [ ["xml"] ] }; // 2. parse the grammar into a Highlight.js-compatible mode var xml_mode = HighlightJSGrammar.getMode( xml_grammar ); // 3. use it with Highlight.js hljs.registerLanguage( "xml", xml_mode ); hljs.highlightBlock( document.getElementById("code") );
Result: