Automatic highlighting fails for some fenced code blocks

This happens in my development setup, in a live discourse forum https://discourse.gohugo.io/ and the discourse playground.

In general when a fenced code block has no language set we get autodetection. This succeeds in a normal Highlight.JS usage (node or browser) all of the time by selecting something.

Discurses seems to save such blocks as <code class="lang-auto">. which is no valid language :wink:

I talked with the AI-Bot ask.discourse.cm…30386:
it told that you do some magic ON RUNTIME in removing the the “lang-auto” and then let highlight.js redo the auto work. It looks like that update is not all the time happening BEFORE highlight.JS touches the code. So that looks like a quirk in the highlight.js integration and auto-detect implementation within discourse.

unsetting a default language will also not work, cause then the “remove lang-auto” does not work and looks like the discourse way does not redo the autodetect.

  • setting the language manually works all of the time – for built-in and a custom (hugo-templates) language added via the PluginAPI (registerHLJSLanguage) as a theme component.
  • without a language it fails depending of the content() race conditions, timings

Setting default language to “text” won’t be a way cause we want that highlighted and we want autodetection for usability (and it works…)

Here’s a Markdown example, where the second code block fails (ofc only if the default language is set to “auto”. Easily reproducable with the below markdown on https://try.discourse.org/

and within 24h : Failed Discourse Autodetection breaks rendering of fenced code blocks - support - Discourse Demo

# This works

```
{{ $currentPagemd5 := md5 $currentPage.File.Path }}
    {{ $currentPagemd5ext := (print $currentPagemd5 ".json")}}
```

# This failed and assigned "lang-auto"

```
{{ $currentPage := . }}
{{ $jsonFile := "" }}
{{ with $currentPage.File }}
    {{ $currentPagemd5 := md5 $currentPage.File.Path }}
    {{ $currentPagemd5ext := (print $currentPagemd5 ".json")}}
    {{ $files := readDir "data/commits/" }}
    {{if gt (len $files ) 0}}
        <div class="bord-bas"></div>
        <div>
        <details>
            <summary>Changements de la page</summary>
            <div>
            {{ range $files }}
                {{ if eq .Name $currentPagemd5ext }}
                    {{ $jsonFile := $currentPagemd5 }}
                    {{ $data := index $.Site.Data.commits $jsonFile }}
                    <ul>
                    {{ range $data }}
                        <li>
                            {{ dateFormat "02/01/2006" .commit_date }} : {{ trim .message "\n" }} ({{ .author }})
                        </li>
                    {{ end }}
                    </ul>
                {{ end }}
            {{ end }}
            </div>
        </details>
        </div>
    {{ end }}
{{ end }}
```

Perhaps it is simply that Discourse and HighlightJS cannot recognize the language, hence making it as such.

The emphasis here is on Discourse and Highlight.JS

  • Highlight.JS alone always detects the language and selects it

  • In Discourse, however, the language is not always detected at runtime without the lang attribute.

Hugo Forum: 57307 Post 6:

Here is a post from the forum: Proposal: Add highlighting support for Go/Hugo templates to Discourse - #6 by irkode - Meta - HUGO

  • The first code block is introduced with ```hugo-html.
    This results in <code="lang-hugo-html>
  • The second block with ```
    This results in <code=“lang-auto”>

Both cases are highlighted correctly.

Hugo Forum: 57367 Post 2:

And here is another one where it doesn’t work: How to capture/generate revisions of page? - #2 by Welsh - support - HUGO

Here too, “lang-auto” is assigned, but the automatic detection at runtime does not work.

It somehow depends on the Discourse implementation - possibly depending on the content due to timeouts, promises …

Maybe I’m misunderstanding, but this is what I’m seeing in the 1st link you posted:

Neither shows lang-auto, and both are highlighted in the same way, although you did not specify the codeblock language for the second codeblock.

Thats the Developer Console - it shows the code after highlight.js has successfully autodetected.

You will have to look at the page source (Ctrl+u) where you will see the lang-auto

which then will trigger discourse way of auto-highlighting by removin the lang-auto and try again check the second post i linked, same situation but there detection fails.

and yes - without the discourse framework around it works

When moving to bare Highlight.JS:

  • a code wrapped in <code class="lang-auto"> won’t get highlighted unless we have a grammar for “auto” :wink:

  • we could restart the autodetection for those using a plugin:

    hljs.addPlugin({
       'before:highlight': (ctx) => {
          if (ctx.language === 'auto') {
             result = hljs.highlightAuto(ctx.code);
             ctx.language = result.language
             ctx.result = result
          }
       }
    });
    

I could not get that working in Discourse due to the way Plugins, Grammars are integrated with the API and due to the DOM capsulation of the highlight.js engine and methods, an if we might get race co ditio s with the default discourse live rendering

1 Like