(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 „Gefällt mir“

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

4 „Gefällt mir“

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 „Gefällt mir“

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

Ein Beitrag wurde zu einem neuen Thema aufgeteilt: Eine neue Sprache für Highlight.JS über eine Theme-Komponente installieren

Ich bin auf diesen Artikel gestoßen, während ich recherchierte, wie man die Syntaxhervorhebung für Chapel auf unserer Chapel Language Discourse-Seite mit einer Drittanbieter-Erweiterung für highlight.js für Chapel unterstützt.

Im obigen Beispiel von @pmusaraj verstehe ich, wie ich es anpassen müsste, um beancount durch chapel zu ersetzen. Aber ich bin noch so neu bei Discourse, dass mir nicht klar ist, was ich dann mit dem Script-Block tun soll, um es für unsere Discourse-Seite zu aktivieren. Könnte jemand zusätzliche Hinweise für Anfänger wie mich geben?

Danke!

Du erstellst eine neue Theme-Komponente unter Admin > Anpassen > Themes und fügst den Code dann im </head>-Bereich ein. Von dort aus kannst du ihn bei Bedarf anpassen und verfeinern.

Weitere Informationen:

Anfängerleitfaden zur Verwendung von Discourse-Themes
Entwicklerleitfaden für Discourse-Themes

4 „Gefällt mir“

Danke @justin, genau das habe ich vermisst (und ich wäre nie selbst darauf gekommen, bevor ich aufgegeben hätte)! Unser Discourse rendert Chapel nun korrekt (oder zumindest so korrekt, wie es mein highlight.js-Skript ermöglicht – ein guter Anfang…).

Ein paar Dinge blieben mir trotz einiger Versuche und Irrtümer unklar:

  1. Stimmt es, dass das Sprach-Tag in einem dreifach geklammerten Block, wie:

    ```chapel
    

    nur mit dem (ersten) Argument des Aufrufs registerHighlightJSLanguage() abgeglichen wird? Oder wird es auch mit den Aliasen abgeglichen, die in der highlight.js-basierten Definition des Sprach-Highlighters definiert sind? Falls ersteres: Gibt es einen Grund, die Registrierung einer Sprachdefinition unter verschiedenen Aliasen zu vermeiden, um mehrere Formen zu unterstützen (z. B. ```chapel vs. ```chpl)?

  2. Stimmt es, dass die Sprache zusätzlich in der Einstellung „Hervorgehobene Sprachen“ der Website hinzugefügt werden muss, damit Codeblöcke erkannt werden? Und dass dieser Name mit dem String übereinstimmen muss, der an registerHighlightJSLanguage() übergeben wird?

Nochmals vielen Dank.

Ich habe eine neue Syntax-Hervorhebung für Jai erstellt: GitHub - Jai-Community/discourse-highlightjs-jai: Discourse theme component to highlight Jai syntax · GitHub

Wenn ich sie jedoch installiere, den Theme-Vorschaumodus aktiviere und dann ein neues Thema erstelle, um etwas Code hinzuzufügen, wie zum Beispiel:

```jai
#run {}
```

… wird die Sprache zwar erkannt (siehe das class-Attribut), aber es wird nichts geparst:

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

Während die gleiche Sprachdefinition in einer lokalen Umgebung die Jai-Syntax erfolgreich hervorhebt:

Probieren Sie es selbst aus, indem Sie _dev/test-syntax-highlight.html in Ihrem Browser öffnen.

Ideen?

Wie sich herausstellt, verwendet Discourse die vorherige Hauptversion von Highlight.js, die mit der aktuellen Version inkompatibel ist. Daher musste ich meine Sprachdefinition anpassen, und das hat perfekt funktioniert.

Für alle, die an einem vollständigen Beispiel für ein Theme-Komponenten-Repository zur Syntaxhervorhebung interessiert sind, hier ist es:

2 „Gefällt mir“

Screenshot 2024-01-21 at 8.41.45 PM

Hallo @what, der OP in diesem Thema war veraltet. Ich habe die funktionierenden Anweisungen in ein neues Thema verschoben:

3 „Gefällt mir“