일부 코드 블록에서 자동 하이라이팅이 작동하지 않습니다

이 문제는 제 개발 환경, 라이브 디스커스 포럼(https://discourse.gohugo.io/) 및 디스커스 플레이그라운드에서 발생합니다.

일반적으로 펜스 코드 블록(fenced code block)에 언어가 설정되지 않은 경우 자동 감지가 수행됩니다. 이는 일반적인 Highlight.JS 사용 환경(노드 또는 브라우저)에서는 항상 무언가를 선택하여 성공합니다.

디스커스는 이러한 블록을 <code class="lang-auto">로 저장하는 것 같습니다. 이는 유효한 언어가 아닙니다. :wink:

AI 봇 ask.discourse.cm…30386과 대화했는데,
런타임 시 "lang-auto"를 제거하는 마법을 부린 다음 highlight.js가 자동 감지 작업을 다시 수행하게 한다고 했습니다. 이 업데이트가 항상 highlight.JS가 코드를 처리하기 이전에 수행되는 것은 아닌 것 같습니다. 따라서 이는 디스커스 내 highlight.js 통합 및 자동 감지 구현의 버그로 보입니다.

기본 언어를 해제하는 것도 작동하지 않습니다. 그렇게 하면 "lang-auto 제거"가 작동하지 않고, 디스커스 방식은 자동 감지를 다시 수행하지 않는 것으로 보입니다.

  • 언어를 수동으로 설정하면 항상 작동합니다. 내장 언어와 PluginAPI(registerHLJSLanguage)를 통해 테마 컴포넌트로 추가된 사용자 정의 언어(hugo-templates) 모두 해당됩니다.
  • 언어가 없으면 콘텐츠() 레이스 컨디션과 타이밍에 따라 실패합니다.

기본 언어를 "text"로 설정하는 것은 해결책이 될 수 없습니다. 우리는 하이라이팅이 필요하며, 사용성을 위해 자동 감지가 필요합니다(그리고 실제로 작동하니까요…).

여기 마크다운 예시가 있습니다. 두 번째 코드 블록이 실패합니다(물론 기본 언어가 "auto"로 설정된 경우에만). 아래 마크다운으로 https://try.discourse.org/에서 쉽게 재현할 수 있습니다.

그리고 24시간 이내: https://try.discourse.org/t/failed-discourse-autodetection-breaks-rendering-of-fenced-code-blocks/1504

# 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 }}
```
1개의 좋아요

아마도 Discourse와 HighlightJS가 해당 언어를 인식하지 못해서 그렇게 된 것일 수 있습니다.

1개의 좋아요

여기서 강조할 점은 Discourse 그리고 Highlight.JS입니다.

  • Highlight.JS 단독으로 사용되면 언어가 항상 감지되어 선택됩니다.

  • 하지만 Discourse에서는 lang 속성이 없으면 실행 시점에 언어가 항상 감지되지 않습니다.

Hugo 포럼: 57307 게시물 6:

포럼에서 가져온 게시물입니다: Proposal: Add highlighting support for Go/Hugo templates to Discourse - #6 by irkode - Meta - HUGO

  • 첫 번째 코드 블록은 ```hugo-html로 시작합니다.
    이는 <code="lang-hugo-html>를 생성합니다.
  • 두 번째 블록은 ```로 시작합니다.
    이는 <code="lang-auto>를 생성합니다.

두 경우 모두 하이라이팅이 올바르게 적용됩니다.

Hugo 포럼: 57367 게시물 2:

그리고 여기 작동하지 않는 또 다른 사례가 있습니다: How to capture/generate revisions of page? - #2 by Welsh - support - HUGO

여기서도 "lang-auto"가 할당되지만, 실행 시점의 자동 감지가 작동하지 않습니다.

따라서 이는 어딘가에서 Discourse 구현과 관련이 있는 것으로 보입니다 - 타임아웃, promise 등으로 인해 콘텐츠에 따라 달라질 수 있습니다.

아마 내가 오해하고 있는 것일 수도 있지만, 게시하신 첫 번째 링크에서 제가 확인한 내용은 다음과 같습니다:

두 곳 모두 lang-auto가 표시되어 있지 않으며, 두 번째 코드 블록의 언어를 지정하지 않으셨음에도 불구하고 두 코드 블록은 동일한 방식으로 강조되어 있습니다.

이것은 개발자 콘솔입니다. highlight.js가 성공적으로 자동 감지를 완료한 이후의 코드를 표시합니다.

페이지 소스(Ctrl+u)를 확인해야 합니다. 그곳에서 lang-auto를 볼 수 있습니다.

lang-auto는 discourse의 자동 하이라이팅 방식을 트리거하며, 이 방식은 lang-auto를 제거하고 다시 시도합니다. 제가 링크한 두 번째 게시물을 확인해 보세요. 동일한 상황이지만, 거기서는 감지가 실패합니다.

그리고 네 - discourse 프레임워크 없이 작동합니다.

순수 Highlight.JS로 전환할 때:

  • <code class="lang-auto">로 감싸진 코드는 "auto"에 대한 문법이 없으면 하이라이팅되지 않습니다. :wink:

  • 플러그인을 사용하여 해당 항목에 대한 자동 감지를 다시 시작할 수 있습니다:

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

Discourse에서는 플러그인과 문법이 API와 통합되는 방식, highlight.js 엔진과 메서드의 DOM 캡슐화, promise를 사용한 비동기 처리, 그리고 기본 Discourse 라이브 렌더링과의 경쟁 상태(race conditions) 발생 가능성 때문에 이를 작동하게 만들 수 없었습니다.

1개의 좋아요

코드가 1,000자를 초과하는 경우 자동 감지를 건너뛰는 조건 때문에 하이라이팅이 적용되지 않습니다.

이 PR에서는 언어 감지를 위해 2,000자 제한의 접두사를 사용하는 방식으로 로직을 변경합니다.

3개의 좋아요

조사와 수정 감사합니다 - 이제 실제로 작동하는 것을 확인해 볼 예정입니다.

이미 마음에 들어요.

특히 “첫 2000개 사용” 기능은 큰 이점을 가져다줄 것입니다.

이것은 이제 라이브인 것 같습니다

감사합니다