الفشل في التمييز التلقائي لبعض كتل الأكواد المحاطة

يحدث هذا في إعداد التطوير الخاص بي، في منتدى Discourse المباشر https://discourse.gohugo.io/ وفي مساحة Discourse للتجربة.

بشكل عام، عندما لا يكون هناك لغة محددة في كتلة الكود المحاطة (fenced code block)، يتم الكشف التلقائي. وهذا ينجح في الاستخدام العادي لـ Highlight.JS (سواء في Node أو المتصفح) في جميع الأوقات عن طريق اختيار شيء ما.

يبدو أن Discourse يحفظ هذه الكتل كـ <code class="lang-auto">، وهو ليس لغة صالحة :wink:

تحدثت مع بوت الذكاء الاصطناعي ask.discourse.cm…30386:
قال إنه تقومون ببعض العمليات السحرية أثناء التشغيل (ON RUNTIME) لإزالة “lang-auto” ثم تتركون highlight.js يعيد عمل الكشف التلقائي. يبدو أن هذا التحديث لا يحدث دائمًا قبل أن يتعامل highlight.JS مع الكود. لذا يبدو أن هناك عيبًا في تكامل highlight.js وتنفيذ الكشف التلقائي داخل Discourse.

إلغاء تعيين لغة افتراضية لن يعمل أيضًا، لأن إزالة “lang-auto” لن تعمل ويبدو أن طريقة Discourse لا تعيد الكشف التلقائي.

  • تعيين اللغة يدويًا يعمل في جميع الأوقات – للغات المدمجة ولغة مخصصة (قوالب Hugo) مضافة عبر PluginAPI (registerHLJSLanguage) كعنصر في السمة.
  • بدون لغة، يفشل الأمر اعتمادًا على ظروف السباق (race conditions) والتوقيتات الخاصة بـ content().

تعيين اللغة الافتراضية إلى “text” لن يكون حلاً لأننا نريد تمييزها (highlighted) ونريد الكشف التلقائي لسهولة الاستخدام (وهو يعمل…)

إليك مثال Markdown، حيث تفشل كتلة الكود الثانية (بالطبع فقط إذا كانت اللغة الافتراضية مضبوطة على “auto”). يمكن تكرار ذلك بسهولة باستخدام Markdown أدناه على https://try.discourse.org/

وخلال 24 ساعة: Failed Discourse Autodetection breaks rendering of fenced code blocks - support - Discourse Demo

# هذا يعمل

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

# هذا فشل وقام بتعيين "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 }}
```

ربما يكون الأمر ببساطة أن Discourse و HighlightJS لا يستطيعان التعرف على اللغة، مما يجعلها على هذا النحو.

هنا تكمن التركيز على Discourse و Highlight.JS

  • Highlight.JS وحده يتعرف على اللغة دائمًا ويختارها

  • في Discourse، بدون سمة lang، لا يتم التعرف على اللغة في وقت التشغيل دائمًا.

منتدى Hugo: المنشور 6 من الموضوع 57307:

إليك منشور من المنتدى: 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: المنشور 2 من الموضوع 57367:

وهنا حالة أخرى لا تعمل فيها: How to capture/generate revisions of page? - #2 by Welsh - support - HUGO

هنا أيضًا يتم تعيين “lang-auto”، لكن التعرف التلقائي في وقت التشغيل لا يعمل.

إذن، الأمر يتعلق بطريقة ما بتنفيذ Discourse - ربما يعتمد على المحتوى بسبب انتهاء المهلة، أو الوعود (promises) …

ربما أنا أفهم الأمر بشكل خاطئ، لكن هذا ما أراه في الرابط الأول الذي نشرته:

لا يظهر lang-auto في أي منهما، وكلاهما مظلل بنفس الطريقة، على الرغم من أنك لم تحدد لغة كتلة الكود للكتلة الثانية.

هذه وحدة تحكم المطور - فهي تعرض الكود بعد أن نجح highlight.js في الكشف التلقائي.

ستضطر إلى النظر إلى مصدر الصفحة (Ctrl+u) حيث سترى lang-auto

وهو ما سيؤدي بعد ذلك إلى تشغيل طريقة discourse في التظليل التلقائي عن طريق إزالة lang-auto ومحاولة التحقق مرة أخرى من المنشور الثاني الذي قمت بربطه، نفس الموقف لكن الفشل في الكشف.

ونعم - بدون إطار عمل discourse من حوله يعمل

عند الانتقال إلى استخدام Highlight.JS مباشرةً:

  • لن يتم تمييز الكود المحاط بـ <code class="lang-auto"> ما لم نمتلك قواعد لغوية (grammar) لـ “auto” :wink:

  • يمكننا إعادة تشغيل الكشف التلقائي لأولئك الذين يستخدمون إضافة (plugin):

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

لم أتمكن من جعل ذلك يعمل في Discourse بسبب طريقة دمج الإضافات وقواعد اللغة مع واجهة برمجة التطبيقات (API)، وبسبب عزل DOM لمحرك highlight.js وطرقه، وإذا كان من الممكن أن نواجه حالات سباق (race conditions) مع العرض الحي الافتراضي في Discourse

إعجاب واحد (1)