ترقية Mathjax إلى الإصدار 4

@sam وجميع المهتمين بكتابة الرياضيات في ديسكورس. لقد قمت بتحديث إضافة discourse-math بحيث تستخدم MathJax V3، بدلاً من V2 الأبطأ والقديم جدًا. وكما هو متوقع، فإن النتيجة هي تجربة مستخدم أسرع بكثير، مع الحفاظ على البيئة الغنية بالميزات مقارنة بـ KaTeX.

أود إصدار طلب سحب (pull request)، إذا كانت النتائج تبدو جيدة في رأيك.


يمكنك رؤيتها قيد العمل على موقع ديسكورس الخاص بفصلي:

معظم المحتوى على هذا الموقع خاص أو غير مدرج. يجب أن تكون هناك عدة مواضيع في الأعلى ضمن فئة MathJax V3 توضح الأفكار، على الرغم من ذلك

يمكنك فحص الكود الخاص بالإضافة في مستودع الإضافة المستقل discourse-mathjax هذا. الملف الذي يحتوي على أكبر قدر من التعديلات هو المُهيئ (initializer).

يمكنك أيضًا استخدام هذا المستودع لتثبيته على موقع مستقل الآن. فقط تأكد من إزالة المستودع القديم أثناء التثبيت. وبالتالي، ستقوم بتعديل تقنية التثبيت القياسية للإضافات لتبدو كالتالي:

  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - rm -r discourse-math
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/mcmcclur/discourse-math.git

تعليقات

أحدث إصدار من MathJax هو في الواقع 4.0.0. لقد اخترت استخدام V3.2.2 لعدة أسباب

  • في حين أن V4 أسرع بالتأكيد من V2، إلا أنه ليس بنفس سرعة V3.
  • تجربة المستخدم مختلفة قليلاً في V4، خاصة إذا نقر المستخدم على المخرجات.
  • حالة 4.0.0 تجعلني أتساءل عن عدد الأخطاء المحتملة.

ومع ذلك، فإن واجهة برمجة التطبيقات (API) لـ V4 مطابقة لتلك الخاصة بـ V3. يجب أن يكون من الممكن الترقية لاحقًا، عن طريق إدراج أحدث مستودع MathJax ببساطة.

اضطررت إلى إجراء تغيير صغير واحد في ملف locales/server.en.yml. بالطبع، هناك عدد كبير من هذه الملفات للغات مختلفة. فهمي هو أنه سيتم ترجمة تلك الملفات الأخرى تلقائيًا لاحقًا؟

أنا لا أستخدم الدردشة على الإطلاق ولم أختبرها في هذا السياق.

4 إعجابات

طلب سحب (Pull request) لترقية MathJax إلى الإصدار 3 تم تقديمه مع اجتياز جميع الاختبارات!

إعجابَين (2)

بخصوص:

هذا رائع :hugs: ، ولكني أتساءل عما إذا كان بإمكاننا استخدام هذا كفرصة لتقليص مستودعنا قليلاً.

الآن بعد أن نقلنا MathJax إلى النواة (core)، يمكننا الاعتماد على pnpm لسحب الحزمة وتجنب تجميع كل المصدر كما نفعل لـ FullCalendar على سبيل المثال.

الهدف تحديداً هو أن يكون لدينا فقط “روابط” في مستودعنا، وبعد ذلك يمكننا استخدام عملية البناء لسحب التبعيات الصحيحة.

أعطنا بضعة أيام، أريد التشاور مع فريق تجربة المطورين (dev xp team) هنا. شكراً جزيلاً لجهودك هنا!

4 إعجابات

نعم، أعتقد أن هذا هو الشيء الصحيح الذي يجب القيام به بالتأكيد. لطالما تساءلت لماذا تقوم بتجميع الحزمة بأكملها!

إذًا، أعتقد أنك ستقوم ببناء دالة loadMathJax لمكتبتك تُستخدم لتحميل MathJax؟

سأقول إن دمج جميع المكونات الإضافية (plugins) في النواة جعل التعامل معها أكثر صعوبة. ربط التبعيات بعملية البناء سيجعل الأمر أكثر صعوبة، على الرغم من أنني متأكد من أنه يمكنني سحب MathJax أو FullCalendar من شبكة توصيل المحتوى (CDN).

أنا أتحدث بشكل أساسي عن الوقت الذي أعبث فيه بالمكونات الإضافية لاستخدامها في منتدياتي الخاصة، وأعتقد تمامًا أنه يجب عليك سحب MathJax أثناء البناء.

بالتأكيد! لقد كنت أستخدم Discourse لسنوات وأنا سعيد للغاية لأنك تعتقد أن هذا رائع! :rocket:

3 إعجابات

نعم، بالضبط. مثال جيد لنسخه هو morphlex:

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

أتساءل عما إذا كنت قد تمكنت من مناقشة الأمر مع فريق تجربة المطورين لديك بعد؟ سأكون سعيدًا بالمساعدة، إذا استطعت. انطباعي، مع ذلك، هو أنه لا يوجد شيء يمكنني القيام به حقًا بدون ملاحظاتك حول ذلك.

لقد أجريت بعض التغييرات الإضافية في فرع منفصل، سأنشر عنها قريبًا. أنا أدرك أن لديك الكثير على طبقك، لذا لا أقصد أن أكون مصدر إزعاج!

لقد قمت بتعديل إضافة discourse-math بحيث يمكنها تحليل مدخلات رياضية أكثر بكثير.

@sam عندما ساهمت لأول مرة في هذه الإضافة في عام 2017، أتذكر أنك كنت حازمًا جدًا بشأن رغبتك في تحليل صارم للغاية. دعني أقول في البداية إن دافعي الرئيسي للاسترخاء وتوسيع التحليل كان لكي يعمل بشكل أفضل مع الذكاء الاصطناعي. على وجه الخصوص، عندما تتحدث عن الرياضيات مع روبوت ذكاء اصطناعي، ستجد غالبًا أنه يستجيب باستخدام LaTeX وهناك العديد من الطرق التي قد يختارها لتحديد مدخلات LaTeX هذه. لذا، في حين أنني أتفهم دافعك للتحليل الصارم، فإن التغييرات التي أجريتها ضرورية لهذا الاستخدام.

بالطبع، قد لا تزال لا تهتم بهذا الاستخدام، لذلك وضعت التغييرات في فرع منفصل عن طلب السحب الخاص بي للإصدار الثالث. إذا قررت أنك تحبها، فسأكون سعيدًا بتقديم طلب سحب آخر.

التغييرات المحددة على طلب السحب هي:

يقبل الرياضيات المضمنة المحددة بشرطة مائلة وقوسين مثل \(a^2+b^2=c^2\).

يقبل الرياضيات العرضية المحددة بعلامتي دولار في سطر واحد مثل
$$a^2+b^2=c^2.$$

يقبل الرياضيات العرضية المحددة بشرطة مائلة وقوسين مربعين في سطر واحد مثل
\[a^2+b^2=c^2.\]

يقبل الرياضيات العرضية المحددة بشرطة مائلة وقوسين مربعين متعددة الأسطر مثل
\[
a^2+b^2=c^2.
\]

بالطبع، لا يزال يقبل مدخلات الأصل:

الرياضيات المضمنة المحددة بعلامة دولار: $a^2+b^2=c^2$.

الرياضيات العرضية متعددة الأسطر المحددة بعلامتي دولار:
$$
a^2+b^2=c^2.
$$

يمكنك العثور على الفرع ذي الصلة هنا.

يوجد الكود أيضًا كإضافة قائمة بذاتها.

أوه، يمكنك أيضًا رؤيته قيد العمل!

إعجابَين (2)

@mcmcclur شكراً لعملك. سيكون من الرائع رؤية هذه الميزات في الإصدار الأساسي.

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

شكراً جزيلاً مارك.

العائق الكبير الذي أواجهه هنا هو أنني أرغب حقًا في الانتقال إلى الأنماط الجديدة لتوزيع التبعيات، انظر:

هل يمكنك إلقاء نظرة على هذا؟

فيما يتعلق بالصياغة المرنة، يبدو لي أنه إعداد للموقع، وربما يكون افتراضيًا نظرًا لجميع نماذج اللغة الكبيرة (LLMs) الموجودة حاليًا؟

3 إعجابات

@mcmcclur كنت أعبث بهذا اليوم:

بعيد عن الجاهزية … ولكن الأمور تعمل بشكل جيد مع 4.1 وهذا لطيف.

إعجابَين (2)

نعم، هذا بالتأكيد تقدم!
القضية الرئيسية الأولى التي يجب معالجتها، كما أظن أنك تعرف، هي أن الخطوط غير موجودة. في الواقع، عبثت بهذا السطر في discourse-math-mathjax.js:

fontURL: getURLWithCDN("/assets/mathjax/woff-v2"),

كاختبار، قمت بتعيين عنوان URL ليشير ببساطة إلى دليل مؤقت على خادم الويب الخاص بي، وبدت النتائج الأولية جيدة جدًا. لذا، إنها مسألة تثبيت تلك الخطوط بشكل صحيح في Discourse.
في مشروع pnpm بسيط على جهازي، يقوم الأمر التالي بتثبيت الخطوط:

pnpm install @mathjax/mathjax-newcm-font@4

عندما أقوم بتشغيل هذا الأمر داخل discourse/frontend/discourse، تظهر الخطوط في

/discourse/frontend/discourse/npm_modules/@mathjax/mathjax-newcm-font/chtml/woff2/

ومع ذلك، لا يبدو أن تلك الخطوط تصل إلى /assets/mathjax/woff-v2 بعد البناء. لقد جربت عددًا من المتغيرات على الدليل ولكن لم أتمكن من جعله يعمل. أفترض أن هذا نوع من سحر التوجيه الذي لست خبيرًا فيه. أنا متأكد من أنه يمكنني إحراز تقدم جيد نحو تنظيفه، بمجرد تسوية مشكلة المسار تلك.

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

@sam أعتقد أنني أحرزت تقدمًا كبيرًا في هذا الشأن، مع وجود محاذير مهمة واحدة. لست متأكدًا من أين يجب تحميل المكونات المطلوبة. معبرًا عنها في الكود،

window.MathJax = {
    loader: {
      // هذا لا يعمل:
      // paths: { mathjax: getURLWithCDN("/assets/mathjax") },
      // ولكن هذا يعمل بشكل رائع:
      paths: { mathjax: "https://cdn.jsdelivr.net/npm/mathjax@4.1.0" },
      load: ["core", "input/tex", "input/mml", "output/chtml", "output/svg"],
    },
    // المزيد من الإعدادات ...
  };

عندما أقول إن الإصدار المعلق لا يعمل، أعني أنني أحصل على الرسالة الصريحة:
MathJax(core): لا يمكن تحميل “/assets/mathjax/core.js”

لاحظ أنه في كلتا الحالتين، تقوم الدالة loadMathJax بسحب بدء تشغيل MathJax من النسخة المحلية. أي أن لدي ما يلي في
/discourse/frontend/discourse/app/static/mathjax-bundle.js

export * from "mathjax/startup.js";

ثم، loadMathJax المعرفة في
/discourse/frontend/discourse/app/lib/load-mathjax.js
تستدعي

const bundle = await import("discourse/static/mathjax-bundle");

هذا يشير إلى احتمالين:

  1. ربما /assets/mathjax ليس الموقع الصحيح أو
  2. ربما تحتاج هذه الأصول إلى التسجيل بطريقة ما حتى تظهر في التوزيع؟

بالاعتماد على نسخة شبكة توصيل المحتوى (CDN)، يبدو أنه يمكنني إحراز تقدم كبير، ولكني أفترض أن هذا يمثل عائقًا كبيرًا بالنسبة لك.

يمكنني مشاركة الكود الخاص بي معك، إذا أردت، ولكن ربما تكون هذه معلومات كافية للتشخيص؟

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

بالتأكيد، الكود سيكون مفيدًا جدًا هنا، ربما قم بعمل تفرع (fork) لـ discourse ثم ادفع تغييراتك إلى فرع (branch)، وبعد ذلك يمكنني سحب التغييرات من فرعك إلى طلب السحب (PR).

سعيد جدًا لأنك تحقق تقدمًا، وأحاول تشخيص هذه المشكلة.

هل يمكنك أيضًا سحب آخر التحديثات (pull latest)، لقد قمت بجولة من التنظيف.

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

حسنًا، إليك الكود:

لكن احذر، لم أعمل مباشرة من آخر تثبيت (commit) لك. لقد بدأت مباشرة من Discourse main وأجريت التغييرات من هناك. وبالتالي، تعلمت قدرًا لا بأس به من عملك ولكن الهيكل العام مختلف.

أعتقد أنه يمكنك تلخيص الاختلاف الرئيسي على النحو التالي: حيث تستخدم (بشكل طبيعي) ميزات Discourse الموروثة من Ember لتنسيق التوقيتات المرتبطة بأشياء مثل التحميل والتنسيق، أنا أستخدم ميزات MathJax. وبالتالي، فإن حزم load-mathjax و mathjax الخاصة بي (واحدة لـ svg والأخرى لـ chtml) أبسط بكثير من حزمك. يتم تنسيق التحميل بالكامل عبر الكائن window.MathJax في discourse-math-mathjax.

ما زلت أواجه نفس المشكلة التي وصفتها سابقًا، وهي أن هذا المُحمّل المعطّل لا يعمل؛ يجب عليّ استخدام إصدار CDN هذا بدلاً من ذلك. أنا حقًا لا أعرف السبب.

أعتقد أن الكود الخاص بك يعاني من نفس المشكلة. لهذا السبب لا يبدو أن AsciiMath يعمل.

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

هل يمكنك التحقق مرة أخرى من آخر تثبيت (commit) لي، أعتقد أنني أضفت قمعًا (funnel) لـ ember، لذا فإن بناء ember يضع جميع الملفات في المكان الصحيح الآن.

إعجابَين (2)

حسنًا، لدي أخبار جيدة جدًا وأخبار محبطة.

أولاً، أنت على حق تمامًا في أن إضافة القمع يضع تلك الملفات في المكان الصحيح. لقد أضفت القمع إلى الفرع الخاص بي وهو يعمل الآن بشكل رائع دون الاعتماد على شبكة توصيل المحتوى (CDN). :tada:

لسوء الحظ، لا يمكنني تشغيل الكود الخاص بك في الوقت الحالي. كلما انتقلت إلى صفحة تحتوي على معادلات رياضية، لا يتم تنسيق المعادلات وأرى رسالة الخطأ التالية في وحدة التحكم (console):
Uncaught (in promise) Error: State EXPLORER already exists

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

git clone https://github.com/discourse/discourse.git ./discourse
cd ./discourse
bundle install
pnpm install
bundle exec rake db:create
bundle exec rake db:migrate
RAILS_ENV=test bundle exec rake db:create db:migrate

# في طرفية واحدة
bundle exec rails server

# في طرفية أخرى
bin/ember-cli

ثم التقطت الكود الخاص بك باستخدام

git checkout 71ad0305f812311f2a4570edf7c33f97de46c457
git switch -c mathjax-sam

حتى من هذا الإعداد الجديد، أحصل على الخطأ.


في هذه المرحلة، أنا سعيد جدًا بنسختي من الكود ولكني ما زلت أتساءل عما يحدث مع نسختك. أحتاج إلى أخذ استراحة من هذا الأمر بسبب العطلة، على الرغم من ذلك. يسعدني إلقاء نظرة أخرى عليه في غضون أيام قليلة.

نقطة أخيرة، مع ذلك: على حد علمي،

await import("tex-mml-chtml.js") // يليه
await import("input/asciimath.js")

لا ينبغي أن يعمل، وهو ما يفعله الكود الخاص بك بشكل فعال، على ما أعتقد.

أنا غير دقيق بشأن المسارات هناك ولكن قصدي هو أنني لست متأكدًا مما إذا كانت الاستدعاءات الديناميكية المتتالية لـ import تؤدي إلى بنية MathJax الصحيحة. أعتقد أن تحميل مكونات MathJax معقد للغاية ولهذا السبب لديهم عملية تحميل مفصلة للغاية مع كائن MathJax وكل شيء.

شكرًا جزيلاً على مساعدتك وصبرك @sam!

إعجابَين (2)

لقد أحرزت تقدماً هنا:

لقد نقلت حمولات جافاسكريبت (javascript) الضخمة إلى حزمة (gem) مخصصة

سيجعل هذا من السهل جداً البقاء على اطلاع دائم، بالإضافة إلى أن MathJax لم يعد مدققاً في المستودع (repo).

3 إعجابات

مرحباً سام - كنت ألعب بهذا كثيراً اليوم. يبدو رائعاً! أعتقد أنه لا يزال هناك الكثير مما يجب القيام به، مع ذلك. بعضه، يمكنني بالتأكيد المساعدة فيه. بعضه ربما يتجاوز قدرتي، خاصة مع بدء جامعتي العمل مرة أخرى.

على أي حال، إليك بعض أفكاري.

التكبير (Zoom)

لم يعد التكبير عند التمرير (Zoom on hover) متاحاً في MathJax V4. ومع ذلك، من السهل ضبطه للتكبير عند الضغط على مفتاح alt. لقد قمت بذلك هنا:

لاحظ أن هناك خطأ معروفاً في MathJax يحتاج إلى معالجة ببعض CSS، كما هو موضح في مسألة GitHub هذه. لقد قمت بتضمين هذا الإصلاح في هذا الكود أيضاً.

خيارات التحميل (Loading options)

كما هو الحال الآن، لا يمكن تشغيل AsciiMath ولا يمكن إيقاف تشغيل إمكانية الوصول (Accessibility). أعتقد أن هذا يرجع إلى الطريقة التي يتم بها تحميل الوحدات الفرعية بالتسلسل في load-mathjax.js.

كما ذكرت في رسالتي الأخيرة، من الشائع جداً تحديد كائن window.MathJax مسبقاً يحدد المكونات التي تريدها. يتم إعادة تعريف كائن MathJax عند تحميل البرنامج النصي الرئيسي. هذه هي الطريقة التي تمكنت بها من جعل هذا يعمل في إصداري V3. أعتقد أنه يمكنني دمج هذا النهج في قاعدة الكود الخاصة بك خلال الجزء الأول من الأسبوع المقبل، إذا كنت ترغب في أن أحاول؟

بمجرد أن ننتهي من تحديد الخيارات، قد يكون من المفيد أيضاً النظر فيما إذا كانت هناك خيارات جديدة متاحة في V4 يجب تضمينها.

المحرر الغني (The rich editor)

هذا رائع فحسب - أنا سعيد جداً لرؤيته!

أتساءل عما إذا كان من الممكن الحصول على قائمة سياق ذكاء اصطناعي لامعة متاحة داخل النافذة المنبثقة؟ أسأل لأن الطلاب (والأساتذة :confused:) يواجهون أحياناً صعوبة في كتابة LaTeX. يمكن لمدقق لغوي صغير يعمل بالذكاء الاصطناعي أن يجعل ذلك أكثر سلاسة. لقد قمت بدمج ذلك في منصة Discourse الخاصة بفصلي الدراسي وأتطلع إلى استخدامه في الفصل الدراسي القادم.


حسناً، أنا متأكد من أن هناك الكثير، لكنني انتهيت لهذا اليوم.

شكراً جزيلاً!!! :rocket: :fire: :tada:

3 إعجابات

أتفهم أن المكون الإضافي discourse-math يعتمد على حزمة أصول MathJax/KaTeX المنفصلة بدلاً من دمج تلك المكتبات مباشرة، مما يحافظ على خفة وزن المكون الإضافي ويسمح بتحديث مكتبات الرياضيات بشكل مستقل.

أود المساعدة في التحقق من ذلك قبل الإصدار الإنتاجي الأول من خلال إجراء بعض الاختبارات الواقعية. كانت فكرتي الأولية هي إعداد مثيل منفصل وقابل للتصرف وتمكين المكون الإضافي هناك لاختبار المحتوى الغني بالرياضيات، وتحميل الأصول عبر المسار القياسي، وسلوك سياسة أمان المحتوى (CSP)، والأداء.

قبل القيام بذلك، أردت أن أسأل ما هي البيئة الموصى بها في هذه المرحلة - سواء كان الاختبار المبكر في إعداد يشبه الإنتاج مناسبًا، أو ما إذا كنتم تفضلون أن يتم ذلك باستخدام بيئة تطوير حتى الإصدار الإنتاجي الأول.

أنا سعيد جدًا بالاختبار بأي طريقة تكون أكثر فائدة وتقديم تقارير عن أي مشكلات أو حالات حافة أواجهها. لا يمكنني الالتزام بجدول اختبار ثابت بسبب التزاماتي الجامعية، ولكني سعيد ببذل قصارى جهدي للاختبار عندما يسمح الوقت، ومن المرجح أن يكون لديّ توافر أكبر بكثير بعد 6 يونيو.

لقد أصبحت الخيارات تعمل جيدًا الآن؛ يمكنك رؤية الشفرة هنا:

إليك بعض التعليقات:

  • تتم معالجة جميع الإعدادات والتحميل بواسطة الكائن MathJaxInitConfig المعرّف في math-renderer.js.
  • أزلت قدرًا لا بأس به من الشفرة الخاملة من load-mathjax.js.
  • يتم تحميل الامتداد ‘ui/safe’ دائمًا.
  • أضفت خيار “قائمة تمكين الرياضيات في Discourse”، وهو صحيح افتراضيًا. عندما يكون خطأ، فإن هذا يزيل القائمة تمامًا، مما يجعل MathJax أسرع.
  • العنصران التاليان في القائمة هما
    • تكبير رياضيات Discourse عند النقر و
    • تمكين إمكانية الوصول للرياضيات في Discourse.
      ليس لهما أي تأثير إذا كانت القائمة معطلة ولكنهما مستقلان عن بعضهما البعض عند تمكينها.

تبدو القائمة بأكملها كالتالي:

لم أضف أي اختبارات بعد ولكن يمكنني المحاولة، إذا كنت ترغب في طلب سحب (pull request).