ゆるい LaTeX数式 → MathML 変換器(になる予定)
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app
repl
src/Text/YuruMath
test
tools
.gitignore
ChangeLog.md
LICENSE
README.md
Setup.hs
package.yaml
stack.yaml

README.md

YuruMath

YuruMath is an implementation of the TeX language (without a complete visual processor) in Haskell. This is developed with the intention to emit MathML from (La)TeX formula.

Play with REPL

$ git clone https://github.com/minoki/yurumath.git
$ cd yurumath/
$ stack build --fast
$ stack exec yurumath-repl
*

* is the prompt (as in TeX).

Now let's type something:

*\message{Hello world!}
Hello world!
*

Some equation:

*\frac{a}{b}
MathML: <math>
    <mfrac>
        <mi>
            a
        </mi>
        <mi>
            b
        </mi>
    </mfrac>
</math>

*

Integers beyond 232 are supported:

*\def\fact#1{\ifnum#1=0 1 \else\numexpr#1*\expandafter\fact\expandafter{\number\numexpr#1-1\relax}\relax\fi}
*\message{\number\fact{20}}
2432902008176640000
*\message{\number"100000000 }
4294967296

The interpreter tries to prevent infinite loop:

*\def\foo{\foo} \foo
error: recursion too deep
*\def\foo{\foo\foo\foo} \foo
error: token list too long
*\def\foo{\uppercase{\foo}} \foo
error: recursion too deep
*\def\foo{'} {\catcode`\'=\active \global\let'=\foo} '
error: recursion too deep

Supported TeX primitives

Some commands are from e-TeX or XeTeX/LuaTeX.

Expandable commands

  • \expandafter, \noexpand, \csname, \string, \number, \romannumeral, \the, \meaning
  • \if, \ifcat, \ifx, \iftrue, \iffalse, \ifnum, \ifdim, \ifodd, \ifcase
  • \ifhmode, \ifvmode, \ifmmode, \ifinner, \ifdefined, \ifcsname, \ifabsnum, \ifincsname
  • \unless, \else, \fi, \or
  • \begincsname, \csstring, \Uchar, \mathstyle
  • \unexpanded, \detokenize, \scantokens, \strcmp (or \pdfstrcmp), \expanded

Non-expandable commands

  • \relax, \endcsname, \global
  • \uppercase, \lowercase, \ignorespaces
  • \let, \futurelet
  • \def, \edef, \gdef, \xdef, \outer, \long, \protected
  • \chardef, \mathchardef, \Umathchardef, \Umathcharnumdef
  • \catcode, \lccode, \uccode, \mathcode, \Umathcode, \Umathcodenum, \delcode, \Udelcode, \Udelcodenum
  • \begingroup, \endgroup
  • \endlinechar, \escapechar
  • \count, \countdef, \dimen, \dimendef, \skip, \skipdef, \muskip, \muskipdef, \toks, \toksdef
  • \advance, \multiply, \divide
  • \numexpr, \dimexpr, \glueexpr, \muexpr
  • \gluestretch, \glueshrink, \gluestretchorder, \glueshrinkorder, \mutoglue, \gluetomu
  • \message, \show, \showthe, \showtokens
  • \char, \kern, \unkern, \unskip, \hskip, \hfil, \hfill, \hss, \hfilneg, \noindent, \ , \/
  • \newcommand, \renewcommand, \providecommand (from LaTeX)

Math mode commands:

  • \mathchar, \Umathchar, \Umathcharnum, \delimiter, \Udelimiter, \mathaccent, \Umathaccent, \radical, \Uradical, \Uroot
  • \mathord, \mathop, \mathbin, \mathrel, \mathopen, \mathclose, \mathpunct, \mathinner
  • \underline, \overline, \vcenter
  • \displaylimits, \limits, \nolimits
  • \left, \middle, \right, \Uleft, \Umiddle, \Uright
  • \over, \atop, \above, \Uskewed, \overwithdelims, \atopwithdelims, \abovewithdelims, \Uskewedwithdelims
  • \mathchoice, \Ustack
  • \fam, \thinmuskip, \medmuskip, \thickmuskip
  • \mkern, \mskip, \nonscript
  • \Usuperscript, \Usubscript, \Ustopmath, \Ustopdisplaymath
  • \displaystyle, \textstyle, \scriptstyle, \scriptscriptstyle, \crampeddisplaystyle, \crampedtextstyle, \crampedscriptstyle, \crampedscriptscriptstyle

Incompatiblities with TeX

  • \over-like commands must be prefixed by \Ustack, like \Ustack{1\over2}.
  • ^^ notation in the control word (e.g. \f^^6fo = \foo) is not allowed.
  • Expansion of \noexpand yields a token whose meaning is really equivalent to \relax; That is, \expandafter\let\expandafter\foo\noexpand\baz \ifx\foo\relax\message{Y}\else\message{N}\fi prints Y in YuruMath, whereas it prints N in a real TeX.
  • The \relax inserted by \or, \else or \fi is equivalent to a control sequence named relax whose meaning is \relax; That is, \def\foo\relax{} \expandafter\foo\ifodd1\fi produces no error in YuruMath, whereas it raises the error Use of \foo doesn't match its definition. in a real TeX.