Mathjax Server Docker-ized version

Mathjax Server Docker-ized version

Gennaio 30, 2022 Off Di Bibliomike

Ciao a tutti oggi testeremo a scopo divulgativo un Server MathJax e creeremo un semplice client web per inoltrare le richieste al server.

MathJax è una libreria opensource sviluppata in JavaScript che permette di visualizzare sui moderni browser formule matematiche scritte in notazione LaTeX, MathML o AsciiMath.

  • Un semplice esempio di come aggiungere le funzionalità di Mathjax ad una pagina html potete trovarlo a questo link https://jsbin.com/?html,output. Come vedrete nell’esempio illustrato, gli snippet inseriti direttamente all’interno dei tag  <head></head> della pagina aggiungono al browser la funzionalità di interpretare correttamente le notazioni matematiche.
  • L’alternativa lato server prevede invece l’utilizzo di MathJax sul motore di runtime Node.js. In questo caso il server in ascolto su una determinata porta riceve per esempio una stringa di testo in formato JSON (Javascipt Object Notation) contenente tra l’altro la formula in notazione TeX e produce l’output nel formato presente nella richiesta stessa (es. *.png, *.svg, ecc.)

Ingredienti

La ricetta che oggi vi propongo prevede i seguenti ingredienti:

  • MathJax Server installato come container su Docker.
  • Framework Bootstrap che ci aiuta a dare un’aspetto decente al front-end dell’applicazione (file index.php).
  • Server Apache con supporto PHP. L’installazione di Apache con PHP non è particolarmente complessa vi rimando alle numerose guide disponibili in rete o ai miei precedenti interventi su questo blog. Per lo scopo di questo progetto è richiesta inoltre l’installazione della libreria specifica php-curl.
  • Script equazione.php, accessibile come risorsa su server Apache e che si occupa di pre-processare in formato JSON la richiesta al server MathJax e di restituire al client l’immagine della formula in formato *.png (Portable Network Graphics).

Ecco un esempio del risultato che vogliamo ottenere:

Client

Figura 1: Form per invio dati al Server (formula in formato TeX)

Client After Submit

Figura 2: Pagina dopo risposta del Server

Passo 1: Installiamo MathJax Server (back-end dell’applicazione)

Docker

Per l’installazione di Docker su Debian o su altra distro vi rimando alla guida ufficiale https://docs.docker.com/engine/install/debian/.

Per completare il tutto, a scopo pratico, vi consiglio di abilitare il vostro utente locale all’esecuzione di Docker senza permessi di amministratore:

sudo usermod -aG docker $USER
Dove al posto di $USER inserite il nome utente

MathJax-Docker

Il server docker-izzato lo installiamo seguendo le indicazioni dalla pagina github dello sviluppatore https://github.com/uni-halle/mathjax-docker.

Che in breve si traduce senza fronzoli con questa istruzione da shell linux:

docker run -d --name TestMathJaxServer -p "8003:8003" unihalle/mathjax

Il nome ‘TestMathJaxServer’ rappresenta il nome del container e lo potete sostituire con ciò che  più vi aggrada.

Ricordatevi che al successivo riavvio del sistema lo start del container non è automatico e quindi va eseguito manualmente inserendo da shell linux la seguente istruzione:

docker start TestMathJaxServer

In alternativa alla shell potete utilizzare un’applicazione Desktop per Docker (es. DockStation) che vi faciliterà la gestione e l’amministrazione dei vostri container.

Il server che abbiamo avviato è ora in ascolto sulla porta 8003, che in soldoni significa che se puntiamo all’indirizzo http://localhost:8003 (oppure nel mio caso anche http://bibliomike:8003) dovremmo quanto meno accorgerci che esiste.

Nella realtà otteniamo una bella pagina bianca con il commento problem! Ciò avviene perché nell’header della richiesta il server si aspetta che ci sia qualcosa di più sostanzioso, ovvero un oggetto in formato JSON che oltre alla formula ben formatta conterrà anche il tipo di risposta che il client si aspetta dal server.

Passo 2: Creiamo il front-end dell’applicazione (file index.php)

Utilizzando un editor di testo o un IDE  a nostra scelta creeremo all’interno di una cartella accessibile sul nostro server Apache il file 'index.php' che conterrà almeno le seguenti componenti:

  1. Form contenente una TextArea che l’utente utilizzerà per l’inserimento del codice della formula con relativi pulsanti di Submit e Reset.
  2. Un’area della pagina dove caricare l’immagine della formula processata dal server in formato *.png.
  3. Funzione PHP che utilizzeremo per tradurre la richiesta del client in codifica JSON, che è quella accettata in modo specifico dal server. Per miglior leggibilità del codice ho preferito definire questa funzione in uno script esterno (equazione.php) e l’ho resa disponibile all’interno di index.php mediante la funzione include di PHP.

Nelle seguenti figure vi mostro un file index.php minimale e lo script equazione.php che ho utilizzato come prototipo per lo sviluppo del mio client.

Figura 3: Prototipo del file index.php

Figura 4: codice dello script equazione.php

Trattandosi di un progetto relativamente semplice ho utilizzato per la scrittura del codice il mitico editor Bluefish rispetto a NetBeans che solitamente utilizzo per progetti più complessi.

Per rendere questo codice funzionante dovrete quantomeno modificare le seguenti parti di codice:

  • riga 11 -> index.php: nell’attributo href va inserito il percorso corretto del vostro file index.php
  • riga 3 -> equazione.php: alla variabile $url dovrete assegnare il corretto indirizzo del server MathJax (es. http://localhost:8003)

L’aspetto della pagina che scaturirà da questo codice è poco accattivante rispetto al risultato che vi ho mostrato all’inizio dell’articolo.

Nota per la versione 8.1 di PHP
Il codice del costrutto if a partire dalla riga 20 dello script equazione.php, serve a verificare che il server MathJax generi una risposta valida ed è stato testato con la versione 7 di PHP. La release 8.1 genera invece un errore che impedisce il funzionamento dell’applicazione. Una possibile soluzione è illustrata a seguire: la funzione utilizzata verifica che la stringa ricevuta dal server abbia una codifica base64 valida per generare un’immagine.

Codice valido per PHP 8

Per rendere il codice del front-end più semplice da interpretare per il lettore, ho preferito tralasciare tutta la parte di sviluppo con le componenti di Bootstrap che avrebbe reso il codice poco leggibile e eccessivamente lungo da commentare.

A scopo informativo vi elenco di seguito le risorse che ho utilizzato per comporre il layout della pagina index.php a partire dal prototipo che vi ho illustrato:

Come scrivere il codice TeX per MathJax

Assumendo che siate anche voi riusciti a creare il vostro client MathJax personale vi invito a questo punto a consultare questa validissima risorsa, che vi aiuterà a progettare equazioni e sistemi di equazioni sempre più complesse.

https://www.onemathematicalcat.org/MathJaxDocumentation/TeXSyntax.htm

Conclusione

Il metodo che vi ho proposto non è sicuramente quello più efficiente o più semplice, probabilmente è possibile implementare un client con le stesse funzionalità sfruttando direttamente JavaScript (es. Ajax, JQuery, ecc.), lascio a voi cari lettori sperimentare altri metodi.

Le mie scelte sono state dettate da semplice curiosità e dal fatto che non avevo particolari impegni per il week-end.

La genesi del tutto è avvenuta quando tempo fa ho cercato di aggiungere qualche formula matematica complessa all’interno di un e-book che sto editando con il software di e-publishing Sigil.

La soluzione più pratica mi è sembrata quella di inserire queste formule nel testo direttamente come immagini, visto che il mio editor mal digerisce MathJax o MathML.

Mi sono chiesto quindi come produrre le mie formule in modo creativo senza usare i consueti strumenti offerti dal generatore di equazioni dei vari programmi per ufficio.

Quando la formula si fa tosta anche questi eccellenti strumenti mostrano i propri limiti, quindi una buona soluzione poteva essere quella di ricorrere al buon vecchio linguaggio TEX nato nel lontano 1978.

La curiosità mi ha poi spinto a testare per la prima volta il funzionamento di Docker e a rispolverare le mie limitate conoscenze di PHP.