El resaltado automático falla en algunos bloques de código

Esto ocurre en mi configuración de desarrollo, en un foro Discourse en vivo https://discourse.gohugo.io/ y en el campo de pruebas de Discourse.

En general, cuando un bloque de código con vallas no tiene un lenguaje establecido, se activa la detección automática. Esto tiene éxito en un uso normal de Highlight.JS (nodo o navegador) todo el tiempo seleccionando algo.

Discourse parece guardar estos bloques como <code class="lang-auto">, lo cual no es un lenguaje válido :wink:

Hablé con el bot de IA ask.discourse.cm…30386:
me dijo que hacen algo mágico EN TIEMPO DE EJECUCIÓN al eliminar “lang-auto” y luego dejan que highlight.js vuelva a hacer el trabajo automático. Parece que esta actualización no siempre ocurre ANTES de que highlight.JS toque el código. Así que parece ser un quirk en la integración de highlight.js y la implementación de detección automática dentro de Discourse.

Desactivar un lenguaje por defecto tampoco funcionará, porque entonces el “eliminar lang-auto” no funciona y parece que el método de Discourse no vuelve a hacer la detección automática.

  • establecer el lenguaje manualmente funciona todo el tiempo – para lenguajes integrados y un lenguaje personalizado (plantillas de Hugo) añadido a través de la API de plugins (registerHLJSLanguage) como un componente de tema.
  • sin un lenguaje, falla dependiendo de las condiciones de carrera de content(), tiempos

Establecer el lenguaje por defecto a “text” no será una opción porque queremos que esté resaltado y queremos la detección automática para usabilidad (y funciona…)

Aquí hay un ejemplo de Markdown, donde el segundo bloque de código falla (por supuesto, solo si el lenguaje por defecto está establecido en “auto”. Fácilmente reproducible con el siguiente markdown en https://try.discourse.org/

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

# Esto funciona

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

# Esto falló y asignó "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 }}
```

Quizás simplemente Discourse y HighlightJS no pueden reconocer el idioma, por lo que lo tratan como tal.

Aquí el énfasis recae en Discourse y Highlight.JS

  • Highlight.JS por sí solo siempre detecta el idioma y lo selecciona

  • En Discourse, sin embargo, sin el atributo lang, el idioma no siempre se detecta en tiempo de ejecución.

Foro de Hugo: Publicación 6 del tema 57307:

Aquí hay una publicación del foro: Proposal: Add highlighting support for Go/Hugo templates to Discourse - #6 by irkode - Meta - HUGO

  • El primer bloque de código se introduce con ```hugo-html.
    Esto genera <code="lang-hugo-html>
  • El segundo bloque con ```
    Esto genera <code="lang-auto">

En ambos casos, el resaltado se aplica correctamente.

Foro de Hugo: Publicación 2 del tema 57367:

Y aquí hay otro caso donde no funciona: How to capture/generate revisions of page? - #2 by Welsh - support - HUGO

Aquí también se asigna “lang-auto”, pero la detección automática en tiempo de ejecución no funciona.

Por lo tanto, parece estar relacionado de alguna manera con la implementación de Discourse, posiblemente dependiendo del contenido debido a tiempos de espera, promesas, etc.

Tal vez lo estoy entendiendo mal, pero esto es lo que veo en el primer enlace que publicaste:

Ninguno muestra lang-auto, y ambos están resaltados de la misma manera, aunque no especificaste el idioma del bloque de código para el segundo bloque de código.

Esa es la consola de desarrollo: muestra el código después de que highlight.js haya detectado automáticamente el lenguaje.

Tendrás que mirar el código fuente de la página (Ctrl+u), donde verás lang-auto,

lo que luego activará la forma de resaltado automático de Discourse al eliminar lang-auto. Intenta de nuevo y comprueba la segunda publicación que enlacé; es la misma situación, pero allí falla la detección.

Y sí, sin el marco de Discourse alrededor, funciona.

Al migrar a Highlight.JS puro:

  • un código envuelto en <code class="lang-auto"> no se resaltará a menos que tengamos una gramática para “auto” :wink:

  • podríamos reiniciar la detección automática para aquellos que usen un complemento:

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

No pude hacer que funcionara en Discourse debido a la forma en que los complementos y las gramáticas se integran con la API, y debido a la encapsulación del DOM del motor y los métodos de highlight.js, y a que podríamos tener condiciones de carrera con la renderización en vivo predeterminada de Discourse

1 me gusta