Aggiornamento di Mathjax alla versione 4

@sam および、Discourse で数式を入力することに関心のあるすべての方へ。discourse-math プラグインを更新し、はるかに遅く時代遅れの V2 ではなく MathJax V3 を使用するようにしました。ご想像の通り、その結果、KaTeX と比較して機能豊富な環境を維持しながら、はるかに軽快なユーザーエクスペリエンスが得られました。

もし結果が良ければ、プルリクエストを発行したいと思います。


私のクラスの Discourse サイトで実際に動作しているのを見ることができます。

そのサイトのコンテンツのほとんどは非公開または限定公開です。アイデアを示すために、MathJax V3 カテゴリの先頭にいくつかのトピックがあるはずですが、

プラグインのコードはこのスタンドアロンの discourse-mathjax プラグインリポジトリで確認できます。最も多くの変更が加えられているファイルはinitializerです。

また、そのリポジトリを使用して、すぐにスタンドアロンサイトにインストールすることもできます。インストール時には、古いリポジトリを削除するようにしてください。したがって、標準のプラグインインストール手順を次のように変更する必要があります。

hooks:
  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 というステータスは、バグがどれくらいあるのか疑問に思わせます。

とはいえ、V4 の API は V3 と同一です。後で最新の MathJax リポジトリをドロップインするだけでアップグレードできるはずです。

locales/server.en.yml ファイルで 1 つの小さな変更を加える必要がありました。もちろん、さまざまな言語に対応するファイルは他にもたくさんあります。私の理解では、これらの他のファイルは後で自動的に翻訳されるということでしょうか?

チャットはまったく利用しておらず、そのコンテキストではテストしていません。

4 Mi Piace

Pull request per l’aggiornamento di MathJax alla V3 effettuato con tutti i test superati!

2 Mi Piace

Riguardo a:

Questo è fantastico :hugs: , ma mi chiedo se possiamo cogliere questa opportunità per snellire un po’ il nostro repository.

Ora che abbiamo spostato MathJax nel core, possiamo fare affidamento su pnpm per scaricare il pacchetto ed evitare di includere tutto il codice sorgente come facciamo per FullCalendar, ad esempio.

In particolare, l’obiettivo è avere solo dei “link” nel nostro repository e poi possiamo usare il processo di build per scaricare le dipendenze corrette.

Dacci qualche giorno, voglio consultare il team di esperienza di sviluppo qui. Grazie mille per i tuoi sforzi!

4 Mi Piace

Sì, penso che sia certamente la cosa giusta da fare. Mi sono sempre chiesto perché includessi l’intero pacchetto!

Quindi, immagino che creerai una funzione loadMathJax per la tua libreria che viene utilizzata per caricare MathJax?

Devo dire che includere tutti i plugin nel core ha reso un po’ più complicato giocarci. Legare le dipendenze al processo di build lo renderebbe ancora più difficile, anche se sono sicuro che potrei scaricare MathJax o FullCalendar da una CDN.

Sto parlando principalmente di quando armeggio con i plugin da usare nei miei forum, e penso assolutamente che dovresti includere MathJax durante la build.

Assolutamente! Uso Discourse da anni e sono felicissimo che tu pensi che questo sia fantastico! :rocket:

3 Mi Piace

Sì, esattamente. Un buon esempio da copiare è morphlex:

1 Mi Piace

Mi chiedo se tu sia riuscito a discutere con i tuoi colleghi dell’esperienza degli sviluppatori. Sarei felice di aiutare, se posso. La mia impressione, tuttavia, è che non ci sia davvero nulla che io possa fare senza il tuo feedback a riguardo.

Ho apportato alcune modifiche aggiuntive in un branch separato, di cui parlerò presto. Sono consapevole che hai molto da fare, quindi non intendo disturbarti!

Ho modificato il plugin discourse-math in modo che possa analizzare un input matematico molto più ampio.

@sam Quando ho contribuito per la prima volta a questo plugin nel 2017, ricordo che eri piuttosto fermo nel volere un’analisi molto rigorosa. Lascia che dica subito che la mia motivazione principale per allentare ed estendere l’analisi è stata quella di farla funzionare meglio con l’IA. In particolare, quando si discute di matematica con un bot IA, si scopre spesso che risponde usando LaTeX e ci sono molti modi in cui potrebbe scegliere di delimitare quell’input LaTeX. Quindi, sebbene io comprenda la tua motivazione per un’analisi rigorosa, le modifiche che ho apportato sono piuttosto essenziali per tale caso d’uso.

Naturalmente, potresti ancora non preoccuparti di quel caso d’uso, quindi ho inserito le modifiche in un branch separato dalla mia pull request V3. Se decidi che ti piacciono, sono felice di emettere un’altra pull request.

Le modifiche specifiche per la pull request sono:

Accetta la matematica inline delimitata da barra-parentesi come \\(a^2+b^2=c^2\\).

Accetta la matematica display delimitata da doppio dollaro su riga singola come
$$a^2+b^2=c^2.$$

Accetta la matematica display delimitata da barra-parentesi quadra su riga singola come
\\[a^2+b^2=c^2.\\]

Accetta la matematica display delimitata da barra-parentesi quadra su più righe come
\\[
a^2+b^2=c^2.
\\]

Naturalmente, accetta ancora gli input dell'originale:

Matematica inline delimitata da dollaro: $a^2+b^2=c^2$.

Matematica display delimitata da doppio dollaro su più righe:
$$
a^2+b^2=c^2.
$$

Puoi trovare il branch pertinente qui.

Il codice esiste anche come plugin autonomo.

Oh, puoi anche vederlo in azione!

2 Mi Piace

@mcmcclur Grazie per il tuo lavoro. Sarebbe fantastico vedere queste funzionalità nel core.

1 Mi Piace

Grazie mille Mark.

Il mio grande ostacolo qui è che voglio davvero passare ai nuovi modelli per la distribuzione delle dipendenze, vedi:

Potresti dare un’occhiata a questo?

Per quanto riguarda la sintassi rilassata, mi sembra un’impostazione del sito, forse anche predefinita visti tutti gli LLM disponibili?

3 Mi Piace

@mcmcclur Stavo giocherellando con questo oggi:

Lontano dall’essere pronto… ma le cose si avviano in qualche modo con la 4.1, il che è carino.

2 Mi Piace

Sì, questo è decisamente un progresso!
Il primo problema chiave da affrontare, come immagino tu sappia, è che i font non vengono trovati. Infatti, ho giocherellato con questa riga in discourse-math-mathjax.js:

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

Come test, ho impostato l’URL in modo che puntasse semplicemente a una directory temporanea sul mio server web, e i risultati iniziali sembrano molto buoni. Quindi, è una questione di installare correttamente quei font in Discourse.
In un semplice progetto pnpm sulla mia macchina, il seguente comando installa i font:

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

Quando eseguo quel comando all’interno di discourse/frontend/discourse, i font appaiono in

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

Tuttavia, quei font non sembrano finire in /assets/mathjax/woff-v2 dopo la build. Ho provato diverse varianti della directory ma non sono riuscito a farlo funzionare. Presumo che si tratti di una sorta di magia di routing di cui non sono un esperto. Sono abbastanza sicuro di poter fare buoni progressi verso la pulizia, una volta risolto quel problema del percorso.

1 Mi Piace

@sam Penso di aver fatto progressi piuttosto significativi su questo, con un’importante avvertenza. Non sono sicuro da dove caricare i componenti desiderati. Espresso in codice,

window.MathJax = {
    loader: {
      // Questo non funziona:
      // paths: { mathjax: getURLWithCDN("/assets/mathjax") },
      // Ma questo funziona benissimo:
      paths: { mathjax: "https://cdn.jsdelivr.net/npm/mathjax@4.1.0" },
      load: ["core", "input/tex", "input/mml", "output/chtml", "output/svg"],
    },
    // Altre configurazioni ...
  };

Quando dico che la versione commentata non funziona, intendo che ricevo il messaggio esplicito:
MathJax(core): Impossibile caricare “/assets/mathjax/core.js”

Nota che, in entrambi i casi, la funzione loadMathJax sta caricando l’avvio di MathJax dalla copia locale. Cioè, ho quanto segue in
/discourse/frontend/discourse/app/static/mathjax-bundle.js

export * from "mathjax/startup.js";

Quindi, loadMathJax definito in
/discourse/frontend/discourse/app/lib/load-mathjax.js
chiama

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

Questo suggerisce un paio di possibilità:

  1. Forse /assets/mathjax non è la posizione corretta o
  2. Forse questi asset devono essere registrati in qualche modo in modo che appaiano nella distribuzione (dist)?

Basandomi sulla versione CDN, sembra che io possa fare progressi significativi, ma presumo che questo sia un blocco importante per te.

Potrei condividere il mio codice con te, se vuoi, ma forse queste sono informazioni sufficienti per una diagnosi?

1 Mi Piace

Assolutamente, il codice sarà molto utile qui, forse puoi fare un fork di Discourse e poi inviare le tue modifiche a un branch, così potrò scaricare le modifiche dal tuo branch nella PR.

Sono così felice che tu stia facendo progressi nel cercare di diagnosticare questo problema.

Puoi anche fare un pull dell’ultima versione, ho fatto un giro di pulizia.

1 Mi Piace

OK, ecco il codice:

Attenzione, però, non ho lavorato direttamente dal tuo ultimo commit. Sono partito direttamente dal main di Discourse e ho apportato modifiche da lì. Quindi, ho imparato parecchio dal tuo lavoro ma la struttura generale è diversa.

Penso che la differenza principale possa essere riassunta così: dove tu (naturalmente) usi le funzionalità di Discourse ereditate da Ember per coordinare i tempi associati a cose come il caricamento e la tipografia, io uso le funzionalità di MathJax. Quindi, i miei bundle load-mathjax e mathjax (uno per svg e uno per chtml) sono molto più semplici dei tuoi. Il caricamento è tutto coordinato tramite l’oggetto window.MathJax in discourse-math-mathjax.

Ho ancora lo stesso problema che ho descritto prima, ovvero che questo loader commentato non funziona; devo usare questa versione CDN invece. Non so davvero perché.

Penso che il tuo codice soffra dello stesso problema. Ecco perché AsciiMath non sembra funzionare.

1 Mi Piace

puoi ricontrollare il mio ultimo commit, penso di aver aggiunto un funnel per ember, quindi ora la build di ember mette tutti i file nel posto giusto.

2 Mi Piace

OK, ho delle ottime notizie e delle notizie frustranti.

Innanzitutto, hai assolutamente ragione sul fatto che l’aggiunta del funnel posiziona quei file nel posto giusto. Ho aggiunto il funnel al mio branch e ora funziona benissimo senza la dipendenza dal CDN. :tada:

Sfortunatamente, al momento non riesco a eseguire il tuo codice. Ogni volta che navigo su una pagina con della matematica, la matematica non viene renderizzata e vedo il seguente messaggio di errore nella console:
Uncaught (in promise) Error: State EXPLORER already exists

Sono sicuro di aver fatto funzionare il tuo codice prima, quindi suppongo sia qualcosa che ho fatto io. Per essere chiari, ho letteralmente iniziato una directory completamente nuova usando le tecniche descritte in Install Discourse on macOS for development.

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

# In un terminale
bundle exec rails server

# In un altro terminale
bin/ember-cli

Poi ho preso il tuo codice con

git checkout 71ad0305f812311f2a4570edf7c33f97de46c457
git switch -c mathjax-sam

Anche da questa configurazione fresca, ottengo l’errore.


A questo punto, sono abbastanza soddisfatto della mia versione del codice ma ancora curioso di sapere cosa sta succedendo con la tua. Devo prendermi una pausa da questo per le vacanze, però. Sarò felice di dare un’altra occhiata tra qualche giorno.

Un ultimo punto, però: per quanto ne so,

await import("tex-mml-chtml.js") // seguito da
await import("input/asciimath.js")

non dovrebbe funzionare, che è di fatto quello che il tuo codice sta facendo, credo.

Sono impreciso con i percorsi lì, ma il mio punto è che non so che chiamate dinamiche consecutive a import portino alla corretta struttura di MathJax. Penso che caricare i componenti di MathJax sia piuttosto complicato ed è per questo che hanno un processo di caricamento così dettagliato con l’oggetto MathJax e tutto il resto.

Grazie mille per il tuo aiuto e la tua pazienza @sam!

2 Mi Piace

Ho fatto progressi qui:

Ho spostato i payload javascript giganti in una gem dedicata

Questo renderà significativamente più facile rimanere aggiornati, inoltre mathjax non è più controllato nel repository.

3 Mi Piace

Ciao Sam, ho giocato molto con questo oggi. Sembra fantastico! Penso però che ci sia ancora parecchio da fare. Su alcune cose posso sicuramente dare una mano. Altre potrebbero essere oltre le mie capacità, specialmente con l’inizio dell’università.

Comunque, ecco alcune delle mie riflessioni.

Zoom

Lo zoom al passaggio del mouse non è più disponibile in MathJax V4. È facile impostarlo per lo zoom con alt-click, però. L’ho fatto qui:

Nota che c’è un bug noto di MathJax che deve essere risolto con un po’ di CSS, come descritto in questa Issue di GitHub. Ho incluso quella correzione anche in questo codice.

Opzioni di caricamento

Allo stato attuale, AsciiMath non può essere attivato e l’Accessibilità non può essere disattivata. Penso che ciò sia dovuto al modo in cui i sottomoduli vengono caricati sequenzialmente in load-mathjax.js.

Come ho affermato nel mio ultimo messaggio, è molto più comune predefinire un oggetto window.MathJax che specifichi quali componenti si desiderano. L’oggetto MathJax viene ridefinito quando viene caricato lo script principale. È così che sono riuscito a farlo funzionare nella mia versione V3. Penso di poter incorporare quell’approccio nella tua base di codice durante la prima parte della prossima settimana, se vuoi che ci provi?

Una volta risolte le opzioni, potrebbe anche valere la pena considerare se ci sono nuove opzioni disponibili in V4 che dovrebbero essere incluse.

L’editor ricco

Questo è semplicemente fantastico - sono super felice di vederlo!

Mi chiedo se sarebbe possibile avere un menu contestuale AI scintillante disponibile all’interno della finestra modale? Lo chiedo perché gli studenti (e i professori :confused:) a volte hanno difficoltà a digitare LaTeX. Un piccolo correttore automatico AI può rendere il tutto molto più fluido. L’ho incorporato nel mio Discourse per le lezioni e non vedo l’ora di usarlo questo semestre.


OK, sono sicuro che c’è molto altro, ma per oggi ho finito.

Grazie mille!!! :rocket: :fire: :tada:

3 Mi Piace

Capisco che il plugin discourse-math si basi sulla gemma di asset MathJax/KaTeX separata anziché includere direttamente tali librerie, il che mantiene il plugin leggero e consente l’aggiornamento indipendente delle librerie matematiche.

Vorrei aiutare a convalidare questo prima del primo rilascio in produzione eseguendo alcuni test nel mondo reale. La mia idea iniziale era di avviare un’istanza separata e usa e getta e di abilitare il plugin lì per testare contenuti ricchi di matematica, il caricamento degli asset tramite la pipeline standard, il comportamento CSP e le prestazioni.

Prima di farlo, volevo chiedere quale sia l’ambiente consigliato in questa fase: se un test anticipato in una configurazione simile alla produzione sia appropriato, o se preferite che ciò venga fatto utilizzando un ambiente di sviluppo fino al primo rilascio in produzione.

Sono molto felice di testare nel modo più utile e di segnalare eventuali problemi o casi limite che dovessi incontrare a monte. Non posso impegnarmi in un programma di test fisso a causa degli impegni universitari, ma sono felice di fare test al meglio delle mie possibilità quando il tempo lo consente, e probabilmente avrò molta più disponibilità dopo il 6 giugno.

Le opzioni ora funzionano bene; puoi vedere il codice qui:

Ecco alcuni commenti:

  • Tutta la configurazione e il caricamento sono gestiti dall’oggetto MathJaxInitConfig definito in math-renderer.js.
  • Ho rimosso una discreta quantità di codice inerte da load-mathjax.js.
  • L’estensione ‘ui/safe’ è caricata sempre.
  • Ho aggiunto un’opzione “Discourse math enable menu”, che è vera per impostazione predefinita. Quando è falsa, questo rimuove completamente il menu, rendendo MathJax ancora più veloce.
  • Le prossime due voci di menu sono
    • Discourse math zoom on click (Zoom di MathJax al clic) e
    • Discourse math enable accessibility (Abilita accessibilità di MathJax).
      Queste non hanno effetto se il menu è disabilitato, ma sono indipendenti l’una dall’altra quando è abilitato.

L’intero menu appare così:

Non ho ancora aggiunto test, ma potrei provarci, se desideri una pull request.