Math should be quotable

تمت ترقية Discourse Math بشكل كبير في يناير 2026 إلى إصدار جديد مدمج رسميًا في النواة، مع MathJax 4.1 كإعداد افتراضي و KaTeX كبديل. تشير وثائق المكون الإضافي أيضًا إلى أن KaTeX يتضمن امتداد CopyTex لنسخ مصدر LaTeX.

هل سيكون من المفيد إضافة تصحيح صغير لمكون الثيم (theme-component patch) يحسن تحديد الاقتباسات للمشاركات التي تحتوي على الكثير من المعادلات الرياضية؟

بالنسبة للمواقع التي تعتمد بشكل كبير على MathJax مثل Physics with Ethan، فإن الفكرة الأكثر عملية هي:

  1. اعتراض HTML المحدد قبل أن يقوم Discourse بتحويله مرة أخرى إلى Markdown،
  2. العثور على عناصر تغليف المعادلات الرياضية،
  3. استبدالها بمصدر TeX الأصلي ملفوفًا بـ $...$ أو $$...$$،
  4. ثم السماح لـ Discourse بمتابعة بناء الاقتباس.

إليك برنامج نصي محتمل لمكون الثيم سأبدأ به، إذا كان من المفيد تعديل منطقة < /head> أو منطقة JavaScript في ثيم Horizon (أو الافتراضي).


<script type="text/discourse-plugin" version="1.0">
  apiInitializer("1.34.0", (api) => {
    function texFromMathElement(el) {
      // MathJax v3/v4 يخزن المصدر عادةً في عنصر ابن للتعليق التوضيحي (annotation).
      const annotation =
        el.querySelector('annotation[encoding="application/x-tex"]') ||
        el.querySelector('annotation');

      if (annotation?.textContent?.trim()) {
        const tex = annotation.textContent.trim();

        // الاستدلال: غالبًا ما تكون حاويات المعادلات الكتلية (block math wrappers) حاويات عرض.
        const isBlock =
          el.tagName === "MJX-CONTAINER" &&
          (el.getAttribute("display") === "true" ||
            el.getAttribute("display") === "block");

        return isBlock ? `$$\n${tex}\n$$` : `$${tex}$`;
      }

      return null;
    }

    function patchMathInFragment(fragment) {
      const candidates = fragment.querySelectorAll(
        "mjx-container, .math, .katex, .MathJax"
      );

      candidates.forEach((node) => {
        const replacement = texFromMathElement(node);
        if (!replacement) {
          return;
        }

        const textNode = document.createTextNode(replacement);
        node.replaceWith(textNode);
      });

      return fragment;
    }

    api.modifyClass("component:quote-button", {
      pluginId: "ethan-math-quote-fix",

      _selectionChanged() {
        this._super(...arguments);

        try {
          const selection = window.getSelection();
          if (!selection || selection.rangeCount === 0) {
            return;
          }

          const range = selection.getRangeAt(0);
          const fragment = range.cloneContents();
          patchMathInFragment(fragment);

          const container = document.createElement("div");
          container.appendChild(fragment);

          // استبدال المخزن المؤقت الذي يقوم Discourse لاحقًا بتحويله إلى علامات اقتباس markdown.
          if (this.quoteState) {
            this.quoteState.buffer = container.innerHTML;
          }
        } catch (e) {
          // الفشل بهدوء حتى يستمر الاقتباس العادي في العمل.
          console.warn("فشل تصحيح اقتباس المعادلة:", e);
        }
      },
    });
  });
</script>

بعض التحذيرات الهامة:

  • هذا تصحيح عملي، وليس شيئًا وجدته منشورًا بالفعل من قبل Meta. الاستراتيجية الأساسية مستنتجة من مسار الاقتباس الذي يمر عبر HTML المحدد وإلى toMarkdown.
  • من المرجح أن يكون مفيدًا عندما أستخدم موفر MathJax، وهو الإعداد الافتراضي الحالي في Discourse Math، والخيار الذي أستخدمه عادةً.
  • قد يحتاج البرنامج النصي إلى تعديلات صغيرة في المحددات اعتمادًا على ما إذا كانت المعادلة المعروضة ستنتهي كـ mjx-container أو .MathJax أو غلاف آخر. سأقوم بالاختبار على موقع تجريبي، والذي سيكون تثبيتًا قياسيًا جديدًا.
  • من غير المرجح أن يكون مثاليًا لكل حالة حافة، خاصةً التحديدات المختلطة داخل السطر/الكتلة أو المواد المقتبسة المتداخلة.

نظرًا لأن Discourse يدعم الآن رسميًا KaTeX مع CopyTex، هناك مسار آخر وهو التبديل إلى الموفر إذا كانت نقطة الألم الرئيسية لدي هي نسخ مصدر LaTeX بدلاً من دقة العرض. هذا لن يحل تلقائيًا تحديد الاقتباس، ولكنه يعني أن المعادلة المعروضة لديها بالفعل مسار أكثر ملاءمة للنسخ مدمج فيها.

بالنسبة لـ Physics with Ethan، ستكون توصيتي:

  • الاحتفاظ بـ MathJax إذا كنت تقدر التوافق والعرض الغني،
  • إضافة تصحيح صغير لتحديد الاقتباس مثل التصحيح أعلاه،
  • ومعاملته كحل محلي لتحسين جودة الحياة حتى تحصل Meta على حل مناسب في المنبع. حقيقة أن موضوع الميزة لعام 2020 لا يزال مفتوحًا في عام 2026 تشير إلى أن الحل في المنبع قد يظل بطيئًا هنا.

بالنسبة لموقعي الذي يعتمد بشكل كبير على MathJax، Physics with Ethan، أفكر حاليًا في:

  • الاحتفاظ بـ MathJax ما لم يقترح شخص ما أن أتحول إلى KaTeX؟،
  • ربما إضافة تصحيح لتحديد الاقتباس إلى ثيم Horizon، من الأعلى (باستخدام موقع تجريبي).
  • ومعاملته كحل محلي لتحسين جودة الحياة حتى يكون هناك حل مناسب في المنبع. حقيقة أن موضوع الميزة لعام 2020 لا يزال مفتوحًا في عام 2026 تشير إلى أن الحل في المنبع قد يظل بطيئًا هنا.
إعجابَين (2)