I have a TeX Live 2019 distribution installed on Windows 10 and want to run a preloaded LaTeX based on e-TeX (with these packages among others: Calculator, Calculus, TikZ, CircuiTikZ) under WebAssembly in a web browser.
For the job I found TikZJax, which works as follows (quoted from readme.md by Jim Fowler kisonecat/tikzjax):
How does this work?
Using https://github.com/kisonecat/web2js the Pascal source of tex is
compiled to WebAssembly; the latex format is loaded (without all the
hyphenation data), and
\documentclass[margin=0pt]{standalone}
\def\pgfsysdriver{pgfsys-ximera.def}
\usepackage{tikz}
is executed. Then core is dumped; the resulting core is compressed,
and by reloading the dumped core in the browser, it is possible to
very quickly get to a point where TikZ can be executed. By using an
SVG driver for PGF along with https://github.com/kisonecat/dvi2html
the DVI output is converted to an SVG.All of this happens in the browser.
I did the following steps according to instructions from Web2JS:
- download a clean copy of the TeX WEB sources; output:
tex.web
- produce the Pascal source by tangle -ing, but with this changed version:
tangle -underline tex.web etex.ch
thanks to ShreevatsaR's tip; output:tex.p
tex.pool
after renaming from etex to tex - compile the
tex.p
" to get the WebAssembly binary; output:out.wasm
- produce
plain.fmt
and a corresponding memory dump with a JavaScript named initex.js; input:out.wasm
,plain.tex
; output:core.dump
,plain.fmt
,plain.log
,texput.log
- compile
sample.tex
; input:core.dump
; output:sample.dvi
,sample.log
I can't figure out how to make etex.ch
right containing all changes for an eTeX built in Pascal (and running in WebAssembly).
I am not able to compile tex.p
(which is actually an etex.p
) with web2js to get the WebAssembly binary out.wasm
.
I learned that in etex.ch
are several changes missing, e.g. memory management.
Here`s an error as follows from a compiling try:
c:\texlive\eTeX\web2js\node_modules\binaryen\index.js:7
if(t){v=__dirname+"/";var ba,ca;a.read=function(c,e){var g=w(c);
g||(ba||(ba=require("fs")),ca||(ca=require("path")),
c=ca.normalize(c),g=ba.readFileSync(c)); return e?g:g.toString()};
a.readBinary=function(c){c=a.read(c,!0);c.buffer||
(c=new Uint8Array(c));assert(c.buffer);return c};1<process.argv.length&&
(a.thisProgram=process.argv[1].replace(/\\/g,"/"));
a.arguments=process.argv.slice(2);
process.on("uncaughtException",function(c){if(!(c instanceof x))
throw c;});process.on("unhandledRejection",y);a.quit=
^
Need 32906 of memory
For this error to get I changed the following constants in tex.web
before tangle-ing:
- max_strings 3000 -> 500000
- string_vacancies 8000 -> 90000
- pool_size 32000 -> 6250000
- max_halfword 65535 -> 268435455
- mem_max 30000 -> 268435455
- buf_size 500 -> 200000
- stack_size 200 -> 5000
- mem_top 3000 -> 268435455
Without these changes I get this error:
! You have to increase POOLSIZE.
How do I make the etex.ch
right?
Update 04.08.2019
Thanks to Marcel Krüger's etex.sys
I can now create a plain e-TeX without any problems.
Annotations on this very valuable answer:
– WebAssembly memory page size: 64 KiB i.e. 65536 Bytes [1]
– WebAssembly memory implementation limit: 2GB (as of today) => 32767 pages [2]
1 Allow providing more initial memory than specified by the module #540
2 Can not set TOTAL_MEMORY greater than 2Gb or expand the memory to greater than 2Gb
Best Answer
You're increase of the pool size lead to additional memory requirements. So you do not need any other changes to eTeX, you have to increase the provided memory. In your Javascript versions, the amount of memory is set in the "compiler". For your settings you would need
32906
pages of memory, but there is an impmentation limit at32767
pages. Luckily you can avoid this problem by using smaller values.So we need to change some of the constants form
etex.web
. This doesn't mean that youretex.ch
is "wrong" and you need a "right" one. Actually the license ofetex.ch
would forbid such modifications(At least without changing the name). Instead you should write a system dependentetex.sys
file which you can pass totangle
later.So first get copies from
tex.web
andetex.ch
, then runto get
etex.web
. Now you need a changefile with you new constants, for example save the following asetex.sys
:Now you can run
tangle
:You get the files
etex.p
andetex.pool
.Of course
web2js
will still look fortex.pool
, but you can just changeinto
in both
header.js
andlibrary.js
.Now let's try
Similar to your original experiment, we get
Now
41
is significantly less than32906
, especially it is below32767
. So we can just allocate more memory. This needs to be done consistently in four files: Inindex.js
,initex.js
,tex.js
andpascal/program.js
, changeinto
(Probably 41 would be enough, but 50 looks nicer)
Now we can try
again. This time it actually works! You could use
node initex.js
now to get plain-TeX format, but we actually want eTeX. So you can get yourself a version ofetex.src
,etexdefs.lib
andlanguage.def
and changein
initex.js
intoHere, the asterisk
*
is important, it enables the "extended mode". Also change&plain
into&etex
in the same file to preloadetex
.Then
generates a
e-TeX
formatetex.fmt
and a memory dump, which can be used with