(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 « J'aime »

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

4 « J'aime »

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 « J'aime »

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

Un message a été divisé en un nouveau sujet : Installer une nouvelle langue pour Highlight.JS via un composant de thème

Je suis tombé sur cet article en cherchant comment ajouter la prise en charge de la coloration syntaxique du langage Chapel sur notre site Discourse du langage Chapel en utilisant une extension tierce de highlight.js pour Chapel.

Dans l’exemple de @pmusaraj ci-dessus, je comprends comment le modifier pour remplacer beancount par chapel. Mais étant assez nouveau sur Discourse, je ne vois pas clairement ce qu’il faut faire ensuite avec le bloc de script pour l’activer sur notre site Discourse. Quelqu’un pourrait-il fournir des indications supplémentaires pour des débutants comme moi ?

Merci !

Vous créerez un nouveau composant de thème sous Admin > Personnaliser > Thèmes, puis vous collerez ce code dans la section <head>. Ensuite, modifiez et ajustez selon les besoins.

Plus d’informations :

Guide du débutant pour l’utilisation des thèmes Discourse
Guide du développeur pour les thèmes Discourse

4 « J'aime »

Merci @justin, c’est exactement ce qui me manquait (et je n’y serais jamais arrivé seul avant d’abandonner) ! Notre Discourse affiche désormais Chapel correctement (ou du moins aussi correctement que le permet mon script highlight.js, ce qui est un excellent début…).

Quelques points qui restaient flous pour moi, même après quelques essais et erreurs :

  1. Est-il exact que l’étiquette de langue sur un bloc à triple guillemet, comme :

    ```chapel
    

    n’est comparée qu’au (premier) argument de l’appel à registerHighlightJSLanguage() ? Ou est-elle également comparée aux alias définis dans la définition basée sur highlight.js du surligneur de langue ? Dans le premier cas, y a-t-il une raison d’éviter d’enregistrer une définition de langue plusieurs fois sous différents alias pour prendre en charge plusieurs formes (par exemple ```chapel vs ```chpl) ?

  2. Est-il exact que la langue doit également être ajoutée au paramètre « langues surlignées » du site pour que les blocs de code soient reconnus ? Et que ce nom doit correspondre à la chaîne passée à registerHighlightJSLanguage() ?

Merci encore.

J’ai créé une nouvelle coloration syntaxique pour Jai : GitHub - Jai-Community/discourse-highlightjs-jai: Discourse theme component to highlight Jai syntax · GitHub

Cependant, lorsque je l’installe, que j’entre en mode aperçu du thème, puis que je crée un nouveau sujet et ajoute du code comme ceci :

```jai
#run {}
```

… il détecte bien la langue (voir l’attribut class), mais ne parvient pas à analyser le contenu :

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

Alors que l’exécution de la même définition de langue dans un environnement local réussit à colorier correctement la syntaxe Jai :

Vous pouvez essayer vous-même en ouvrant _dev/test-syntax-highlight.html dans votre navigateur.

Des idées ?

Il s’avère que Discourse utilise la version majeure précédente de Highlight.js, qui est incompatible avec la version actuelle. J’ai donc dû corriger ma définition de langage, et cela a fonctionné à merveille.

Pour toute personne intéressée par un exemple complet de dépôt de composant de thème pour la coloration syntaxique, le voici :

2 « J'aime »

Screenshot 2024-01-21 at 8.41.45 PM

Salut @what, l’OP de ce sujet était obsolète. J’ai extrait les instructions fonctionnelles dans un nouveau sujet :

3 « J'aime »