diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/x-mmp.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/base/x-mmp.mkiv | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/x-mmp.mkiv b/Master/texmf-dist/tex/context/base/x-mmp.mkiv new file mode 100644 index 00000000000..dff7ade58d8 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/x-mmp.mkiv @@ -0,0 +1,497 @@ +%D \module +%D [ file=x-mmp, +%D version=2007.09.04, +%D title=\CONTEXT\ XML Modules, +%D subtitle=Presentation MathML Renderer, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startluacode + do + + lxml.mml = lxml.mml or { } + + local texsprint = tex.sprint + + -- an alternative is to remap to private codes, where we can have + -- different properties .. to be done + + local n_replacements = { + -- [" "] = utf.char(0x2002), -- "&textspace;" -> tricky, no &; in mkiv + ["."] = "{.}", + [","] = "{,}", + [" "] = "", + } + local o_replacements = { + ["{"] = "\\mmlleftdelimiter\\lbrace", + ["}"] = "\\mmlrightdelimiter\\rbrace", + ["("] = "\\mmlleftdelimiter(", + [")"] = "\\mmlrightdelimiter)", + ["["] = "\\mmlleftdelimiter[", + ["]"] = "\\mmlrightdelimiter]", + ["<"] = "\\mmlleftdelimiter<", + [">"] = "\\mmlrightdelimiter>", + ["#"] = "\\mmlchar{35}", + ["$"] = "\\mmlchar{36}", + ["%"] = "\\mmlchar{37}", + ["&"] = "\\mmlchar{38}", + ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math see the char instead of \char + ["_"] = "\\mmlchar{95}{}", -- so we need the {} + ["~"] = "\\mmlchar{126}", + [" "] = "", + } + local i_replacements = { + ["sin"] = "\\mathopnolimits{sin}", + ["cos"] = "\\mathopnolimits{cos}", + ["abs"] = "\\mathopnolimits{abs}", + ["arg"] = "\\mathopnolimits{arg}", + ["codomain"] = "\\mathopnolimits{codomain}", + ["curl"] = "\\mathopnolimits{curl}", + ["determinant"] = "\\mathopnolimits{det}", + ["divergence"] = "\\mathopnolimits{div}", + ["domain"] = "\\mathopnolimits{domain}", + ["gcd"] = "\\mathopnolimits{gcd}", + ["grad"] = "\\mathopnolimits{grad}", + ["identity"] = "\\mathopnolimits{id}", + ["image"] = "\\mathopnolimits{image}", + ["lcm"] = "\\mathopnolimits{lcm}", + ["max"] = "\\mathopnolimits{max}", + ["median"] = "\\mathopnolimits{median}", + ["min"] = "\\mathopnolimits{min}", + ["mode"] = "\\mathopnolimits{mode}", + ["mod"] = "\\mathopnolimits{mod}", + ["polar"] = "\\mathopnolimits{Polar}", + ["exp"] = "\\mathopnolimits{exp}", + ["ln"] = "\\mathopnolimits{ln}", + ["log"] = "\\mathopnolimits{log}", + ["sin"] = "\\mathopnolimits{sin}", + ["arcsin"] = "\\mathopnolimits{arcsin}", + ["sinh"] = "\\mathopnolimits{sinh}", + ["arcsinh"] = "\\mathopnolimits{arcsinh}", + ["cos"] = "\\mathopnolimits{cos}", + ["arccos"] = "\\mathopnolimits{arccos}", + ["cosh"] = "\\mathopnolimits{cosh}", + ["arccosh"] = "\\mathopnolimits{arccosh}", + ["tan"] = "\\mathopnolimits{tan}", + ["arctan"] = "\\mathopnolimits{arctan}", + ["tanh"] = "\\mathopnolimits{tanh}", + ["arctanh"] = "\\mathopnolimits{arctanh}", + ["cot"] = "\\mathopnolimits{cot}", + ["arccot"] = "\\mathopnolimits{arccot}", + ["coth"] = "\\mathopnolimits{coth}", + ["arccoth"] = "\\mathopnolimits{arccoth}", + ["csc"] = "\\mathopnolimits{csc}", + ["arccsc"] = "\\mathopnolimits{arccsc}", + ["csch"] = "\\mathopnolimits{csch}", + ["arccsch"] = "\\mathopnolimits{arccsch}", + ["sec"] = "\\mathopnolimits{sec}", + ["arcsec"] = "\\mathopnolimits{arcsec}", + ["sech"] = "\\mathopnolimits{sech}", + ["arcsech"] = "\\mathopnolimits{arcsech}", + [" "] = "", + + ["false"] = "{\\mr false}", + ["notanumber"] = "{\\mr NaN}", + ["otherwise"] = "{\\mr otherwise}", + ["true"] = "{\\mr true}", + ["declare"] = "{\\mr declare}", + ["as"] = "{\\mr as}", + } + + function lxml.mml.prepare_number(id,pattern) + local str = xml.content(lxml.id(id),pattern) or "" + texsprint(tex.ctxcatcodes,(str:gsub(".",n_replacements))) + end + function lxml.mml.prepare_operator(id,pattern) + local str = xml.content(lxml.id(id),pattern) or "" + tex.sprint(tex.ctxcatcodes,(str:gsub(".",o_replacements))) + end + function lxml.mml.prepare_identifier(id,pattern) + local str = xml.content(lxml.id(id),pattern) or "" + str = str:gsub("^%s*(.*)%s*$","%1") + local rep = i_replacements[str] + if rep then + tex.sprint(tex.ctxcatcodes,rep) + else + tex.sprint(tex.ctxcatcodes,(str:gsub(".",i_replacements))) + end + end + + function lxml.mml.connect(id,pattern,separators) -- multiple separators + local n = xml.count(id,pattern) + if n == 0 then + -- skip + elseif n == 1 then + lxml.all(id,pattern) + else + local t = { } + for s in utf.gmatch(separators,"([^%s])") do + t[#t+1] = s + end + for i=1,n do + if i > 1 then + texsprint(tex.ctxcatcodes,"{") + texsprint(t[i] or t[#t] or "") + texsprint(tex.ctxcatcodes,"}") + end + lxml.idx(id,pattern,i) -- kind of slow, some day ... + end + end + end + + local function flush(e,tag,toggle) + -- texsprint(tex.ctxcatcodes,(toggle and "^{") or "_{") + if toggle then + texsprint(tex.ctxcatcodes,"^{") + else + texsprint(tex.ctxcatcodes,"_{") + end + if tag == "none" then + texsprint(tex.ctxcatcodes,"{}") + else + xml.sprint(e.dt) + end + if not toggle then + texsprint(tex.ctxcatcodes,"}") + else + texsprint(tex.ctxcatcodes,"}{}") + end + return not toggle + end + + function lxml.mml.multiscripts(id) + local done, toggle = false, false + id = lxml.id(id) + -- for i=1,#id.dt do local e = id.dt[i] if type(e) == table then ... + for r, d, k in xml.elements(id,"/*") do + local e = d[k] + local tag = e.tg + if tag == "mprescripts" then + texsprint(tex.ctxcatcodes,"{}") + done = true + elseif done then + toggle = flush(e,tag,toggle) + end + end + local done, toggle = false, false + for r, d, k in xml.elements(id,"/*") do + local e = d[k] + local tag = e.tg + if tag == "mprescripts" then + break + elseif done then + toggle = flush(e,tag,toggle) + else + xml.sprint(e.dt) + done = true + end + end + end + + end +\stopluacode + +\unprotect + +% helpers + +% \let\myspecialnormalvert\myspecialstretchvert +% \setupMMLappearance[scripts][\c!alternative=\v!a] {} rond base + +\mapXMLvalue{mmp}{normal} {\tf} \mapXMLvalue{mmp}{double-stuck} {\bf} +\mapXMLvalue{mmp}{bolditalic} {\bi} \mapXMLvalue{mmp}{bold-italic} {\bi} +\mapXMLvalue{mmp}{boldslanted}{\bs} \mapXMLvalue{mmp}{bold-slanted} {\bs} +\mapXMLvalue{mmp}{boldnormal} {\bf} \mapXMLvalue{mmp}{bold} {\bf} +\mapXMLvalue{mmp}{slanted} {\sl} \mapXMLvalue{mmp}{normalslanted}{\sl} +\mapXMLvalue{mmp}{italic} {\it} \mapXMLvalue{mmp}{normalitalic} {\it} +\mapXMLvalue{mmp}{fraktur} {\bf} \mapXMLvalue{mmp}{bold-fraktur} {\bf} +\mapXMLvalue{mmp}{script} {\tf} \mapXMLvalue{mmp}{bold-script} {\bf} + +\def\setMMLptextstyle#1% + {\XMLval{mmp}{\xmlatt{#1}{fontweight}\xmlatt{#1}{fontstyle}}{}} + +\def\setMMLpmathstyle#1% + {\XMLval{mmp}{\xmlatt{#1}{mathvariant}}{}} + +\def\doMMPpcolor#1% + {\doifelsenothing{\xmlatt{#1}{color}} \firstofoneargument {\color[\xmlatt{#1}{color}]}} + +\def\doMMPpbackground#1% + {\doifelsenothing{\xmlatt{#1}{background}} + {\firstofoneargument} + {\inframed + [\c!frame=\v!off, + \c!background=\v!color, + \c!backgroundcolor=\xmlatt{#1}{background}]}} + +\def\doMMPpsometext#1#2% + {\doMMPpbackground{#1}{\doMMPpcolor{#1}{\setMMLptextstyle{#1}\ignorespaces#2\removeunwantedspaces}}} + +\def\doMMLfiller#1% bugged + {\pushmacro\doMMLfiller + \let\doMMLfiller\gobbleoneargument + \gdef\dodoMMLfiller{\disablefiller\mathematics{#1}}% + \hbox + {\def\normalorfiller##1##2% + {\gdef\dodoMMLfiller{\enablefiller#1}% + \let\normalorfiller\gobbletwoarguments}% + $#1$}% + \popmacro\doMMLfiller} + +% setups + +% \defineXMLentity[_] {{\_{}}} +% \defineXMLentity[^] {{\^{}}} + +% \defineXMLentity[_] {\string_} +% \defineXMLentity[^] {\normalorfiller\hat\widehat} + +\startsetups mml:semantics % todo: width=ex/ex/pt + \xmlflush{#1} +\stopsetups + +% \startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground +% \edef\MMPidentifier{\xmlstripped{#1}{*}} +% \doifXMLentityelse{\detokenize\expandafter{\MMPidentifier}} { +% \getXMLentity\MMPidentifier +% } { +% \MMPidentifier +% } +% \stopxmlsetups + +\startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground + \ctxlua{lxml.mml.prepare_identifier("#1","*")} +\stopxmlsetups + +\startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground + \begingroup + \mr \ctxlua{lxml.mml.prepare_number("#1","*")}% + \endgroup +\stopxmlsetups + +% hbox will make . and , behave ok, see rep patterns above as alternative +% +% \startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground +% \mathop{\hbox{\mr \ctxlua{lxml.mml.prepare_number("#1","*")}}}% we need . and , properly spaced +% \stopxmlsetups + +% \startxmlsetups mml:mo +% \edef\MMPoperator{\ctxlua{lxml.mml.prepare_operator("#1","*")}} +% \doifXMLentityelse{\detokenize\expandafter{\MMPoperator}} { +% \getXMLentity\MMPoperator +% } { +% \MMPoperator +% } +% \stopxmlsetups + +% also ok: + +\startxmlsetups mml:mo + \ctxlua{lxml.mml.prepare_operator("#1","*")} +\stopxmlsetups + +\startxmlsetups mml:mrow + \begingroup + \ifcase\xmlcount{#1}{/mml:mo}\relax + \xmlflush{#1} + \else % no \let + \def\MMLleft {\left } + \def\MMLright{\right} + \enabledelimiter + \checkdelimiters{\xmlall{#1}{/mml:mo}} + \fakeleftdelimiter + \xmlflush{#1} + \fakerightdelimiter + \disabledelimiter + \fi + \endgroup +\stopxmlsetups + +\startxmlsetups mml:mstyle + \begingroup + \setMMLpmathstyle{#1} + \xmlflush{#1} + \endgroup +\stopxmlsetups + +\startxmlsetups mml:ms + \xmlattdef{#1}{lquot}{"} + \doMMPpsometext{#1}{\xmlflush{#1}} + \xmlattdef{#1}{rquot}{"} +\stopxmlsetups + +\startxmlsetups mml:mtext + \hbox \bgroup \tf % else encoding problems, we can make mr an option + \doMMPpsometext{#1}{\xmlflush{#1}} + \egroup +\stopxmlsetups + +\startxmlsetups mml:merror + \hbox{$\displaystyle\xmlflush{#1}$} +\stopxmlsetups + +\startxmlsetups mml:mphantom + \phantom{{}\xmlflush{#1}{}} +\stopxmlsetups + +\startxmlsetups mml:mpadded + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups mml:mfenced % {} around separator is needed for spacing + \edef\MMPopen {\xmlatt{#1}{open}} + \edef\MMPclose {\xmlatt{#1}{close}} + \edef\MMPseparators{\xmlatt{#1}{separators}} + \ifx\MMPseparators\empty \def\MMPseparators{,}\fi + \doifelsenothing \MMPopen { + \left. + } { + \left\MMPopen + } + \ctxlua{lxml.mml.connect("#1","/*","\MMPseparators")}% + \doifelsenothing \MMPclose { + \right. + } { + \right\MMPclose + } +\stopxmlsetups + +\startxmlsetups mml:menclose % notation=..... + % we will implement this when we need it + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups mml:msqrt + \sqrt{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:mroot + \root{\xmlindex{#1}{*}{1}}\of{\xmlindex{#1}{*}{2}} +\stopxmlsetups + +\startsetups mml:mfrac % dodo: handle linethickness in lua + unit + \begingroup + \edef\MMPlinethickness{\xmlatt{#1}{linethickness}} + \ifx\MMPlinethickness\empty + \doifelse{\xmlatt{#1}{bevelled}}{true} { + \xmlindex{#1}{/*}{1} + \mathpunct{\kern-.2ex\left.\middle/\right.\kern-.25ex} + \xmlindex{#1}{/*}{2} + } { + \frac{\xmlindex{#1}{/*}{1}}{\xmlindex{#1}{/*}{2}} + } + \else + \processaction + [\MMPlinethickness] + [ thin=>\scratchdimen=.2pt, + medium=>\scratchdimen=.4pt, + thick=>\scratchdimen=.8pt, + unknown=>\setdimensionwithunit\scratchdimen{\MMPlinethickness}{pt}] + { + {\xmlindex{#1}{/*}{1}} + \above\scratchdimen + {\xmlindex{#1}{/*}{2}} + } + \fi + \endgroup +\stopsetups + +\startsetups mml:mspace % todo: width=ex/ex/pt + \hskip.5em\relax +\stopsetups + +% {} around first component is essential! + +\startsetups mml:msub + {\xmlindex{#1}{/*}{1}}_{\xmlindex{#1}{/*}{2}} +\stopsetups + +\startsetups mml:msup + {\xmlindex{#1}{/*}{1}}^{\xmlindex{#1}{/*}{2}} +\stopsetups + +\startsetups mml:msubsup + {\xmlindex{#1}{/*}{1}}_{\xmlindex{#1}{/*}{2}}^{\xmlindex{#1}{/*}{3}} +\stopsetups + +\startsetups mml:mover + \mathop { + \edef\mmlovertoken{\xmlraw{#1}{/mml:mo[position()==2]}} + \doifelse{\utfmathclass\mmlovertoken}{accent} { + \utfmathcommand\mmlovertoken{\xmlindex{#1}{/*}{1}} + } { + \vbox { + \m@th\ialign { + \hss##\hss\crcr + \noalign{\kern3\p@}% + \disabledelimiter\doMMLfiller{ + \xmlindex{#1}{/*}{2} + }\crcr + \noalign{\kern3\p@\nointerlineskip}% + \disabledelimiter\doMMLfiller{ + \xmlindex{#1}{/*}{1} + }\crcr + } + } + } + } + \limits +\stopsetups + +\startsetups mml:munder + \mathop { + \vtop { + \m@th\ialign{ + \hss##\hss\crcr + \disabledelimiter\doMMLfiller{\xmlindex{#1}{/*}{1}}\crcr + \noalign{\kern3\p@\nointerlineskip}% + \disabledelimiter\doMMLfiller{\xmlindex{#1}{/*}{2}}\crcr + \noalign{\kern3\p@} + } + } + } + \limits +\stopsetups + +\startsetups mml:munderover + \edef\mmlunderovertoken{\xmlraw{#1}{/mml:mo[position()==1]}} +% \doifelse{\utfmathclass\mmlunderovertoken}{limop} { +% \utfmathcommand\mmlunderovertoken +% } { +% \xmlindex{#1}{/*}{1} +% { + \utfmathcommanddefault\mmlunderovertoken{xmlindex}{{#1}{/*}{1}} + _{\disablefiller\disabledelimiter\xmlindex{#1}{/*}{2}} + ^{\disablefiller\disabledelimiter\xmlindex{#1}{/*}{3}} +\stopsetups + +\startxmlsetups mml:mlabeledtr + \bTR \xmlall{#1}{/mml:mtd} \eTR +\stopxmlsetups + +\startxmlsetups mml:mtr + \bTR \xmlall{#1}{/mml:mtd} \eTR +\stopxmlsetups + +\startxmlsetups mml:mtd + \bTD$\MMLhack\xmlall{#1}{/*}\relax$\eTD +\stopxmlsetups + +\startxmlsetups mml:mtable + \vcenter \bgroup + \bTABLE[\c!frame=\v!off] + \xmlall{#1}{/mml:mtr|mml:mlabeledtr} + \eTABLE + \egroup +\stopxmlsetups + +\startxmlsetups mml:mmultiscripts + \ctxlua{lxml.mml.multiscripts("#1")} +\stopxmlsetups + +\protect \endinput |