(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 Me gusta

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

4 Me gusta

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 Me gusta

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

Se dividió una publicación a un nuevo tema: Instalar un nuevo idioma para Highlight.JS a través de un componente temático

Encontré este artículo mientras investigaba cómo agregar soporte para el resaltado de sintaxis de Chapel en nuestro sitio Discourse del lenguaje Chapel utilizando una extensión de highlight.js de terceros para Chapel.

En el ejemplo de @pmusaraj anterior, entiendo cómo actualizarlo para reemplazar beancount con chapel. Pero como soy relativamente nuevo en Discourse, no me queda claro qué debo hacer luego con el bloque de script para habilitarlo en nuestro sitio de Discourse. ¿Alguien podría proporcionar más indicaciones para principiantes como yo?

¡Gracias!

Crearías un nuevo componente de tema en Admin > Personalizar > Temas y luego pegarías ese código en la sección </head>. A partir de ahí, podrás modificarlo y ajustarlo según sea necesario.

Más información:

Guía para principiantes sobre el uso de temas en Discourse
Guía para desarrolladores sobre temas de Discourse

4 Me gusta

Gracias @justin, esto es exactamente lo que me faltaba (¡y nunca lo habría descubierto yo mismo antes de rendirme!). Nuestro Discourse ahora renderiza Chapel correctamente (o, al menos, tan correctamente como lo hace mi script de highlight.js, lo cual es un gran comienzo).

Unas pocas cosas que seguían sin estar claras para mí incluso después de algunos ensayos y errores:

  1. ¿Es correcto que la etiqueta de idioma en un bloque con tres comillas, como:

    ```chapel
    

    solo se compara con el (primer) argumento de la llamada a registerHighlightJSLanguage()? ¿O también se compara con los alias definidos dentro de la definición basada en highlight.js del resaltador de idiomas? Si es lo primero, ¿hay alguna razón para evitar registrar una definición de idioma varias veces bajo varios alias para admitir múltiples formas (por ejemplo, ```chapel frente a ```chpl)?

  2. ¿Es correcto que el idioma también debe agregarse a la configuración de “idiomas resaltados” del sitio para que los bloques de código sean reconocidos? ¿Y que este nombre debe coincidir con la cadena pasada a registerHighlightJSLanguage()?

Gracias de nuevo.

He creado un nuevo resaltado de sintaxis para Jai: GitHub - Jai-Community/discourse-highlightjs-jai: Discourse theme component to highlight Jai syntax · GitHub

Sin embargo, cuando lo instalo, entro en el modo de vista previa del tema y luego creo un nuevo tema añadiendo algo de código, como esto:

```jai
#run {}
```

… detecta el lenguaje (fíjate en el atributo class), pero no parsea nada:

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

mientras que ejecutar la misma definición de lenguaje con una configuración local sí resalta la sintaxis de Jai correctamente:

Pruébalo tú mismo abriendo _dev/test-syntax-highlight.html en tu navegador.

¿Alguna idea?

Resulta que Discourse está utilizando la versión mayor anterior de Highlight.js, que es incompatible con la actual. Así que tuve que corregir mi definición de lenguaje, y funcionó de maravilla.

Para cualquiera que esté interesado en un ejemplo completo de repositorio de componente de tema para resaltado de sintaxis, aquí está:

2 Me gusta

Screenshot 2024-01-21 at 8.41.45 PM

Hola @what, el OP de este tema estaba desactualizado. He extraído las instrucciones de trabajo en un nuevo tema:

3 Me gusta