Compiling LATEX to computer algebra-enabled HTML5
aa r X i v : . [ c s . S C ] J u l Compiling L A TEX to computer algebra-enabledHTML5
Bernard ParisseInstitut FourierUMR 5582 du CNRSUniversité de Grenoble I2017
Abstract
This document explains how to create or modify an existing L A TEX documentwith commands enabling computations in the HTML5 output: when the readeropens the HTML5 output, he can run a computation in his browser, or modify thecommand to be executed and run it. This is done by combining different softwares: hevea [6] for compilation to HTML5, giac.js for the CAS computing kernel(itself compiled from the C++ Giac[10] library with emscripten [11]), and amodified version[9] of itex2MML [3] for fast and nice rendering in MathML inbrowsers that support MathML.
Contents Introduction
Combining L A TEX rendering quality and CAS computing is not new:1. math softwares provide converters to export data to a L A TEX file, or provide au-tomated computations in a way similar to the way bibtex provides bibliography,like sagetex ([2]).2. some softwares handle both L A TEX-like rendering and computation, for exampletexmacs ([5]), lyx ([7]), Jupyter notebook ([8]).However, in the first case, the reader can not modify the CAS commandlines, and inthe second case the data format is not standard L A TEX (the writer can not start from anexisting document) and requires additional software to be installed on the reader deviceor a net access to a server to run the computations.The solution presented here is new in that the writer will edit a standard L A TEX file,add a few easy to learn commands like \giacinputmath{factor(x^10-1)} or \giacinput{plot(sin(x))} and compile it to produce a HTML5+MathMLdocument. The reader can see the document in any browser (it’s optimized for Firefox),without installation, and he can modify computation commandlines and run them onhis own computer.If you are reading this file in PDF format, it is highly recommended to open theHTML5/Mathml version in order to test interactivity and look at the L A TEX source The writer must install • the latest unstable version of hevea ([6]) or a forked version hevea-mathjax ([1])), • Giac/Xcas ([10]) for computing-enabled output • heveatomml ([9]) for MathML output The files giac.tex (or the French version giacfr.tex ) giac.js , hevea.sty , mathjax.sty must be copied in the L A TEX working directory. On an Internet con- http://hevea.inria.fr/distri/unstable/ https://github.com/YannickChevalier/hevea-mathjax We now assume that the installation is done. The writer opens a L A TEX file with hisusual editor. He must add in the preamble the following lines \makeindex\input{giac.tex}\giacmathjax
For interactive CAS L A TEX commands support, the writer should add \begin{giacjshere}\tableofcontents\printindex just after \begin{document} and \end{giacjshere} just before \end{document} . Printing the table of contents and index before thefirst L A TEX section command is recommended, otherwise the HTML output
Table and
Index buttons will not link correctly.The rest of the source file is standard L A TEX except that • References to numbered equations should be inside additional backslash-ed paren-thesis, for example 3 begin{equation} \label{eq:test}\frac{2}{x^2-1}=\frac{1}{x-1}-\frac{1}{x+1}\end{equation}From equation (\(\ref{eq:test}\)) ... x − x − − x + 1 (1)From equation ( ) ... • \mathbb{} should be explicit, commands like \R where \R is defined by \newcommand{\R}{\mathbb{R}} will not work. • New commands are available for interactive CAS support – \giacinputmath{commandline} will output an inline commandline that the user can modify and execute, the answer will be displayed inMathML (or SVG for 2-d graph output).Example : \giacinputmath{factor(x^10-1)}factor(x^10-1) ( x − · ( x + 1)( x − x + x − x + 1)( x + x + x + x + 1) Warnings , if your command contains < or > , you must replace them by < or > , otherwise they will be interpreted as HTML delimiters.You can also use the giacprog and giaconload environments ex-plained below.If the output is a 2-d graph, do not skip a line with \\ after the commandfor PDF output – \giaccmdmath{command}{arguments} will output command ina button following the arguments , the reader can only modify the argu-ments: \giaccmdmath{factor}{x^4-1}factor(x^4-1) ( x − · ( x + 1)( x + 1) – These commands may take an optional HTML style argument, for example \giacinputmath[style="width:200px;"]{factor(x^10-1)}factor(x^10-1) ( x − · ( x + 1)( x − x + x − x + 1)( x + x + x + x + 1) giaccmdmath[style="font-size:x-large"]{factor}{x^4-1}factor(x^4-1) ( x − · ( x + 1)( x + 1) – There are similar commands for outlined output \giacinputbigmath{} or \giaccmdbigmath{}{} :For example \giacinputbigmath{factor(x^25-1)}factor(x^25-1) ( x − x + x + x + x + 1)( x + x + x + x + 1) Example with an optional style argument \giacinputbigmath[style="width:600px;height:20px;"]{factor(x^25-1)}factor(x^25-1) ( x − x + x + x + x + 1)( x + x + x + x + 1) \giaccmdbigmath{factor}{x^25-1}factor(x^25-1) ( x − x + x + x + x + 1)( x + x + x + x + 1) \giaccmdbigmath[style="width:600px;height:20px;"]{factor}{x^25-1}factor(x^25-1) ( x − x + x + x + x + 1)( x + x + x + x + 1) – Similar commands with text (or plot) output \giacinput and \giacinputbig and \giaccmd , example: \giacinput{factor(x^4-1)} : factor(x^4-1) ( x − · ( x + 1)( x + 1) giaccmd{print}{"Hello world"} : print("Hello world") With optional style argument \giacinput[style="font-size:x-large"]{plot(1/x)}plot(1/x) xy−10 −5 0 5 10 −0.4−0.200.20.4 \giaccmd[style="font-size:x-large"]{factor}{x^4-1}factor(x^4-1) ( x − · ( x + 1)( x + 1) – The giacprog environment should be used for programs or multi-linecommands \begin{giacprog}...\end{giacprog}
Inside this environment, you can keep < and > . The program will be parsedonce the user press the ok button. After parse, the program may be modi-fied and parsed again. Warning : Do not use the giacprog environment in another environment(like itemize or enumerate).If you want the program to be parsed at load-time, replace giacprog with giaconload : \begin{giaconload}...\end{giaconload} – The \giacslider{idname}{min}{max}{step}{value}{command} command will add a slider. When the user modifies the slider interactively,6he new value is stored in idname and the command (depending on idname ) is executed. Example: \giacslider{a}{-5}{5}{0.1}{0.5}{plot(sin(a*x))}a:=0.5;plot(sin(a*x)) xy−10 −5 0 5 10 −1−0.500.51 – The \giachidden command behaves like \giaccmd except that thedefault HTML5 style is “hidden” until the command button has been pressed. – The \giaclink command will add a link in the HTML version andnothing in PDF/DVI. The links open in a new tab, and the correspondingtext may be specified as optional argument (default is Test online). Notethat hevea.sty provides similar commands ( \ahref , \footahref , \ahrefurl ) with output in PDF/DVI.Example with a link to Xcas for Firefox with a few commands Once the source file is written, it is compiled to HTML5 with the command hevea2mml sourcefile.tex
The HTML output and the giac.js files should be in the same directory on the webserver. Index and bibliography should be processed with makeindex and bibhva .If a PDF output is desired, the command icas from a Giac/Xcas installationshould be used instead of pdflatex because it will run all CAS commands, outputthem in a temporary L A TEX file, and run pdflatex on the output (this was inspired bythe pgiac script from Jean-Michel Sarlat [4]). The temporary file name is obtained byadding a _ at the end of the initial file name (without the .tex extension). Therefore,if you have an index and or citations, you should run makeindex and bibtex onthe file name with _ appended. For bibtex citations in the HTML files, you shouldrun bibhva . For example, the PDF version of this document is available here . http://melusine.eu.org/syracuse/giac/pgiac/ .3 On the reader side The reader’s browser opens an HTML5+MathML file (linking to the JavaScript giac.js ).The MathML is rendered natively on Firefox or Safari, while Chrome or Internet Ex-plorer will automatically load MathJax to render MathML (this is of course noticeablyslower if the document is large). Computations are run by the reader’s browser (theCAS is JavaScript code). This is slower than native code but faster than net access to aserver and it does not require setting up a specific server for computations.
This example illustrates with a slider that the evolute of a curve is the envelope of thenormals to the curve, here the curve is an ellipsis and the envelop an astroid. The listof normals L is initialized empty at load-time. L:=[]
Now move the slider: t0:=0.7;gl_x=-6..6;gl_y=-4..4;G:=plotparam([2*cos(t),sin(t)],t=0..2*pi);M:=element(G,evalf(t0));T:=tangent(M);N:=perpendicular(M,T);L:=append(L,N);evolute(G,color=red)
GMT NL xy−4 −2 0 2 4 6−3−2−10123 C is a cone of center the origin, axis of direction (0 , , , and angle π , P is a plane ofequation z = my + 3 . m is controlled by the slider, when m moves the intersection isan ellipsis or hyperbola (limit value is a parabola). m:=0.7;C:=cone([0,0,0],[0,0,1],pi/6, display=green+filled);P:=plane(z=evalf(m)*y+3,display=cyan+filled); xzP A program computing the Dunford decomposition of a matrix with Newton method. Itis parsed at load-time ( giaconload environment). function dunford(A)local U,p,q,q1,j,d,n;U:=A;n:=nrows(U);p:=charpoly(U);q:=p/gcd(p,p’); // square free partq1:=q’;for (j:=1;j<=n;j:=2*j){d:=inv(horner(q1,U))*horner(q,U); // Newton stepif (d==0*d) return U,A-U;U:=U-d;}return U,A-U;end:;
Example : we define J an almost diagonal matrix and A a similar matrix and we checkthe Dunford decomposition of A . J = , P = − , A = P JP − J:=[[2,0,0],[0,1,1],[0,0,1]]; P:=trn([[1,2,3],[0,-1,4],[0,0,1]]); A:=P*J*inv(P) , − , − − −
41 16 5 ,N:=dunford(A); N^2; P*diag(diag(J))*inv(P) , − − −
44 16 4 , , This will display the slopefield of an ordinary differential equation dydt = − y + cos ( t ) and one solution corresponding to an initial condition y (0) that the user may modifywith the slider. y0:=1.0;gl_x=-5..5; gl_y=-3..3;plotfield(-y+cos(t),[t=-5..5,y=-3..3],xstep=0.4,ystep=0.4);plotode(-y+cos(t),[t=-5..5,y],[0,y0],tstep=0.1,color=red) xy−4 −2 0 2 4 −2−1012 The CAS kernel can compute non-trivial Gröbner basis. Of course, the JavaScriptversion is significantly slower than the native Giac/Xcas kernel. kat7:=[-x1+2*x8^2+2*x7^2+2*x6^2+2*x5^2+2*x4^2+2*x3^2+2*x2^2+x1^2,-x2+2*x8*x7+2*x7*x6+2*x6*x5+2*x5*x4+2*x4*x3+2*x3*x2+2*x2*x1,-x3+2*x8*x6+2*x7*x5+2*x6*x4+2*x5*x3+2*x4*x2+2*x3*x1+x2^2,-x4+2*x8*x5+2*x7*x4+2*x6*x3+2*x5*x2+2*x4*x1+2*x3*x2,-x5+2*x8*x4+2*x7*x3+2*x6*x2+2*x5*x1+2*x4*x2+x3^2,-x6+2*x8*x3+2*x7*x2+2*x6*x1+2*x5*x2+2*x4*x3,-x7+2*x8*x2+2*x7*x1+2*x6*x2+2*x5*x3+x4^2,-1+2*x8+2*x7+2*x6+2*x5+2*x4+2*x3+2*x2+x1]:; Z / G:=gbasis(kat7 mod 16777213,[x1,x2,x3,x4,x5,x6,x7,x8]):; size(G); G[20];
Done , , x5 · x7 · x8 +6710886 · x4 · x8 − · x5 · x8 +5106109 · x6 · x8 − · x7 · x8 +4960220 · x8 − · x7 +3350574 · x7 · x8 − · x7 · x8 − · x2 · x6 · x8 − · x3 · x6 · x8 +4830623 · x4 · x6 · x8 +6654447 · x2 · x7 · x8 +1485963 · x3 · x7 · x8 +7645914 · x4 · x7 · x8 +6108299 · x5 · x7 · x8 − · x7 · x8 +1467630 · x2 · x8 − · x3 · x8 − · x4 · x8 − · x5 · x8 +5036573 · x6 · x8 − · x7 · x8 − · x8 − · x2 · x7 − · x3 · x7 − · x4 · x7 − · x5 · x7 +5344773 · x6 · x7 +8336020 · x7 − · x2 · x4 · x7 · x8 − · x2 · x5 · x7 · x8+5772217 · x3 · x5 · x7 · x8 − · x2 · x7 · x8+6818342 · x3 · x7 · x8 − · x4 · x7 · x8+2932624 · x5 · x7 · x8+8254803 · x6 · x7 · x8 − · x7 · x8+8076837 · x2 · x4 · x8 +17492 · x2 · x5 · x8 +2985896 · x3 · x5 · x8 − · x2 · x6 · x8 +6542761 · x3 · x6 · x8 +1168714 · x4 · x6 · x8 +7247300 · x2 · x7 · x8 − · x3 · x7 · x8 − · x4 · x7 · x8 +3659549 · x5 · x7 · x8 +3059392 · x6 · x7 · x8 +7854288 · x7 · x8 +4699527 · x2 · x8 +2770983 · x3 · x8 − · x4 · x8 − · x5 · x8 +7556960 · x6 · x8 +4537622 · x7 · x8 +6304804 · x8 +3315662 · x2 · x4 · x6+4416381 · x6 +8014147 · x2 · x4 · x7+6313405 · x2 · x5 · x7 − · x3 · x5 · x7 − · x2 · x6 · x7+5361345 · x3 · x6 · x7 − · x4 · x6 · x7+4866646 · x6 · x7 − · x2 · x7 − · x3 · x7 +7598477 · x4 · x7 +2841104 · x5 · x7 +1175912 · x6 · x7 +256538 · x7 +5505000 · x2 · x4 · x8 − · x2 · x5 · x8+712446 · x3 · x5 · x8+4754075 · x2 · x6 · x8 − · x3 · x6 · x8+2532426 · x4 · x6 · x8+5979911 · x6 · x8+5610090 · x2 · x7 · x8+7153809 · x3 · x7 · x8+5595623 · x4 · x7 · x8 − · x5 · x7 · x8 − · x6 · x7 · x8+7135075 · x7 · x8+1582261 · x2 · x8 +1104606 · x3 · x8 +2300040 · x4 · x8 +6997133 · x5 · x8 − · x6 · x8 +1805598 · x7 · x8 +6256405 · x8 +4736670 · x2 · x4 − · x2 · x5 − · x3 · x5+6347609 · x2 · x6+304173 · x3 · x6 − · x4 · x6+8076963 · x5 · x6 − · x6 − · x2 · x7 − · x3 · x7 − · x4 · x7+8039746 · x5 · x7 − · x6 · x7+5282236 · x7 +8160369 · x2 · x8+7695372 · x3 · x8+3981391 · x4 · x8+2313354 · x5 · x8+2267196 · x6 · x8+479769 · x7 · x8 − · x8 − · x2+2233312 · x3+7143090 · x4+1632345 · x5+4462465 · x6+2457609 · x7 − · x8 Basis over Q G:=gbasis(kat7,[x1,x2,x3,x4,x5,x6,x7,x8]):; size(G); G[20];
Done , , · x5 · x7 · x8 +14791699293342485729566066619904000 · x4 · x8 +15434816653922593804764591255552000 · x5 · x8 +12862347211602161503970492712960000 · x6 · x8 +13505464572182269579169017348608000 · x7 · x8 +9325201728411567090378607216896000 · x8 − · x7 − · x7 · x8 − · x7 · x8 +160779340145027018799631158912000 · x2 · x6 · x8 +600221686826000076111666520128000 · x3 · x6 · x8 +1273847681214291488932343388672000 · x4 · x6 · x8 +186437307964613840475659253936000 · x2 · x7 · x8 +752203505074579054604747812972800 · x3 · x7 · x8 − · x4 · x7 · x8 − · x5 · x7 · x8 +454447652288092171148808976608000 · x7 · x8 − · x2 · x8 − · x3 · x8 − · x4 · x8 − · x5 · x8 − · x6 · x8 − · x7 · x8 − · x8 − · x2 · x7 − · x3 · x7 − · x4 · x7 − · x5 · x7 − · x6 · x7 − · x7 − · x2 · x4 · x7 · x8 − · x2 · x5 · x7 · x8 − · x3 · x5 · x7 · x8 − · x2 · x7 · x8 − · x3 · x7 · x8 − · x4 · x7 · x8 − · x5 · x7 · x8 − · x6 · x7 · x8 − · x7 · x8 − · x2 · x4 · x8 − · x2 · x5 · x8 − · x3 · x5 · x8 − · x2 · x6 · x8 − · x3 · x6 · x8 − · x4 · x6 · x8 − · x2 · x7 · x8 − · x3 · x7 · x8 − · x4 · x7 · x8 − · x5 · x7 · x8 − · x6 · x7 · x8 − · x7 · x8 − · x2 · x8 − · x3 · x8 − · x4 · x8 − · x5 · x8 − · x6 · x8 − · x7 · x8 +374371816008112991685996200902080 · x8 − · x2 · x4 · x6+271109377228003452783896549760 · x6 +2628441194615113394423827720800 · x2 · x4 · x7+9613536060917368128768219000000 · x2 · x5 · x7+12192741404432093251997475825600 · x3 · x5 · x7+5564895255194648753981939738400 · x2 · x6 · x7 − · x3 · x6 · x7 − · x4 · x6 · x7+5188507391232533844112778323560 · x6 · x7+7632836308610801201148972855300 · x2 · x7 − · x3 · x7 +3871815792450784509518290458180 · x4 · x7 +89868955193762132338520852933280 · x5 · x7 +118738983748114730979236687763600 · x6 · x7 +112700208596061313641314862430560 · x7 +4053544256098076583899196741600 · x2 · x4 · x8+6865996284226614668583179489760 · x2 · x5 · x8+45242337648974041470614272158060 · x3 · x5 · x8+32227201282706955721618206220800 · x2 · x6 · x8+74541032189966350904022813664440 · x3 · x6 · x8+109222371672216817132192001508000 · x4 · x6 · x8 − · x6 · x8+29594299342945246138164657151080 · x2 · x7 · x8+205159980647763425790697815649620 · x3 · x7 · x8+278339206993654959199265198747760 · x4 · x7 · x8+320109418092634463592305998443900 · x5 · x7 · x8+470455163686395205853079522680640 · x6 · x7 · x8+755778577030191710047502491424040 · x7 · x8+154034703044709254756761011059520 · x2 · x8 +408438843078288837589395409099080 · x3 · x8 +626571774184586400445578730691040 · x4 · x8 +624320625021505001235797755627800 · x5 · x8 +765354057100611716543860177215120 · x6 · x8 +1613656634668411336764387754269240 · x7 · x8 +742017541276853107569936500714280 · x8 − · x2 · x4+249618277062914161062989489490 · x2 · x5+1900410268192910546526379348920 · x3 · x5+4235302367045310263654245214340 · x2 · x6+6017966457428446868635215553710 · x3 · x6+7191909101684961100934533192860 · x4 · x6+9789374444237912565456468704848 · x5 · x6+11559501634033175787315078653112 · x6 +101079410207415260494159169730 · x2 · x7+99661074822647098112134792800 · x3 · x7 − · x4 · x7 − · x5 · x7+13966570096620920111910735849858 · x6 · x7+6167950709721386348534611467920 · x7 +6479267803700614230481232223780 · x2 · x8 − · x3 · x8 − · x4 · x8 − · x5 · x8 − · x6 · x8 − · x7 · x8 − · x8 +145410814833489474708302735228 · x2+567461515246797856334772898352 · x3+690332069209059893002349525292 · x4+810398183902583651863724586368 · x5+1317646827183272993428371499025 · x6+2648636588012522741659902630708 · x7+2995670767262379465274814083712 · x8 The L A TEX \giac... commands are defined in giac.tex . For example \giacinput is defined like this: \newcommand{\verb||\\$$\,\mathrm{undef}\,$$[2][style="width:400px;font-size:large"]{\ifhevea\@print{
Module interface created by compiling Giac/X-cas with the C++ to JavaScript compiler emscripten . The CAS code being inJavaScript, it can be run on every JavaScript-enabled browser. It will be faster onbrowsers that have support for asm.js ( asmjs.org ) like Mozilla Firefox: numer-ical computations are 1 to 2 times slower than native code, while exact computationsare 2 to 10 times slower than native code (the main reason being that JavaScript hascurrently no 64 bits integer type). http://kripken.github.io/emscripten-site/ pdflatex is run on the tex file, giac commands will bewritten verbatim, but they will not be processed. The icas command from the Gi-ac/Xcas package will filter all giac commands, process them and output the result inmath mode in a temporary L A TEX file. If the answer is a 2-d graph output, icas willoutput a pdf file on the hard disk and output a corresponding \includegraphics command in the temporary L A TEX file. After that, the temporary file will be processedby pdflatex . The current version of icas and giac.tex are already usable to easily produceHTML interactive CAS-enabled document from L A TEX documents. They may be com-pleted in future versions depending on user requests. For example, online coursesmight have commands to enable student exercises answers auto-check.
Acknowledgements
Thanks to Luc Maranget and Yannick Chevalier for fixing bugs in mathjax-enabledhevea. Thanks to Renée De Graeve and Murielle Stepec who have tested preliminaryversions of this compilation method.
References [1] Yannick Chevallier. Hevea: LaTeX to HTML5 compiler, fork for MathJax sup-port. https://github.com/YannickChevalier/hevea-mathjax ,2017.[2] Dan Drake. SageTex. , 2009.[3] Jacques Distler. LaTeX to MathML converter. golem.ph.utexas.edu/˜ distler/blog/itex2MML.html , 2016.[4] Jean-Michel Sarlat. pgiac. http://melusine.eu.org/syracuse/giac/pgiac/ ,2011.[5] Joris van der Hoeven. Texmacs. , 2017.[6] Luc Maranget. Hevea: LaTeX to HTML5 compiler (unstable version). http://hevea.inria.fr/distri/unstable/ , 2017.[7] Matthias Ettrich. Lyx. https://ww.lyx.org , 2012.[8] NumFOCUS Foundation. The Jupyter Notebook. jupyter.org , 2017.[9] Bernard Parisse. LaTeX to Mathml converter, fork for hevea output support. ,2017.[10] Bernard Parisse and Renée De Graeve. Giac/Xcas Computer Algebra System. , 2017.1211] Alon Zakai. Emscripten: A C/C++ to Javascript compiler. kripken.github.io/emscripten-site/kripken.github.io/emscripten-site/