(old) method for adding languages to highlight.js on Discourse

:warning: 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!

4 Mi Piace

Ideally I would prefer simply to upgrade highlight and make the brand new languages an option. This hack is very very very hacky.

4 Mi Piace

Me too! :smiley: Unfortunately this is not under my control.

I was wandering… Discourse’s HLJS plugin already allow some customization on init. Maybe it would be useful to not limit this customization to languages. Maybe passing an object that would be merged with the config object could do this trick and more.

However, I don’t think ppl need this very much. I’ll stick with my hack until (1) HLJS is released and (2) Discourse updated.

How do you indiciate which syntax highlighter to use when you insert code into a post?

AFAIK HighlightJS uses the first language that match.

However, every language has a “registration name”.

hljs.registerLanguage("beancount",function(e){...})

So if you want to explicitly define the language, inform the name after the triple ```.

``` python
Some code
```
4 Mi Piace

Thanks - I had seen the registration name but it wasn’t clear how to specify that name when posting code.

Un post è stato diviso in un nuovo argomento: Installare una nuova lingua per Highlight.JS tramite un componente del tema

Ho trovato questo articolo mentre cercavo informazioni su come aggiungere il supporto per l’evidenziazione della sintassi di Chapel sul nostro sito Discourse della lingua Chapel utilizzando un’estensione di highlight.js di terze parti per Chapel.

Nell’esempio di @pmusaraj sopra, ho capito come aggiornarlo per sostituire beancount con chapel. Ma essendo abbastanza nuovo su Discourse, non mi è chiaro cosa dovrei fare con il blocco di script per abilitarlo sul nostro sito Discourse. Qualcuno potrebbe fornire ulteriori indicazioni per principianti come me?

Grazie!

Creerai un nuovo componente del tema in Amministrazione > Personalizza > Temi, quindi incollerai quel codice nella sezione <head>. Da lì, modifica e aggiusta come necessario.

Ulteriori informazioni:

Guida per principianti all’uso dei temi Discourse
Guida per sviluppatori ai temi Discourse

4 Mi Piace

Grazie @justin, è esattamente ciò che mi mancava (e non ci sarei mai arrivato da solo prima di arrendermi)! Il nostro Discourse ora rende Chapel correttamente (o, almeno, il più correttamente possibile con il mio script highlight.js, che è un ottimo inizio…).

Alcune cose che sono rimaste poco chiare per me anche dopo qualche prova ed errore:

  1. È corretto che il tag della lingua su un blocco con triplo apice, come:

    ```chapel
    

    venga confrontato solo con il (primo) argomento della chiamata registerHighlightJSLanguage()? O viene confrontato anche con gli alias definiti nella definizione basata su highlight.js del rilevatore di sintassi della lingua? Nel primo caso, c’è qualche motivo per evitare di registrare una definizione di lingua più volte con vari alias per supportare diverse forme (ad esempio ```chapel rispetto a ```chpl)?

  2. È corretto che la lingua debba essere aggiunta anche all’impostazione “lingue evidenziate” del sito affinché i blocchi di codice vengano riconosciuti? E che questo nome debba corrispondere alla stringa passata a registerHighlightJSLanguage()?

Grazie ancora.

Ho creato una nuova evidenziazione della sintassi per Jai: GitHub - Jai-Community/discourse-highlightjs-jai: Discourse theme component to highlight Jai syntax · GitHub

Tuttavia, quando lo installo ed entro nella modalità di anteprima del tema, quindi creo un nuovo argomento e aggiungo del codice, come in questo caso:

```jai
#run {}
```

… rileva la lingua (vedi l’attributo class), ma non analizza nulla:

<pre><code class="lang-jai hljs">#run {}
</code></pre>

mentre eseguendo la stessa definizione di lingua con un’installazione locale, l’evidenziazione della sintassi di Jai funziona correttamente:

Prova tu stesso aprendo _dev/test-syntax-highlight.html nel tuo browser.

Idee?

Risulta che Discourse sta utilizzando la versione principale precedente di Highlight.js, che non è compatibile con quella attuale. Quindi ho dovuto correggere la mia definizione del linguaggio, e ha funzionato alla perfezione.

Per chiunque sia interessato a un esempio completo di repository di Componente Tema per l’evidenziazione della sintassi, eccolo qui:

2 Mi Piace

Screenshot 2024-01-21 at 8.41.45 PM

Ciao @what, l’OP in questo argomento era obsoleto. Ho estratto le istruzioni funzionanti in un nuovo argomento:

3 Mi Piace