(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

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

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

投稿が新しいトピックに分割されました:Highlight.JSにテーマコンポーネント経由で新しい言語をインストールする

Chapel の構文ハイライトを、Chapel 用のサードパーティ製 highlight.js 拡張機能を使用して、当社の Chapel Language Discourse サイト に追加する方法を調べている際に、この記事を見つけました。

上記の @pmusaraj さんの例では、beancount を chapel に置き換える方法については理解できました。しかし、Discourse についてはまだ十分に慣れていないため、その後のスクリプトブロックをどう扱えば、当社の Discourse サイトで有効化できるのかがよくわかりません。私のような初心者にもわかるよう、何か追加のヒントをいただけませんでしょうか?

ありがとうございます!

Admin > カスタマイズ > テーマの下に新しいテーマコンポーネントを作成し、そのコードを <head> セクションに貼り付けてください。その後、必要に応じて修正や調整を行ってください。

詳細情報:

Discourse テーマの使い方:初心者ガイド
Discourse テーマの使い方:開発者ガイド

「いいね!」 4

@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 の以前のメジャーバージョンを使用しており、現在のバージョンと互換性がないことがわかりました。そのため、言語定義を修正する必要がありましたが、見事に動作しました。

構文ハイライト用の完全なテーマコンポーネントリポジトリ例に興味のある方のために、こちらをご覧ください:

「いいね!」 2

Screenshot 2024-01-21 at 8.41.45 PM

こんにちは @what、このトピックのOPは古くなっています。動作する手順を新しいトピックにまとめました。

「いいね!」 3