(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!

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

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
```

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

Я наткнулся на эту статью, изучая, как добавить поддержку подсветки синтаксиса Chapel на нашем сайте Discourse для языка Chapel, используя стороннее расширение highlight.js для Chapel.

В примере от @pmusaraj выше я понимаю, как его обновить, чтобы заменить beancount на chapel. Но я достаточно новичок в Discourse, и мне не совсем понятно, что мне нужно сделать с блоком скрипта, чтобы включить его для нашего сайта Discourse. Не могли бы вы дать дополнительные советы для таких новичков, как я?

Спасибо!

Вы создадите новый компонент темы в разделе Администрирование > Настроить > Темы, а затем вставите этот код в секцию </head>. После этого при необходимости внесите изменения и доработки.

Подробнее:

Руководство для начинающих по использованию тем Discourse
Руководство разработчика по темам Discourse

Спасибо, @justin, это именно то, чего мне не хватало (и я бы никогда сам до этого не дошёл, не бросив всё раньше)! Теперь наш Discourse корректно отображает Chapel (или, по крайней мере, так же корректно, как это позволяет мой скрипт highlight.js, что уже отличный старт…).

Однако после некоторых проб и ошибок у меня осталось несколько неясностей:

  1. Правильно ли я понимаю, что языковой тег в блоке с тройными кавычками, например:

    ```chapel
    

    сопоставляется только с (первым) аргументом вызова registerHighlightJSLanguage()? Или же он также сопоставляется с алиасами, определёнными в описании языка на основе highlight.js? Если верно первое, есть ли причина избегать регистрации определения языка несколько раз под разными алиасами для поддержки различных форм (например, ```chapel против ```chpl)?

  2. Правильно ли я понимаю, что язык также необходимо добавить в настройку «выделенные языки» (highlighted languages) сайта, чтобы блоки кода распознавались? И что это имя должно совпадать со строкой, переданной в registerHighlightJSLanguage()?

Ещё раз спасибо.

Я создал новую подсветку синтаксиса для Jai: GitHub - Jai-Community/discourse-highlightjs-jai: Discourse theme component to highlight Jai syntax · GitHub

Однако, когда я устанавливаю её, перехожу в режим предпросмотра темы, создаю новую тему и добавляю код, например:

```jai
#run {}
```

… язык определяется (см. атрибут class), но ничего не парсится:

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

В то время как при запуске того же определения языка в локальной среде подсветка синтаксиса Jai работает успешно:

Попробуйте сами, открыв _dev/test-syntax-highlight.html в браузере.

Есть идеи?

Оказывается, Discourse использует предыдущую основную версию Highlight.js, которая несовместима с текущей. Поэтому мне пришлось исправить моё определение языка, и всё заработало как по маслу.

Для всех, кто заинтересован в полном примере репозитория компонента темы для подсветки синтаксиса, вот он:

Скриншот 21.01.2024 в 20:41:45

Привет, @what, исходный пост в этой теме был устаревшим. Я вынес актуальные инструкции в новую тему: