(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 구문 하이라이팅을 Chapel에 대한 제3자 highlight.js 확장 플러그인을 사용하여 Chapel Language Discourse 사이트에 추가하는 방법을 조사하다가 이 기사를 발견했습니다.

@pmusaraj님의 위의 예시에서는 beancount를 chapel로 대체하는 방법을 이해하고 있습니다. 하지만 저는 Discourse에 익숙하지 않아, 그 다음 스크립트 블록을 어떻게 해야 Discourse 사이트에서 활성화할 수 있는지 명확하지 않습니다. 저와 같은 초보자를 위해 추가적인 힌트를 주실 수 있으신가요?

감사합니다!

Admin > Customize > Themes 아래에서 새 테마 컴포넌트를 생성한 다음, 해당 코드를 </head> 섹션에 붙여넣으세요. 이후 필요에 따라 수정하고 조정하면 됩니다.

자세한 정보:

Beginner’s guide to using Discourse Themes
Developer’s guide to Discourse Themes

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를 사용하고 있었던 것입니다. 그래서 제 언어 정의를 수정해야 했는데, 그랬더니 완벽하게 작동했습니다.

구문 하이라이팅을 위한 완전한 Theme Component 저장소 예시를 궁금해하시는 분들을 위해 링크를 공유합니다:

Screenshot 2024-01-21 at 8.41.45 PM

Hi @what, 이 주제의 원 게시자(OP)가 오래된 상태였습니다. 작동하는 지침을 새 주제로 분리해 두었습니다: