Destaque automático falha em alguns blocos de código delimitados

Isso acontece na minha configuração de desenvolvimento, em um fórum Discourse ao vivo https://discourse.gohugo.io/ e no playground do Discourse.

Em geral, quando um bloco de código delimitado não tem linguagem definida, temos a detecção automática. Isso tem sucesso em um uso normal do Highlight.JS (node ou navegador) na maioria das vezes, selecionando algo.

O Discourse parece salvar esses blocos como <code class="lang-auto">. o que não é uma linguagem válida :wink:

Conversei com o AI-Bot ask.discourse.cm…30386:
ele disse que você faz alguma mágica EM TEMPO DE EXECUÇÃO ao remover o “lang-auto” e depois deixa o highlight.js refazer o trabalho automático. Parece que essa atualização nem sempre acontece ANTES do highlight.JS tocar no código. Então, isso parece ser uma peculiaridade na integração do highlight.js e na implementação de detecção automática dentro do Discourse.

Desativar uma linguagem padrão também não funcionará, pois então o “remover lang-auto” não funcionará e parece que a maneira do Discourse não refaz a detecção automática.

  • definir a linguagem manualmente funciona na maioria das vezes – para linguagens integradas e uma linguagem personalizada (modelos do Hugo) adicionada via PluginAPI (registerHLJSLanguage) como um componente de tema.
  • sem uma linguagem, falha dependendo das condições de corrida de conteúdo(), tempos

Definir a linguagem padrão como “texto” não será uma opção, pois queremos que seja destacado e queremos detecção automática para usabilidade (e funciona…)

Aqui está um exemplo de Markdown, onde o segundo bloco de código falha (é claro, apenas se a linguagem padrão estiver definida como “auto”. Fácil de reproduzir com o markdown abaixo em https://try.discourse.org/

e dentro de 24h: Failed Discourse Autodetection breaks rendering of fenced code blocks - support - Discourse Demo

# Isso funciona

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

# Isso falhou e atribuiu "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 }}
```

Talvez seja simplesmente que o Discourse e o HighlightJS não conseguem reconhecer a linguagem, tratando-a como tal.

a ênfase aqui está no Discourse e no Highlight.JS

  • O Highlight.JS sozinho sempre detecta o idioma e o seleciona

  • No Discourse, sem o atributo lang, o idioma nem sempre é detectado em tempo de execução.

Fórum Hugo: 57307 Post 6:

Aqui está uma postagem do fórum: Proposal: Add highlighting support for Go/Hugo templates to Discourse - #6 by irkode - Meta - HUGO

  • o primeiro bloco de código é iniciado com ```hugo-html.
    isso resulta em <code="lang-hugo-html>
  • o segundo bloco com ```
    isso resulta em <code=“lang-auto”>

ambos os casos são destacados corretamente.

Fórum Hugo: 57367 Post 2:

E aqui está outro onde não funciona: How to capture/generate revisions of page? - #2 by Welsh - support - HUGO

aqui também é atribuído “lang-auto”, mas a detecção automática em tempo de execução não funciona.

Portanto, está de alguma forma relacionado à implementação do Discourse - possivelmente dependendo do conteúdo devido a timeouts, promises …

Talvez eu esteja entendendo errado, mas isso é o que estou vendo no primeiro link que você postou:

Nenhum deles mostra lang-auto, e ambos estão destacados da mesma forma, embora você não tenha especificado a linguagem do bloco de código para o segundo bloco.

Essa é a Console do Desenvolvedor — ela mostra o código após o highlight.js ter detectado automaticamente com sucesso.

Você precisará olhar o código-fonte da página (Ctrl+u), onde verá o lang-auto

que então acionará o método do Discourse de destaque automático, removendo o lang-auto e tentando novamente. Verifique a segunda postagem que liguei; é a mesma situação, mas ali a detecção falha.

E sim — sem a estrutura do Discourse ao redor, funciona.

Ao migrar para o Highlight.JS puro:

  • um código envolto em <code class="lang-auto"> não será destacado, a menos que tenhamos uma gramática para “auto” :wink:

  • poderíamos reiniciar a detecção automática para aqueles que usam um plugin:

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

Não consegui fazer isso funcionar no Discourse devido à maneira como Plugins e Gramáticas são integrados à API, e devido à encapsulação do DOM do motor e dos métodos do highlight.js, além de podermos ter condições de corrida com a renderização ao vivo padrão do Discourse

1 curtida