This method doesn’t work any more. See This method no longer works. Please see Install a new language for Highlight.JS via a theme component instead.
Original Post
Warning: This is a crazy hack!
I’m just sharing because (1) it maybe helpful to someone and (2) hopefully you will teach me a better way.
I hired a “Discourse as a Service” instance, so I don’t control the source code, nor can install plugins.
I wanted my forum to highlight the Beancount language.
First I wrote the syntax definition and sent it to upstream, but I didn’t want to wait for a Highlight.JS and Discourse release, and for my host to upgrade my instance.
Then I went to Admin -> Customize -> CSS/HTML -> </head>
and added this hack to inject the Beancount language into Discourse’s Highlight.JS.
<script>
// Crazy hack to install Beancount syntax.
function waitForHighlightJS() {
if(typeof hljs !== "undefined"){
console.debug('HighlightJS ready... installing Beancount syntax.');
// Install Beancount syntax.
//Got this building highlight.js with: node tools/build.js -t cdn
hljs.registerLanguage("beancount",function(e){var c="[A-Z][A-Za-z0-9-]*",a="[0-9]{4}[-|/][0-9]{2}[-|/][0-9]{2}",b="(balance|commodity|custom|document|event|note|open|pad|price|query)",t={cN:"literal",b:/([\-|\+]?)([\d]+[\.]?[\d]*)/,r:0},n={cN:"string",b:'"',e:'"',r:0,c:[e.BE]},s={cN:"name",b:"\\{",e:"\\}",c:[{cN:"literal",b:a},t,n,{cN:"subst",b:"[A-Z][A-Z0-9'._-]{0,22}[A-Z0-9]"}]};return{aliases:["beancount","bean","ledger"],c:[{cN:"built_in",b:"^(include|option|plugin|popmeta|poptag|pushmeta|pushtag)",r:0},{b:"^"+a+"\\s+"+b,rB:!0,r:10,c:[{cN:"type",b:a,e:/\s+/,eE:!0},{cN:"keyword",b:b}]},{b:"^"+a+"\\s+.\\s",rB:!0,r:10,c:[{cN:"type",b:a,e:"\\s+",eE:!0},{cN:"variable",b:".",endsParent:!0}]},e.C(";","$"),{cN:"meta",b:/^\s{2,}[a-z][A-Za-z0-9\-_]+:/},s,{cN:"name",b:"@"},{cN:"type",b:c+":",r:0,c:[{cN:"subst",b:c+"(:"+c+")?"}]},{cN:"section",b:/^\*\s+?.*/},{cN:"link",b:/\^[A-Za-z0-9\-_\/.]+/},{cN:["emphasis"],b:/#[A-Za-z0-9\-_\/.]+/},n,t]}});
// Realod syntax for codeblocks.
$("pre code[class]").each(function(i, e){
hljs.highlightBlock(e);
})
console.debug('HighlightJS updated. Everything should look good.');
}
else{
console.debug('HighlightJS not ready yet.')
setTimeout(waitForHighlightJS, 250);
}
}
setTimeout(waitForHighlightJS, 250);
</script>
Works for me. If you have any suggestions I would be glad to hear. Mainly if you know how it can be done without the setTimeout
.
's!