summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-06-07 08:17:45 +0200
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-06-07 08:17:45 +0200
commite3a0d092848f3f128742ffe478334651ab18e8dc (patch)
treed4ab51ab52cd72d343fe5d72b9e11adf81642460 /tex
parent75be509021abdcd01f7d5caf35d026647042322a (diff)
downloadcontext-e3a0d092848f3f128742ffe478334651ab18e8dc.tar.gz
2021-06-07 08:07:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-nl.mkii1
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua8
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context-todo.tex5
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/grph-pat.lua3
-rw-r--r--tex/context/base/mkiv/mult-low.lua2
-rw-r--r--tex/context/base/mkiv/mult-prm.lua2
-rw-r--r--tex/context/base/mkiv/s-inf-01-pdf-keep.pdfbin23890 -> 0 bytes
-rw-r--r--tex/context/base/mkiv/s-inf-03-pdf-keep.pdfbin230077 -> 0 bytes
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin23890 -> 23893 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin230077 -> 230133 bytes
-rw-r--r--tex/context/base/mkxl/anch-pos.mkxl2
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/driv-ini.lmt2
-rw-r--r--tex/context/base/mkxl/font-fmp.lmt14
-rw-r--r--tex/context/base/mkxl/node-ref.lmt6
-rw-r--r--tex/context/base/mkxl/page-par.mkxl12
-rw-r--r--tex/context/base/mkxl/spac-par.mkxl20
-rw-r--r--tex/context/base/mkxl/spac-ver.mkxl4
-rw-r--r--tex/context/base/mkxl/strc-not.mklx16
-rw-r--r--tex/context/base/mkxl/syst-aux.mkxl12
-rw-r--r--tex/context/base/mkxl/syst-ini.mkxl4
-rw-r--r--tex/context/base/mkxl/typo-cap.mkxl5
-rw-r--r--tex/context/base/mkxl/typo-del.mkxl16
-rw-r--r--tex/context/base/mkxl/typo-drp.mkxl8
-rw-r--r--tex/context/base/mkxl/typo-fln.mkxl4
-rw-r--r--tex/context/interface/mkii/keys-nl.xml1
-rw-r--r--tex/context/modules/mkiv/x-asciimath.mkiv4
-rw-r--r--tex/context/modules/mkxl/m-system-readers.mkxl (renamed from tex/context/modules/mkiv/m-system-readers.mkxl)0
-rw-r--r--tex/context/modules/mkxl/m-timing.mkxl (renamed from tex/context/modules/mkiv/m-timing.mkxl)0
-rw-r--r--tex/context/modules/mkxl/s-languages-goodies.lmt (renamed from tex/context/modules/mkiv/s-languages-goodies.lmt)0
-rw-r--r--tex/context/modules/mkxl/s-languages-goodies.mkxl (renamed from tex/context/modules/mkiv/s-languages-goodies.mkxl)0
-rw-r--r--tex/context/modules/mkxl/s-system-macros.mkxl (renamed from tex/context/modules/mkiv/s-system-macros.mkxl)0
-rw-r--r--tex/context/modules/mkxl/s-system-tokens.mkxl (renamed from tex/context/modules/mkiv/s-system-tokens.mkxl)0
-rw-r--r--tex/context/modules/mkxl/x-mathml.lmt910
-rw-r--r--tex/context/modules/mkxl/x-mathml.mkxl2448
-rw-r--r--tex/context/patterns/mkxl/lang-de.llg (renamed from tex/context/patterns/lmtx/lang-de.llg)0
-rw-r--r--tex/context/patterns/mkxl/lang-en.llg (renamed from tex/context/patterns/lmtx/lang-en.llg)0
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
43 files changed, 3452 insertions, 71 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index aac7ad364..6671dcdd1 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.06.04 17:20}
+\newcontextversion{2021.06.07 08:05}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index b0041b657..f22901bf5 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.06.04 17:20}
+\edef\contextversion{2021.06.07 08:05}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii
index ce87e0b93..78445f695 100644
--- a/tex/context/base/mkii/mult-nl.mkii
+++ b/tex/context/base/mkii/mult-nl.mkii
@@ -1265,6 +1265,7 @@
\setinterfaceconstant{symbolset}{symboolset}
\setinterfaceconstant{symcolor}{symkleur}
\setinterfaceconstant{symstyle}{symletter}
+\setinterfaceconstant{synchronize}{synchronize}
\setinterfaceconstant{synonym}{synoniem}
\setinterfaceconstant{synonymcolor}{synoniemkleur}
\setinterfaceconstant{synonymcommand}{synoniemcommando}
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index 10d87e139..f95ac301c 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -20,16 +20,8 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- more efficient approach is stable enough to move the original code to the obsolete
-- module.
--
--- to be considered:
---
--- 0.528 local foo = tex.ctxcatcodes
--- 0.651 local foo = getcount("ctxcatcodes")
--- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes")
-
-- maybe:  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔) (old)
-- note : tex.print == line with endlinechar appended
--- todo : context("%bold{total: }%s",total)
--- todo : context.documentvariable("title")
--
-- During the crited project we ran into the situation that luajittex was 10-20 times
-- slower that luatex ... after 3 days of testing and probing we finally figured out that
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d4815dd08..2b0da3435 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.06.04 17:20}
+\newcontextversion{2021.06.07 08:05}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context-todo.tex b/tex/context/base/mkiv/context-todo.tex
index 6aa5bca08..e9345c409 100644
--- a/tex/context/base/mkiv/context-todo.tex
+++ b/tex/context/base/mkiv/context-todo.tex
@@ -169,6 +169,11 @@ concern \LUATEX\ have been removed from the agenda but some improvements in
\stopitem
\stopitemize
+% should be in lpdf namespace:
+%
+% ./grph-pat.lua 69: local l = new_literal(lpdf.patternstream(p,width,height))
+
+
\stopsubject
\stoptext
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index ac9434b86..b6e4c672d 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.06.04 17:20}
+\edef\contextversion{2021.06.07 08:05}
%D Kind of special:
diff --git a/tex/context/base/mkiv/grph-pat.lua b/tex/context/base/mkiv/grph-pat.lua
index 4310af672..7954e9fee 100644
--- a/tex/context/base/mkiv/grph-pat.lua
+++ b/tex/context/base/mkiv/grph-pat.lua
@@ -9,7 +9,8 @@ if not modules then modules = { } end modules ['grph-pat'] = {
-- This is just a proof of concept. Viewers behave different (offsets) and Acrobat doesn't
-- show xform based patterns.
--
--- This module will be cleaned up and use codeinjections and such.
+-- This module will be cleaned up and use codeinjections and such. It should be in the lpdf
+-- namespace.
local texsetbox = tex.setbox
local texgetbox = tex.getbox
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 2745fb52a..13ebb8fcb 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -227,7 +227,7 @@ return {
--
"doglobal", "dodoglobal", "redoglobal", "resetglobal",
--
- "donothing", "dontcomplain", "forgetall",
+ "donothing", "untraceddonothing", "dontcomplain", "forgetall",
--
"donetrue", "donefalse", "foundtrue", "foundfalse",
--
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index e7eb8dde4..a3e2f2115 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -319,6 +319,7 @@ return {
"gleaders",
"glet",
"gletcsname",
+ "glettonothing",
"gluespecdef",
"glyphdatafield",
"glyphoptions",
@@ -392,6 +393,7 @@ return {
"letcsname",
"letfrozen",
"letprotected",
+ "lettonothing",
"linedirection",
"linepar",
"localbrokenpenalty",
diff --git a/tex/context/base/mkiv/s-inf-01-pdf-keep.pdf b/tex/context/base/mkiv/s-inf-01-pdf-keep.pdf
deleted file mode 100644
index 0002d614e..000000000
--- a/tex/context/base/mkiv/s-inf-01-pdf-keep.pdf
+++ /dev/null
Binary files differ
diff --git a/tex/context/base/mkiv/s-inf-03-pdf-keep.pdf b/tex/context/base/mkiv/s-inf-03-pdf-keep.pdf
deleted file mode 100644
index b037b49ab..000000000
--- a/tex/context/base/mkiv/s-inf-03-pdf-keep.pdf
+++ /dev/null
Binary files differ
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 0002d614e..ce6002720 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index b037b49ab..bc07c3a2b 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkxl/anch-pos.mkxl b/tex/context/base/mkxl/anch-pos.mkxl
index d217f2cac..6b482dc05 100644
--- a/tex/context/base/mkxl/anch-pos.mkxl
+++ b/tex/context/base/mkxl/anch-pos.mkxl
@@ -406,7 +406,7 @@
\permanent\let\disableparpositions\relax
-\aliased\let\registerparoptions\relax
+\permanent\lettonothing\registerparoptions % hooks into everypar
\permanent\protected\def\doregisterparoptions
{\iftrialtypesetting \orelse\ifinpagebody \orelse\ifmmode \orelse\ifinformula \else
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 05c0fc8b2..79bb909ab 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.06.04 17:20}
+\newcontextversion{2021.06.07 08:05}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index bbd67d48b..ccd340d28 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.06.04 17:20}
+\immutable\edef\contextversion{2021.06.07 08:05}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/driv-ini.lmt b/tex/context/base/mkxl/driv-ini.lmt
index 729196e87..40b351d84 100644
--- a/tex/context/base/mkxl/driv-ini.lmt
+++ b/tex/context/base/mkxl/driv-ini.lmt
@@ -316,7 +316,7 @@ do
local filename = nil
drivers.install {
- name = "default",
+ name = "default", -- "pdf"
actions = {
convert = drivers.converters.engine,
outputfilename = function(driver)
diff --git a/tex/context/base/mkxl/font-fmp.lmt b/tex/context/base/mkxl/font-fmp.lmt
index f35c96f49..dc70a70e8 100644
--- a/tex/context/base/mkxl/font-fmp.lmt
+++ b/tex/context/base/mkxl/font-fmp.lmt
@@ -8,8 +8,13 @@ if not modules then modules = { } end modules ['font-fmp'] = {
-- We only need to pick up the filename and optionally the enc file as we only use
-- them for old school virtual math fonts. We might as well drop this completely.
--- This used to be a backend module but the code is rather generic so we just put it
--- here now.
+-- This used to be a backend module but the code is rather generic so for now we
+-- just put it here.
+--
+-- As Type 1 is kind of obsolete I don't expect usage of those fonts in ways that
+-- are not yet covered. Actually, we don't need map files at all because we read the
+-- afm files. Maybe for math but there at some point we'll ditch the virtual old
+-- school variants because afaik ConTeXt users are not using these any longer.
local find, match, splitlines = string.find, string.match, string.splitlines
@@ -99,7 +104,10 @@ function mappings.loadline(how,line)
end
function mappings.reset()
- lpdf.setmapfile("") -- tricky ... backend related
+ local setmapfile = lpdf and lpdf.setmapfile
+ if setmapfile then
+ setmapfile("") -- tricky ... backend related
+ end
end
mappings.getentry = getentry
diff --git a/tex/context/base/mkxl/node-ref.lmt b/tex/context/base/mkxl/node-ref.lmt
index 78ff824c9..a7b624591 100644
--- a/tex/context/base/mkxl/node-ref.lmt
+++ b/tex/context/base/mkxl/node-ref.lmt
@@ -100,7 +100,9 @@ local dir_code = nodecodes.dir
local par_code = nodecodes.par
local leftskip_code = gluecodes.leftskip
+local lefthang_code = gluecodes.lefthangskip
local rightskip_code = gluecodes.rightskip
+local righthang_code = gluecodes.righthangskip
local parfillleftskip_code = gluecodes.parfillleftskip
local parfillskip_code = gluecodes.parfillskip
@@ -359,9 +361,9 @@ local inject_areas do
goto NEXT
elseif id == glue_code then
local subtype = getsubtype(current)
- if subtype == leftskip_code or subtype == parfillleftskip_code then
+ if subtype == leftskip_code or subtype == lefthang_code or subtype == parfillleftskip_code then
goto NEXT
- elseif subtype == rightskip_code or subtype == parfillskip_code then
+ elseif subtype == rightskip_code or subtype == righthang_code or subtype == parfillskip_code then
if reference and (done[reference] or 0) == 0 then
head, current = inject_range(head,first,last,reference,parent,pardir,firstdir)
reference = nil
diff --git a/tex/context/base/mkxl/page-par.mkxl b/tex/context/base/mkxl/page-par.mkxl
index c198784dc..4cfc3f9bf 100644
--- a/tex/context/base/mkxl/page-par.mkxl
+++ b/tex/context/base/mkxl/page-par.mkxl
@@ -22,7 +22,7 @@
\definecounter[\v!paragraph]
-\permanent\let\showparagraphnumber\relax
+\permanent\lettonothing\showparagraphnumber
\appendtoks
\page_par_check_state
@@ -36,16 +36,16 @@
\lastnamedcs
\fi}
-\setvalue{\??paragraphnumberingvariants\v!start}%
+\defcsname\??paragraphnumberingvariants\v!start\endcsname
{\enforced\let\showparagraphnumber\page_par_show_number_normal}
-\setvalue{\??paragraphnumberingvariants\v!stop}%
- {\enforced\let\showparagraphnumber\relax}
+\defcsname\??paragraphnumberingvariants\v!stop\endcsname
+ {\enforced\lettonothing\showparagraphnumber}
-\setvalue{\??paragraphnumberingvariants\v!line}%
+\defcsname\??paragraphnumberingvariants\v!line\endcsname
{\enforced\let\showparagraphnumber\page_par_show_number_lines}
-\setvalue{\??paragraphnumberingvariants\v!reset}%
+\defcsname\??paragraphnumberingvariants\v!reset\endcsname
{\strc_counters_reset\v!paragraph
\enforced\let\showparagraphnumber\page_par_show_number_normal}
diff --git a/tex/context/base/mkxl/spac-par.mkxl b/tex/context/base/mkxl/spac-par.mkxl
index 66b08633d..6c3927861 100644
--- a/tex/context/base/mkxl/spac-par.mkxl
+++ b/tex/context/base/mkxl/spac-par.mkxl
@@ -104,7 +104,7 @@
\installcorenamespace {parwrapafter}
\installcorenamespace {parwrapcount}
-\let\spac_paragraph_wrap\relax
+\lettonothing\spac_paragraph_wrap
\newcount\c_spac_paragraph_group_level
@@ -147,7 +147,7 @@
\clf_setparwrapper{#3}#4}%
#2\csname\??parwrapafter #3\endcsname{#5}%
\clf_newparwrapper{#3}%
- \enforced\let\spac_paragraph_wrap\spac_paragraph_update}
+ \let\spac_paragraph_wrap\spac_paragraph_update}
\def\spac_register_par_wrapper_nop#1#2#3#4#5%
{\ifcsname\??parwrapcount#3\endcsname \else
@@ -212,7 +212,7 @@
\setparagraphfreezing
-\appendtoks\enforced\let\spac_paragraph_wrap\relax\to\everyforgetall
+\appendtoks\lettonothing\spac_paragraph_wrap\to\everyforgetall
%D In due time, the code below will be upgraded using the above mechanisms.
@@ -250,8 +250,6 @@
\installcorenamespace{paragraphintro}
-\let\spac_paragraphs_flush_intro\relax % hook into everypar
-
\newtoks\t_spac_paragraphs_intro_first
\newtoks\t_spac_paragraphs_intro_next
\newtoks\t_spac_paragraphs_intro_each
@@ -260,8 +258,8 @@
\newconditional\c_spac_paragraphs_intro_next
\newconditional\c_spac_paragraphs_intro_each
-\let\spac_paragraphs_flush_intro\relax
-\let\spac_paragraphs_intro_step \relax
+\lettonothing\spac_paragraphs_flush_intro
+\lettonothing\spac_paragraphs_intro_step
\permanent\protected\tolerant\def\setupparagraphintro[#1]#*[#2]%
{\def\spac_paragraphs_intro_step##1%
@@ -277,7 +275,7 @@
\global\t_spac_paragraphs_intro_first\emptytoks
\global\t_spac_paragraphs_intro_next \emptytoks
\global\t_spac_paragraphs_intro_each \emptytoks
- \glet\spac_paragraphs_flush_intro\relax}
+ \glettonothing\spac_paragraphs_flush_intro}
\defcsname\??paragraphintro\v!first\endcsname#1%
{\global\settrue\c_spac_paragraphs_intro_first
@@ -372,7 +370,7 @@
\the\t_spac_paragraphs_intro_next
\the\t_spac_paragraphs_intro_each
\else
- \glet\spac_paragraphs_flush_intro\relax
+ \glettonothing\spac_paragraphs_flush_intro
\the\t_spac_paragraphs_intro_next
\fi}}
@@ -385,7 +383,7 @@
%D This macro collects data that will be flushed at the next paragraph. By using
%D this macro you can avoid interfering nodes (writes, etc).
-\aliased\let\flushpostponednodedata\relax % hook into everypar
+\lettonothing\flushpostponednodedata % hook into everypar
\newbox \b_spac_postponed_data
%newcount\c_spac_postponed_data
@@ -453,7 +451,7 @@
\ifvoid\b_spac_postponed_data\else
\hpack{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data
\fi
- \enforced\glet\flushpostponednodedata\relax
+ \enforced\glettonothing\flushpostponednodedata
}%\fi}
\permanent\protected\def\doflushatpar % might be renamed
diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl
index d11611339..1e630c5bf 100644
--- a/tex/context/base/mkxl/spac-ver.mkxl
+++ b/tex/context/base/mkxl/spac-ver.mkxl
@@ -1356,10 +1356,10 @@
\newcount\c_spac_keep_lines_together
-\aliased\let\restoreinterlinepenalty\relax
+\permanent\lettonothing\restoreinterlinepenalty
\protected\def\spac_penalties_restore
- {\global\enforced\let\restoreinterlinepenalty\relax
+ {\enforced\glettonothing\restoreinterlinepenalty
\overloaded\global\resetpenalties\interlinepenalties
\global\c_spac_keep_lines_together\zerocount}
diff --git a/tex/context/base/mkxl/strc-not.mklx b/tex/context/base/mkxl/strc-not.mklx
index 3faf7135b..a0691d9f1 100644
--- a/tex/context/base/mkxl/strc-not.mklx
+++ b/tex/context/base/mkxl/strc-not.mklx
@@ -1287,8 +1287,8 @@
\fi}
\appendtoks
- \enforced\let\flushnotes \relax
- \enforced\let\postponenotes\relax
+ \enforced\lettonothing\flushnotes
+ \enforced\lettonothing\postponenotes
\forgetall
\resetallattributes % new, we don't want color bleed into notes
\inheritmaintextcolor % but we do want to obey the textcolor
@@ -1517,7 +1517,7 @@
\fi
\fi}
-\aliased\let\flushnotes\relax
+\permanent\lettonothing\flushnotes
% also \ifcase\insertionmigrationmode here, needs testing:
@@ -1534,8 +1534,8 @@
\permanent\protected\def\doflushnotes
{\ifconditional\postponingnotes
\begingroup
- \enforced\let\flushnotes \relax
- \enforced\let\postponenotes\relax
+ \enforced\lettonothing\flushnotes
+ \enforced\lettonothing\postponenotes
\ifconditional\postponednote
\ifhmode
% needed for tagging ... otherwise we get some weird node free error
@@ -1545,7 +1545,7 @@
\clf_flushpostponednotes% this also resets the states !
\global\setfalse\postponednote
\global\setfalse\postponingnotes
- \enforced\glet\flushnotes\relax
+ \enforced\glettonothing\flushnotes
\endgroup
\fi}
@@ -1563,8 +1563,8 @@
\newtoks\everyplacelocalnotes
\appendtoks
- \enforced\let\flushnotes \relax
- \enforced\let\postponenotes\relax
+ \enforced\lettonothing\flushnotes
+ \enforced\lettonothing\postponenotes
\to \everyplacelocalnotes
\newconditional\inlocalnotes
diff --git a/tex/context/base/mkxl/syst-aux.mkxl b/tex/context/base/mkxl/syst-aux.mkxl
index 21b1a66ef..fea524bee 100644
--- a/tex/context/base/mkxl/syst-aux.mkxl
+++ b/tex/context/base/mkxl/syst-aux.mkxl
@@ -216,7 +216,17 @@
%D Reserved macros for tests:
-\aliased\let\donothing\empty
+%D A \type \type {\let} is more efficient than a \type {\def} so we often let something
+%D to relax or do nothing. However, we then loose the name in tracing. For that we now
+%D have \type {\lettonothing \foo} which is efficient but also keeps the name. Of course
+%D this is no solution for commands that take arguments but at least it helps tracing a
+%D bit. We keep of course \type {\donothing}.
+
+%D Maybe even nicer is a let that aliases but keeps the name.
+
+% \aliased\let\donothing\empty
+ \immutable\def\donothing {} % better in tracing
+%untraced\immutable\def\untraceddonothing{}
\let\m_syst_string_one \empty
\let\m_syst_string_two \empty
diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl
index d147e07aa..d87277657 100644
--- a/tex/context/base/mkxl/syst-ini.mkxl
+++ b/tex/context/base/mkxl/syst-ini.mkxl
@@ -681,8 +681,8 @@
\permanent\protected\def\tracingall
{\tracingonline \plusone
- \tracingcommands \plusthree
- \tracingmacros \plustwo
+ \tracingcommands \plusfour % > 3: show mode change independent
+ \tracingmacros \plusthree % > 2: obey \untraced
\tracingoutput \plusone
\tracingpages \plusone
\tracingparagraphs\plusone
diff --git a/tex/context/base/mkxl/typo-cap.mkxl b/tex/context/base/mkxl/typo-cap.mkxl
index afdefe923..744b09a47 100644
--- a/tex/context/base/mkxl/typo-cap.mkxl
+++ b/tex/context/base/mkxl/typo-cap.mkxl
@@ -249,8 +249,9 @@
\definefont
[MixedCaps]
-% [CurrentFont*default cp 1.2\exheight]
- [CurrentFont*default sa .8] % better adaptation to slanted
+ [CurrentFont*default cp 1.2\exheight]
+% [CurrentFont*default at 1.5\exheight] % better adaptation to slanted but still not nice
+% [CurrentFont*default ht 1.2\exheight] % maybe this is better indeed
\setupcapitals
[\v!mixed]
diff --git a/tex/context/base/mkxl/typo-del.mkxl b/tex/context/base/mkxl/typo-del.mkxl
index 8e17ea82b..4b8540368 100644
--- a/tex/context/base/mkxl/typo-del.mkxl
+++ b/tex/context/base/mkxl/typo-del.mkxl
@@ -379,9 +379,9 @@
\appendtoks
\expandafter\newcount\csname\??delimitedtextlevel\currentdelimitedtext\endcsname
- \frozen\instance\setuevalue{\currentdelimitedtext }{\delimitedtext[\currentdelimitedtext]}%
- \frozen\instance\setuevalue{\e!start\currentdelimitedtext}{\startdelimitedtext[\currentdelimitedtext]}%
- \frozen\instance\setuevalue{\e!stop \currentdelimitedtext}{\stopdelimitedtext}%
+ \frozen\instance\protected\edefcsname\currentdelimitedtext \endcsname{\delimitedtext[\currentdelimitedtext]}%
+ \frozen\instance\protected\edefcsname\e!start\currentdelimitedtext\endcsname{\startdelimitedtext[\currentdelimitedtext]}%
+ \frozen\instance\protected\edefcsname\e!stop \currentdelimitedtext\endcsname{\stopdelimitedtext}%
\to \everydefinedelimitedtext
\setupdelimitedtext
@@ -407,7 +407,7 @@
\typo_delimited_handle_middle\c!middle
\fi}
-\let\typo_delimited_repeat\relax
+\lettonothing\typo_delimited_repeat
\permanent\tolerant\protected\def\startdelimitedtext[#1]#*[#2]%
{\begingroup
@@ -437,7 +437,7 @@
\ifx\p_delimited_repeat\v!yes
\let\typo_delimited_repeat\typo_delimited_repeat_indeed
\else
- \let\typo_delimited_repeat\relax
+ \lettonothing\typo_delimited_repeat
\fi
\setfalse\c_typo_delimited_repeating
\edef\p_delimited_location{\delimitedtextparameter\c!location}%
@@ -847,7 +847,8 @@
{\dontleavehmode
\begingroup
\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext
- \usedlanguageparameter{\c!left\currentparentdelimitedtext}% was: \currentdelimitedtext
+ % \usedlanguageparameter{\c!left\currentparentdelimitedtext}% was: \currentdelimitedtext
+ \usedlanguageparameter{\c!left\currentparentdelimitedtextparent}% was: \currentdelimitedtext
\usedelimitedtextstyleandcolor\c!style\c!color
\typo_delimited_start_content
\bgroup
@@ -856,7 +857,8 @@
\def\typo_delimited_fontdriven_e
{\typo_delimited_stop_content
- \usedlanguageparameter{\c!right\currentparentdelimitedtext}% was: \currentdelimitedtext
+ % \usedlanguageparameter{\c!right\currentparentdelimitedtext}% was: \currentdelimitedtext
+ \usedlanguageparameter{\c!right\currendelimitedtextparent}% was: \currentdelimitedtext
\dostoptagged
\typo_delimited_pop
\endgroup}
diff --git a/tex/context/base/mkxl/typo-drp.mkxl b/tex/context/base/mkxl/typo-drp.mkxl
index 35bbbca8c..da11f76e7 100644
--- a/tex/context/base/mkxl/typo-drp.mkxl
+++ b/tex/context/base/mkxl/typo-drp.mkxl
@@ -71,10 +71,10 @@
\permanent\tolerant\protected\def\placeinitial[#1]% old command
{\par
\namedinitialparameter{#1}\c!before
- \edef\typo_initial_handle{\typo_initial_handle_indeed{#1}{}}}
+ \enforced\edef\typo_initial_handle{\typo_initial_handle_indeed{#1}{}}}
\permanent\tolerant\protected\def\setinitial[#1]#*[#2]%
- {\edef\typo_initial_handle{\typo_initial_handle_indeed{#1}{#2}}}
+ {\enforced\edef\typo_initial_handle{\typo_initial_handle_indeed{#1}{#2}}}
\permanent\tolerant\protected\def\flushinitial % when used inside a mechanism that forgets
{\typo_initial_handle}
@@ -110,9 +110,9 @@
\c_attr_initial\plusone
\initialparameter\c!text
\endgroup
- \glet\typo_initial_handle\relax}
+ \enforced\glettonothing\typo_initial_handle}
-\let\typo_initial_handle\relax
+\lettonothing\typo_initial_handle % hook into everypar
% \setupbodyfont[dejavu,9pt]
%
diff --git a/tex/context/base/mkxl/typo-fln.mkxl b/tex/context/base/mkxl/typo-fln.mkxl
index 3ef688bb5..a62646fff 100644
--- a/tex/context/base/mkxl/typo-fln.mkxl
+++ b/tex/context/base/mkxl/typo-fln.mkxl
@@ -88,9 +88,9 @@
% \kern\zeropoint % we need a node
% \hskip\zeropoint\s!plus\emwidth\relax % can be an option
\endgroup
- \glet\typo_firstline_handle\relax}
+ \glettonothing\typo_firstline_handle}
-\let\typo_firstline_handle\relax
+\lettonothing\typo_firstline_handle
% goodie, question on list
%
diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml
index a0da8b763..2312b7675 100644
--- a/tex/context/interface/mkii/keys-nl.xml
+++ b/tex/context/interface/mkii/keys-nl.xml
@@ -1271,6 +1271,7 @@
<cd:constant name='symbolset' value='symboolset'/>
<cd:constant name='symcolor' value='symkleur'/>
<cd:constant name='symstyle' value='symletter'/>
+ <cd:constant name='synchronize' value='synchronize'/>
<cd:constant name='synonym' value='synoniem'/>
<cd:constant name='synonymcolor' value='synoniemkleur'/>
<cd:constant name='synonymcommand' value='synoniemcommando'/>
diff --git a/tex/context/modules/mkiv/x-asciimath.mkiv b/tex/context/modules/mkiv/x-asciimath.mkiv
index 32eaf2af2..bd9b847d9 100644
--- a/tex/context/modules/mkiv/x-asciimath.mkiv
+++ b/tex/context/modules/mkiv/x-asciimath.mkiv
@@ -174,7 +174,7 @@
\def\asciimath_yes[#1]#2%
{\mathematics
[#1]%
- {\the\everyasciimath%
+ {\the\everyasciimath
\clf_justasciimath{\detokenize\expandafter{\normalexpanded{#2}}}}}
\def\asciimath_nop#1%
@@ -191,7 +191,7 @@
\def\xmlasciimath_yes[#1]#2%
{\mathematics
[#1]%
- {\the\everyasciimath%
+ {\the\everyasciimath
\clf_xmlasciimath{#2}}}
\def\xmlasciimath_nop#1%
diff --git a/tex/context/modules/mkiv/m-system-readers.mkxl b/tex/context/modules/mkxl/m-system-readers.mkxl
index 0f2d3275e..0f2d3275e 100644
--- a/tex/context/modules/mkiv/m-system-readers.mkxl
+++ b/tex/context/modules/mkxl/m-system-readers.mkxl
diff --git a/tex/context/modules/mkiv/m-timing.mkxl b/tex/context/modules/mkxl/m-timing.mkxl
index 3edfd14e2..3edfd14e2 100644
--- a/tex/context/modules/mkiv/m-timing.mkxl
+++ b/tex/context/modules/mkxl/m-timing.mkxl
diff --git a/tex/context/modules/mkiv/s-languages-goodies.lmt b/tex/context/modules/mkxl/s-languages-goodies.lmt
index 7256fd35d..7256fd35d 100644
--- a/tex/context/modules/mkiv/s-languages-goodies.lmt
+++ b/tex/context/modules/mkxl/s-languages-goodies.lmt
diff --git a/tex/context/modules/mkiv/s-languages-goodies.mkxl b/tex/context/modules/mkxl/s-languages-goodies.mkxl
index 3ced071be..3ced071be 100644
--- a/tex/context/modules/mkiv/s-languages-goodies.mkxl
+++ b/tex/context/modules/mkxl/s-languages-goodies.mkxl
diff --git a/tex/context/modules/mkiv/s-system-macros.mkxl b/tex/context/modules/mkxl/s-system-macros.mkxl
index 605859000..605859000 100644
--- a/tex/context/modules/mkiv/s-system-macros.mkxl
+++ b/tex/context/modules/mkxl/s-system-macros.mkxl
diff --git a/tex/context/modules/mkiv/s-system-tokens.mkxl b/tex/context/modules/mkxl/s-system-tokens.mkxl
index b83a4f47b..b83a4f47b 100644
--- a/tex/context/modules/mkiv/s-system-tokens.mkxl
+++ b/tex/context/modules/mkxl/s-system-tokens.mkxl
diff --git a/tex/context/modules/mkxl/x-mathml.lmt b/tex/context/modules/mkxl/x-mathml.lmt
new file mode 100644
index 000000000..ba05c002e
--- /dev/null
+++ b/tex/context/modules/mkxl/x-mathml.lmt
@@ -0,0 +1,910 @@
+if not modules then modules = { } end modules ['x-mathml'] = {
+ version = 1.001,
+ comment = "companion to x-mathml.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This needs an upgrade to the latest greatest mechanisms. But ... it
+-- probably doesn't pay back as no mathml support ever did.
+
+local type, next = type, next
+local formatters, lower, find, gsub, match = string.formatters, string.lower, string.find, string.gsub, string.match
+local strip = string.strip
+local xmlsprint, xmlcprint, xmltext, xmlcontent, xmlempty = xml.sprint, xml.cprint, xml.text, xml.content, xml.empty
+local lxmlcollected, lxmlfilter = lxml.collected, lxml.filter
+local getid = lxml.getid
+local utfchar, utfcharacters, utfsplit, utflen = utf.char, utf.characters, utf.split, utf.len
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local P, Cs = lpeg.P, lpeg.Cs
+
+local mathml = { }
+moduledata.mathml = mathml
+lxml.mathml = mathml -- for the moment
+
+local context = context
+
+local ctx_enabledelimiter = context.enabledelimiter
+local ctx_disabledelimiter = context.disabledelimiter
+local ctx_xmlflush = context.xmlflush -- better xmlsprint
+
+local ctx_halign = context.halign
+local ctx_noalign = context.noalign
+local ctx_bgroup = context.bgroup
+local ctx_egroup = context.egroup
+local ctx_crcr = context.crcr
+
+local ctx_bTABLE = context.bTABLE
+local ctx_eTABLE = context.eTABLE
+local ctx_bTR = context.bTR
+local ctx_eTR = context.eTR
+local ctx_bTD = context.bTD
+local ctx_eTD = context.eTD
+
+local ctx_mn = context.mn
+local ctx_mi = context.mi
+local ctx_mo = context.mo
+local ctx_startimath = context.startimath
+local ctx_ignorespaces = context.ignorespaces
+local ctx_removeunwantedspaces = context.removeunwantedspaces
+local ctx_stopimath = context.stopimath
+
+local ctx_mmlapplycsymbol = context.mmlapplycsymbol
+
+local ctx_mathopnolimits = context.mathopnolimits
+local ctx_left = context.left
+local ctx_right = context.right
+
+-- an alternative is to remap to private codes, where we can have
+-- different properties .. to be done; this will move and become
+-- generic; we can then make the private ones active in math mode
+
+-- todo: handle opening/closing mo's here ... presentation mml is such a mess ...
+
+-- characters.registerentities()
+
+local doublebar = utfchar(0x2016)
+
+local n_replacements = {
+-- [" "] = utfchar(0x2002), -- "&textspace;" -> tricky, no &; in mkiv
+ ["."] = "{.}",
+ [","] = "{,}",
+ [" "] = "",
+}
+
+local l_replacements = { -- in main table
+ ["|"] = "\\mmlleftdelimiter\\vert",
+ ["{"] = "\\mmlleftdelimiter\\lbrace",
+ ["("] = "\\mmlleftdelimiter(",
+ ["["] = "\\mmlleftdelimiter[",
+ ["<"] = "\\mmlleftdelimiter<",
+ [doublebar] = "\\mmlleftdelimiter\\Vert",
+}
+local r_replacements = { -- in main table
+ ["|"] = "\\mmlrightdelimiter\\vert",
+ ["}"] = "\\mmlrightdelimiter\\rbrace",
+ [")"] = "\\mmlrightdelimiter)",
+ ["]"] = "\\mmlrightdelimiter]",
+ [">"] = "\\mmlrightdelimiter>",
+ [doublebar] = "\\mmlrightdelimiter\\Vert",
+}
+
+-- todo: play with asciimode and avoid mmlchar
+
+-- we can use the proper names now! todo
+
+local o_replacements = { -- in main table
+ ["@l"] = "\\mmlleftdelimiter.",
+ ["@r"] = "\\mmlrightdelimiter.",
+ ["{"] = "\\mmlleftdelimiter \\lbrace",
+ ["}"] = "\\mmlrightdelimiter\\rbrace",
+ ["|"] = "\\mmlleftorrightdelimiter\\vert",
+ -- ["."] = "\\mmlleftorrightdelimiter.",
+ ["/"] = "\\mmlleftorrightdelimiter\\solidus",
+ [doublebar] = "\\mmlleftorrightdelimiter\\Vert",
+ ["("] = "\\mmlleftdelimiter(",
+ [")"] = "\\mmlrightdelimiter)",
+ ["["] = "\\mmlleftdelimiter[",
+ ["]"] = "\\mmlrightdelimiter]",
+ -- ["<"] = "\\mmlleftdelimiter<",
+ -- [">"] = "\\mmlrightdelimiter>",
+ ["#"] = "\\mmlchar{35}",
+ ["$"] = "\\mmlchar{36}", -- $
+ ["%"] = "\\mmlchar{37}",
+ ["&"] = "\\mmlchar{38}",
+ ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math sees the char instead of \char so we
+ ["_"] = "\\mmlchar{95}{}", -- need the {} ... has to do with active mess feedback into scanner
+ ["~"] = "\\mmlchar{126}",
+ [" "] = "",
+ ["°"] = "^\\circ", -- hack
+
+ -- [utfchar(0xF103C)] = "\\mmlleftdelimiter<",
+ [utfchar(0xF1026)] = "\\mmlchar{38}",
+ [utfchar(0x02061)] = "", -- function applicator sometimes shows up in font
+ -- [utfchar(0xF103E)] = "\\mmlleftdelimiter>",
+ -- [utfchar(0x000AF)] = '\\mmlchar{"203E}', -- 0x203E
+}
+
+local simpleoperatorremapper = utf.remapper(o_replacements)
+
+--~ languages.data.labels.functions
+
+local i_replacements = {
+ ["sin"] = "\\sin",
+ ["cos"] = "\\cos",
+ ["abs"] = "\\abs",
+ ["arg"] = "\\arg",
+ ["codomain"] = "\\codomain",
+ ["curl"] = "\\curl",
+ ["determinant"] = "\\det",
+ ["divergence"] = "\\div",
+ ["domain"] = "\\domain",
+ ["gcd"] = "\\gcd",
+ ["grad"] = "\\grad",
+ ["identity"] = "\\id",
+ ["image"] = "\\image",
+ ["lcm"] = "\\lcm",
+ ["lim"] = "\\lim",
+ ["max"] = "\\max",
+ ["median"] = "\\median",
+ ["min"] = "\\min",
+ ["mode"] = "\\mode",
+ ["mod"] = "\\mod",
+ ["polar"] = "\\Polar",
+ ["exp"] = "\\exp",
+ ["ln"] = "\\ln",
+ ["log"] = "\\log",
+ ["sin"] = "\\sin",
+ ["arcsin"] = "\\arcsin",
+ ["sinh"] = "\\sinh",
+ ["arcsinh"] = "\\arcsinh",
+ ["cos"] = "\\cos",
+ ["arccos"] = "\\arccos",
+ ["cosh"] = "\\cosh",
+ ["arccosh"] = "\\arccosh",
+ ["tan"] = "\\tan",
+ ["arctan"] = "\\arctan",
+ ["tanh"] = "\\tanh",
+ ["arctanh"] = "\\arctanh",
+ ["cot"] = "\\cot",
+ ["arccot"] = "\\arccot",
+ ["coth"] = "\\coth",
+ ["arccoth"] = "\\arccoth",
+ ["csc"] = "\\csc",
+ ["arccsc"] = "\\arccsc",
+ ["csch"] = "\\csch",
+ ["arccsch"] = "\\arccsch",
+ ["sec"] = "\\sec",
+ ["arcsec"] = "\\arcsec",
+ ["sech"] = "\\sech",
+ ["arcsech"] = "\\arcsech",
+ [" "] = "",
+
+ ["false"] = "{\\mathrm false}",
+ ["notanumber"] = "{\\mathrm NaN}",
+ ["otherwise"] = "{\\mathrm otherwise}",
+ ["true"] = "{\\mathrm true}",
+ ["declare"] = "{\\mathrm declare}",
+ ["as"] = "{\\mathrm as}",
+
+}
+
+-- we could use a metatable or when accessing fallback on the
+-- key but at least we now have an overview
+
+local csymbols = {
+ arith1 = {
+ lcm = "lcm",
+ big_lcm = "lcm",
+ gcd = "gcd",
+ big_gcd = "big_gcd",
+ plus = "plus",
+ unary_minus = "minus",
+ minus = "minus",
+ times = "times",
+ divide = "divide",
+ power = "power",
+ abs = "abs",
+ root = "root",
+ sum = "sum",
+ product = "product",
+ },
+ fns = {
+ domain = "domain",
+ range = "codomain",
+ image = "image",
+ identity = "ident",
+ -- left_inverse = "",
+ -- right_inverse = "",
+ inverse = "inverse",
+ left_compose = "compose",
+ lambda = "labmda",
+ },
+ linalg1 = {
+ vectorproduct = "vectorproduct",
+ scalarproduct = "scalarproduct",
+ outerproduct = "outerproduct",
+ transpose = "transpose",
+ determinant = "determinant",
+ vector_selector = "selector",
+ -- matrix_selector = "matrix_selector",
+ },
+ logic1 = {
+ equivalent = "equivalent",
+ ["not"] = "not",
+ ["and"] = "and",
+ -- big_and = "",
+ ["xor"] = "xor",
+ -- big_xor = "",
+ ["or"] = "or",
+ -- big-or = "",
+ implies = "implies",
+ ["true"] = "true",
+ ["false"] = "false",
+ },
+ nums1 = {
+ -- based_integer = "based_integer"
+ rational = "rational",
+ inifinity = "infinity",
+ e = "expenonentiale",
+ i = "imaginaryi",
+ pi = "pi",
+ gamma = "gamma",
+ NaN = "NaN",
+ },
+ relation1 = {
+ eq = "eq",
+ lt = "lt",
+ gt = "gt",
+ neq = "neq",
+ leq = "leq",
+ geq = "geq",
+ approx = "approx",
+ },
+ set1 = {
+ cartesian_product = "cartesianproduct",
+ empty_set = "emptyset",
+ map = "map",
+ size = "card",
+ -- suchthat = "suchthat",
+ set = "set",
+ intersect = "intersect",
+ -- big_intersect = "",
+ union = "union",
+ -- big_union = "",
+ setdiff = "setdiff",
+ subset = "subset",
+ ["in"] = "in",
+ notin = "notin",
+ prsubset = "prsubset",
+ notsubset = "notsubset",
+ notprsubset = "notprsubset",
+ },
+ veccalc1 = {
+ divergence = "divergence",
+ grad = "grad",
+ curl = "curl",
+ laplacian = "laplacian",
+ Laplacian = "laplacian",
+ },
+ calculus1 = {
+ diff = "diff",
+ -- nthdiff = "",
+ partialdiff = "partialdiff",
+ int = "int",
+ -- defint = "defint",
+ },
+ integer1 = {
+ factorof = "factorof",
+ factorial = "factorial",
+ quotient = "quotient",
+ remainder = "rem",
+ },
+ linalg2 = {
+ vector = "vector",
+ matrix = "matrix",
+ matrixrow = "matrixrow",
+ },
+ mathmkeys = {
+ -- equiv = "",
+ -- contentequiv = "",
+ -- contentequiv_strict = "",
+ },
+ rounding1 = {
+ ceiling = "ceiling",
+ floor = "floor",
+ -- trunc = "trunc",
+ -- round = "round",
+ },
+ setname1 = {
+ P = "primes",
+ N = "naturalnumbers",
+ Z = "integers",
+ rationals = "rationals",
+ R = "reals",
+ complexes = "complexes",
+ },
+ complex1 = {
+ -- complex_cartesian = "complex_cartesian", -- ci ?
+ real = "real",
+ imaginary = "imaginary",
+ -- complex_polar = "complex_polar", -- ci ?
+ argument = "arg",
+ conjugate = "conjugate",
+ },
+ interval1 = { -- not an apply
+ -- integer_interval = "integer_interval",
+ interval = "interval",
+ interval_oo = { tag = "interval", closure = "open" },
+ interval_cc = { tag = "interval", closure = "closed" },
+ interval_oc = { tag = "interval", closure = "open-closed" },
+ interval_co = { tag = "interval", closure = "closed-open" },
+ },
+ linalg3 = {
+ -- vector = "vector.column",
+ -- matrixcolumn = "matrixcolumn",
+ -- matrix = "matrix.column",
+ },
+ minmax1 = {
+ min = "min",
+ -- big_min = "",
+ max = "max",
+ -- big_max = "",
+ },
+ piece1 = {
+ piecewise = "piecewise",
+ piece = "piece",
+ otherwise = "otherwise",
+ },
+ error1 = {
+ -- unhandled_symbol = "",
+ -- unexpected_symbol = "",
+ -- unsupported_CD = "",
+ },
+ limit1 = {
+ -- limit = "limit",
+ -- both_sides = "both_sides",
+ -- above = "above",
+ -- below = "below",
+ -- null = "null",
+ tendsto = "tendsto",
+ },
+ list1 = {
+ -- map = "",
+ -- suchthat = "",
+ -- list = "list",
+ },
+ multiset1 = {
+ size = { tag = "card", type = "multiset" },
+ cartesian_product = { tag = "cartesianproduct", type = "multiset" },
+ empty_set = { tag = "emptyset", type = "multiset" },
+ -- multi_set = { tag = "multiset", type = "multiset" },
+ intersect = { tag = "intersect", type = "multiset" },
+ -- big_intersect = "",
+ union = { tag = "union", type = "multiset" },
+ -- big_union = "",
+ setdiff = { tag = "setdiff", type = "multiset" },
+ subset = { tag = "subset", type = "multiset" },
+ ["in"] = { tag = "in", type = "multiset" },
+ notin = { tag = "notin", type = "multiset" },
+ prsubset = { tag = "prsubset", type = "multiset" },
+ notsubset = { tag = "notsubset", type = "multiset" },
+ notprsubset = { tag = "notprsubset", type = "multiset" },
+ },
+ quant1 = {
+ forall = "forall",
+ exists = "exists",
+ },
+ s_dist = {
+ -- mean = "mean.dist",
+ -- sdev = "sdev.dist",
+ -- variance = "variance.dist",
+ -- moment = "moment.dist",
+ },
+ s_data = {
+ mean = "mean",
+ sdev = "sdev",
+ variance = "vriance",
+ mode = "mode",
+ median = "median",
+ moment = "moment",
+ },
+ transc1 = {
+ log = "log",
+ ln = "ln",
+ exp = "exp",
+ sin = "sin",
+ cos = "cos",
+ tan = "tan",
+ sec = "sec",
+ csc = "csc",
+ cot = "cot",
+ sinh = "sinh",
+ cosh = "cosh",
+ tanh = "tanh",
+ sech = "sech",
+ csch = "cscs",
+ coth = "coth",
+ arcsin = "arcsin",
+ arccos = "arccos",
+ arctan = "arctan",
+ arcsec = "arcsec",
+ arcscs = "arccsc",
+ arccot = "arccot",
+ arcsinh = "arcsinh",
+ arccosh = "arccosh",
+ arctanh = "arstanh",
+ arcsech = "arcsech",
+ arccsch = "arccsch",
+ arccoth = "arccoth",
+ },
+}
+
+function xml.functions.remapmmlcsymbol(e)
+ local at = e.at
+ local cd = at.cd
+ if cd then
+ cd = csymbols[cd]
+ if cd then
+ local tx = e.dt[1]
+ if tx and tx ~= "" then
+ local tg = cd[tx]
+ if tg then
+ at.cd = nil
+ at.cdbase = nil
+ e.dt = { }
+ if type(tg) == "table" then
+ for k, v in next, tg do
+ if k == "tag" then
+ e.tg = v
+ else
+ at[k] = v
+ end
+ end
+ else
+ e.tg = tg
+ end
+ end
+ end
+ end
+ end
+end
+
+function xml.functions.remapmmlbind(e)
+ e.tg = "apply"
+end
+
+function xml.functions.remapopenmath(e)
+ local tg = e.tg
+ if tg == "OMOBJ" then
+ e.tg = "math"
+ elseif tg == "OMA" then
+ e.tg = "apply"
+ elseif tg == "OMB" then
+ e.tg = "apply"
+ elseif tg == "OMS" then
+ local at = e.at
+ e.tg = "csymbol"
+ e.dt = { at.name or "unknown" }
+ at.name = nil
+ elseif tg == "OMV" then
+ local at = e.at
+ e.tg = "ci"
+ e.dt = { at.name or "unknown" }
+ at.name = nil
+ elseif tg == "OMI" then
+ e.tg = "ci"
+ end
+ e.rn = "mml"
+end
+
+function mathml.checked_operator(str)
+ context(simpleoperatorremapper(str))
+end
+
+function mathml.stripped(str)
+ context(strip(str))
+end
+
+local p_entity = (P("&") * ((1-P(";"))^0) * P(";"))
+local p_utfchar = lpegpatterns.utf8character
+local p_spacing = lpegpatterns.whitespace^1
+
+local p_mn = Cs((p_entity/"" + p_spacing/utfchar(0x205F) + p_utfchar/n_replacements)^0)
+local p_strip = Cs((p_entity/"" + p_utfchar )^0)
+local p_mi = Cs((p_entity/"" + p_utfchar/i_replacements)^0)
+
+function mathml.mn(id)
+ -- maybe at some point we need to interpret the number, but
+ -- currently we assume an upright font
+ ctx_mn(lpegmatch(p_mn,xmlcontent(getid(id)) or ""))
+end
+
+function mathml.mo(id)
+ local str = lpegmatch(p_strip,xmlcontent(getid(id)) or "")
+ context(simpleoperatorremapper(str) or str)
+end
+
+function mathml.mi(id)
+ -- we need to strip comments etc .. todo when reading in tree
+ local e = getid(id)
+ local str = e.dt
+ if type(str) == "table" then
+ local n = #str
+ if n == 0 then
+ -- nothing to do
+ elseif n == 1 then
+ local first = str[1]
+ if type(first) == "string" then
+ -- local str = gsub(first,"&.-;","") -- bah
+ -- local rep = i_replacements[str]
+ -- if not rep then
+ -- rep = gsub(str,".",i_replacements)
+ -- end
+ local str = lpegmatch(p_strip,first)
+ local rep = i_replacements[str] or lpegmatch(p_mi,str)
+ context(rep)
+ -- ctx_mi(rep)
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+end
+
+function mathml.mfenced(id) -- multiple separators
+ id = getid(id)
+ local at = id.at
+ local left = at.open or "("
+ local right = at.close or ")"
+ local separators = at.separators or ","
+ local l = l_replacements[left]
+ local r = r_replacements[right]
+ ctx_enabledelimiter()
+ if l then
+ context(l_replacements[left] or o_replacements[left] or "")
+ else
+ context(o_replacements["@l"])
+ context(left)
+ end
+ ctx_disabledelimiter()
+ local collected = lxmlfilter(id,"/*") -- check the *
+ if collected then
+ local n = #collected
+ if n == 0 then
+ -- skip
+ elseif n == 1 then
+ xmlsprint(collected[1]) -- to be checked
+ else
+ local t = utfsplit(separators,true)
+ for i=1,n do
+ xmlsprint(collected[i]) -- to be checked
+ if i < n then
+ local m = t[i] or t[#t] or ""
+ if m == "|" then
+ m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter"
+ elseif m == doublebar then
+ m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter"
+ elseif m == "{" then
+ m = "\\{"
+ elseif m == "}" then
+ m = "\\}"
+ end
+ context(m)
+ end
+ end
+ end
+ end
+ ctx_enabledelimiter()
+ if r then
+ context(r_replacements[right] or o_replacements[right] or "")
+ else
+ context(right)
+ context(o_replacements["@r"])
+ end
+ ctx_disabledelimiter()
+end
+
+local function flush(e,tag,toggle)
+ if tag == "none" then
+ -- if not toggle then
+ context("{}") -- {} starts a new ^_ set
+ -- end
+ elseif toggle then
+ context("^{")
+ xmlsprint(e.dt)
+ context("}{}") -- {} starts a new ^_ set
+ else
+ context("_{")
+ xmlsprint(e.dt)
+ context("}")
+ end
+ return not toggle
+end
+
+function mathml.mmultiscripts(id)
+ local done, toggle = false, false
+ for e in lxmlcollected(id,"/*") do
+ local tag = e.tg
+ if tag == "mprescripts" then
+ context("{}")
+ done = true
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ end
+ end
+ local done, toggle = false, false
+ for e in lxmlcollected(id,"/*") do
+ local tag = e.tg
+ if tag == "mprescripts" then
+ break
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ else
+ xmlsprint(e)
+ done = true
+ end
+ end
+end
+
+local columnalignments = {
+ left = "flushleft",
+ right = "flushright",
+ center = "middle",
+}
+
+local rowalignments = {
+ top = "high",
+ bottom = "low",
+ center = "lohi",
+ baseline = "top",
+ axis = "lohi",
+}
+
+local frametypes = {
+ none = "off",
+ solid = "on",
+ dashed = "on",
+}
+
+-- crazy element ... should be a proper structure instead of such a mess
+
+function mathml.mcolumn(root)
+ root = getid(root)
+ local matrix, numbers = { }, 0
+ local function collect(m,e)
+ local tag = e.tg
+ if tag == "mi" or tag == "mn" or tag == "mo" or tag == "mtext" then
+ local str = xmltext(e)
+ str = lpegmatch(p_strip,str)
+ for s in utfcharacters(str) do
+ m[#m+1] = { tag, s }
+ end
+ if tag == "mn" then
+ local n = utflen(str)
+ if n > numbers then
+ numbers = n
+ end
+ end
+ elseif tag == "mspace" or tag == "mline" then
+ local str = e.at.spacing or ""
+ for s in utfcharacters(str) do
+ m[#m+1] = { tag, s }
+ end
+ -- elseif tag == "mline" then
+ -- m[#m+1] = { tag, e }
+ end
+ end
+ for e in lxmlcollected(root,"/*") do
+ local m = { }
+ matrix[#matrix+1] = m
+ if e.tg == "mrow" then
+ -- only one level
+ for e in lxmlcollected(e,"/*") do
+ collect(m,e)
+ end
+ else
+ collect(m,e)
+ end
+ end
+ ctx_halign()
+ ctx_bgroup()
+ context([[\hss\startimath\alignmark\stopimath\aligntab\startimath\alignmark\stopimath\cr]])
+ for i=1,#matrix do
+ local m = matrix[i]
+ local mline = true
+ for j=1,#m do
+ if m[j][1] ~= "mline" then
+ mline = false
+ break
+ end
+ end
+ if mline then
+ ctx_noalign([[\obeydepth\nointerlineskip]])
+ end
+ for j=1,#m do
+ local mm = m[j]
+ local tag, chr = mm[1], mm[2]
+ if tag == "mline" then
+ -- This code is under construction ... I need some real motivation
+ -- to deal with this kind of crap.
+--~ local n, p = true, true
+--~ for c=1,#matrix do
+--~ local mc = matrix[c][j]
+--~ if mc then
+--~ mc = mc[2]
+--~ if type(mc) ~= "string" then
+--~ n, p = false, false
+--~ break
+--~ elseif find(mc,"^[%d ]$") then -- rangecheck is faster
+--~ -- digit
+--~ elseif not find(mc,"^[%.%,]$") then -- rangecheck is faster
+--~ -- punctuation
+--~ else
+--~ n = false
+--~ break
+--~ end
+--~ end
+--~ end
+--~ if n then
+--~ chr = "\\mmlmcolumndigitrule"
+--~ elseif p then
+--~ chr = "\\mmlmcolumnpunctuationrule"
+--~ else
+--~ chr = "\\mmlmcolumnsymbolrule" -- should be widest char
+--~ end
+ chr = "\\hrulefill"
+ elseif tag == "mspace" then
+ chr = "\\mmlmcolumndigitspace" -- utfchar(0x2007)
+ end
+ if j == numbers + 1 then
+ context("\\aligntab")
+ end
+ local nchr = n_replacements[chr]
+ context(nchr or chr)
+ end
+ ctx_crcr()
+ end
+ ctx_egroup()
+end
+
+local spacesplitter = lpeg.tsplitat(" ")
+
+function mathml.mtable(root)
+ -- todo: align, rowspacing, columnspacing, rowlines, columnlines
+ root = getid(root)
+ local at = root.at
+ local rowalign = at.rowalign
+ local columnalign = at.columnalign
+ local frame = at.frame
+ local rowaligns = rowalign and lpegmatch(spacesplitter,rowalign)
+ local columnaligns = columnalign and lpegmatch(spacesplitter,columnalign)
+ local frames = frame and lpegmatch(spacesplitter,frame)
+ local framespacing = at.framespacing or "0pt"
+ local framespacing = at.framespacing or "-\\ruledlinewidth" -- make this an option
+
+ ctx_bTABLE { frame = frametypes[frame or "none"] or "off", offset = framespacing, background = "" } -- todo: use xtables and definextable
+ for e in lxmlcollected(root,"/(mml:mtr|mml:mlabeledtr)") do
+ ctx_bTR()
+ local at = e.at
+ local col = 0
+ local rfr = at.frame or (frames and frames [#frames])
+ local rra = at.rowalign or (rowaligns and rowaligns [#rowaligns])
+ local rca = at.columnalign or (columnaligns and columnaligns[#columnaligns])
+ local ignorelabel = e.tg == "mlabeledtr"
+ for e in lxmlcollected(e,"/mml:mtd") do -- nested we can use xml.collected
+ col = col + 1
+ if ignorelabel and col == 1 then
+ -- get rid of label, should happen at the document level
+ else
+ local at = e.at
+ local rowspan = at.rowspan or 1
+ local columnspan = at.columnspan or 1
+ local cra = rowalignments [at.rowalign or (rowaligns and rowaligns [col]) or rra or "center"] or "lohi"
+ local cca = columnalignments[at.columnalign or (columnaligns and columnaligns[col]) or rca or "center"] or "middle"
+ local cfr = frametypes [at.frame or (frames and frames [col]) or rfr or "none" ] or "off"
+ ctx_bTD { align = formatters["{%s,%s}"](cra,cca), frame = cfr, nx = columnspan, ny = rowspan }
+ if xmlempty(e,".") then
+ -- nothing, else hsize max
+ else
+ ctx_startimath()
+ -- ctx_ignorespaces()
+ xmlcprint(e)
+ -- ctx_removeunwantedspaces()
+ ctx_stopimath()
+ end
+ ctx_eTD()
+ end
+ end
+ -- if e.tg == "mlabeledtr" then
+ -- ctx_bTD()
+ -- xmlcprint(xml.first(e,"/!mml:mtd"))
+ -- ctx_eTD()
+ -- end
+ ctx_eTR()
+ end
+ ctx_eTABLE()
+end
+
+function mathml.csymbol(root)
+ root = getid(root)
+ local at = root.at
+ local encoding = at.encoding or ""
+ local hash = url.hashed(lower(at.definitionUrl or ""))
+ local full = hash.original or ""
+ local base = hash.path or ""
+ local text = strip(xmltext(root) or "")
+ ctx_mmlapplycsymbol(full,base,encoding,text)
+end
+
+local p = lpeg.Cs(((1-lpegpatterns.whitespace)^1 / "mml:enclose:%0" + (lpegpatterns.whitespace^1)/",")^1)
+
+function mathml.menclosepattern(root)
+ root = getid(root)
+ local a = root.at.notation
+ if a and a ~= "" then
+ context(lpegmatch(p,a))
+ end
+end
+
+function xml.is_element(e,name)
+ return type(e) == "table" and (not name or e.tg == name)
+end
+
+function mathml.cpolar_a(root)
+ root = getid(root)
+ local dt = root.dt
+ ctx_mathopnolimits("Polar")
+ ctx_left(false,"(")
+ for k=1,#dt do
+ local dk = dt[k]
+ if xml.is_element(dk,"sep") then
+ context(",")
+ else
+ xmlsprint(dk)
+ end
+ end
+ ctx_right(false,")")
+end
+
+-- crap .. maybe in char-def a mathml overload
+
+local mathmleq = {
+ [utfchar(0x00AF)] = utfchar(0x203E),
+}
+
+function mathml.extensible(chr)
+ context(mathmleq[chr] or chr)
+end
+
+--
+
+local function install(name,action)
+ interfaces.implement {
+ name = name,
+ public = true,
+ -- protected = true, -- some definitely not !
+ arguments = "argument",
+ actions = action,
+ }
+end
+
+install("mathml_mi", mathml.mi)
+install("mathml_mo", mathml.mo)
+install("mathml_mn", mathml.mn)
+install("mathml_mfenced", mathml.mfenced)
+install("mathml_mmultiscripts", mathml.mmultiscripts)
+install("mathml_menclosepattern", mathml.menclosepattern)
+install("mathml_mtable", mathml.mtable)
+install("mathml_mcolumn", mathml.mcolumn)
+install("mathml_extensible", mathml.extensible)
+
+install("mathml_csymbol", mathml.csymbol)
+install("mathml_cpolar_a", mathml.cpolar_a)
+
+install("mathml_cpolar_extensible", mathml.cpolar_extensible)
diff --git a/tex/context/modules/mkxl/x-mathml.mkxl b/tex/context/modules/mkxl/x-mathml.mkxl
new file mode 100644
index 000000000..fbfc17883
--- /dev/null
+++ b/tex/context/modules/mkxl/x-mathml.mkxl
@@ -0,0 +1,2448 @@
+%D \module
+%D [ file=x-mathml,
+%D version=2008.05.29, (evolved from pre 2000 code)
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\MATHML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \xmlfilter{#1}{/*/name()} -> \xmltag
+
+% This implementation looks like a hack ... this is because we deal with all weird
+% cases we ran into, including abuse that was supposed to render ok (even if it
+% didn't in other renderers) .. it was simply expected to work that way. It is also
+% the product of stepwise adaptation to what we run into. And that in turn is often
+% determined by the tools that were used to produce the \XML. Even worse is the
+% cycling between coding that happens in projects: from content\ \MATHML\ to
+% OpenMath to asciimath to presentation \MATHML\ to \unknown\ which all depends on
+% what tools are available to render in a browser (where first \MATHML\ was hardly
+% supported, then became accepted, then was taken over by mathjax, then merged with
+% other input methods and who knopws what comes next in these days where technologies
+% are shortlived and the next best thing is already waiting around the corner.
+%
+% So, consider this module to be under constant construction and clean up. We still
+% use a funny mix of xml, tex and lua. I could rewrite the lot but it also shows
+% how context evolves. I might end up with a lua-only implementation some day, but
+% I must find a real good reason to spend time on it as so far it never paid back.
+% As far as I can tell, publishers have never shown much (real) interest anyway or
+% at least I haven't met one who cared to invest in it. If they run into \MATHML\
+% they just expect it to be supported.
+%
+% This variant is adapted to \LMTX\ and might evolve with upcoming variations of
+% the standard. As with \SVG\ and probably other \XML\ definitions that target a
+% specific domain, \MATHML\ is now more just something for browsers and \HTML\
+% usage (although support fluctuates). It's getting less generic (or at least we
+% see no more structural elements showing up) and with \CSS\ becoming the
+% recomended way to control local optimizations it indeed looks like only browsers
+% are the target, unless we can just ignore all that. Limitations of renderers,
+% specific usage, application determined \XML\ ... where will it end. All we can do
+% is follow and try to keep up, but maybe the more web it becomes, the less \TEX\
+% users need to care (read: can stick to \TEX\ coding).
+%
+% See the \MKII\ and \MKIV\ files for a history and the hacks we had to use in
+% the past.
+
+\writestatus{loading}{ConTeXt XML Macros / MathML Renderer}
+
+\unprotect
+
+\usemodule[x][calcmath]
+%usemodule[x][asciimath]
+
+\startmodule [mathml]
+
+\registerctxluafile{x-mathml}{autosuffix}
+
+\setupxml[\c!entities=\v!yes] % load big entities table
+
+\def\ctxmodulemathml#1{\ctxlua{moduledata.mathml.#1}}
+
+\startxmlsetups xml:mml:define
+ \xmlsetsetup{#1} {(formula|subformula)} {mml:formula}
+ \xmlfilter {#1} {omt:*/function(remapopenmath)}
+ \xmlfilter {#1} {mml:bind/function(remapmmlbind)}
+ \xmlfilter {#1} {mml:csymbol/function(remapmmlcsymbol)}
+ \xmlsetsetup{#1} {mml:*} {mml:*}
+ \xmlsetsetup{#1} {mml:apply/mml:apply/mml:inverse/../..} {mml:apply:inverse}
+ \xmlstrip {#1} {(mml:mi|mml:mo|mml:mn|mml:csymbol)}
+\stopxmlsetups
+
+\xmlregisterns{omt}{openmath}
+\xmlregisterns{mml}{mathml}
+
+\xmlregistersetup{xml:mml:define}
+
+\xmlmapvalue {mml:math:mode} {display} {\displaymathematics} % we had this already
+\xmlmapvalue {mml:math:mode} {inline} {\inlinemathematics }
+
+\xmlmapvalue {mml:math:display} {block} {\displaymathematics} % before this showed up
+\xmlmapvalue {mml:math:display} {inline} {\inlinemathematics }
+
+\xmlmapvalue {mml:math:dir} {ltr} {\setfalse\c_math_right_to_left\math_basics_synchronize_direction}
+\xmlmapvalue {mml:math:dir} {rtl} {\settrue \c_math_right_to_left\math_basics_synchronize_direction}
+
+\edef\mmlconstantone {1}
+\edef\mmlconstantfalse{false}
+
+\startxmlsetups mml:math
+ \begingroup
+ \enableautofences
+ \enableautofencemode
+ \xmlval {mml:math:dir} {\xmlatt{#1}{dir}} {}
+ \xmlval {mml:math:display} {\xmlatt{#1}{display}} {
+ \xmlval {mml:math:mode} {\xmlatt{#1}{mode}} {
+ \automathematics
+ }
+ }
+ {
+ \xmlflush{#1}
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:imath
+ \inlinemathematics {
+ \enableautofences
+ \enableautofencemode
+ \xmlflush{#1}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:dmath
+ \displaymathematics {
+ \enableautofences
+ \enableautofencemode
+ \xmlflush{#1}
+ }
+\stopxmlsetups
+
+%D First we define some general formula elements.
+
+\startxmlsetups mml:formula
+ \edef\mmlformulaid {\xmlatt{#1}{id}}
+ \edef\mmlformulalabel {\xmlatt{#1}{label}\mmlformulaid}
+ \edef\mmlformulasublabel{\xmlatt{#1}{sublabel}\mmlformulaid}
+ \doifsomething\mmlformulalabel{\placeformula[\mmlformulalabel]{\mmlformulasublabel}}
+ \startformula
+ \xmlfirst{#1}{/mml:math}
+ \stopformula
+\stopxmlsetups
+
+
+\setfalse\mmlignoredelimiter % alternatively we could turn it on/off inside the start/stop and ignore \left\right\middle otherwise
+
+\let\mmlleftdelimiter \autofenceopen
+\let\mmlmiddledelimiter \autofencemiddle
+\let\mmlrightdelimiter \autofenceclose
+\let\mmlleftorrightdelimiter\autofenceboth
+
+\def\mmlchar#1{\char#1 } % used in lua code
+
+%D The rendering macros:
+
+\def\MMLrm{\mr}
+
+\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % nils space after separator
+\def\MMLseparator#1{,} % todo, for europe we need to block the space
+
+%D Since I only had the draft of MathML 2 and later 3 as example of rendering, there
+%D are probably a lot of omissions and misinterpretations. At least I learned some
+%D bits and pieces of math rendering.
+%D
+%D The main complications were not so much the math, but to find the most efficient
+%D way to handle elements without spacing beging messed up. The first implementation
+%D was aimed at getting reasonable output, this second implementation is already
+%D better in terms of handling nesting, and I will definitely need a third one that
+%D has more efficient and less ugly code.
+%D
+%D The \TEX\ part is not that complicated and once the preprocessor was okay, the
+%D rest way just a lot of keying and testing. It all comes down to gobbling,
+%D redefining, and not so much to parsing.
+%D
+%D The second implementation expanded the whole math sequence into an internal \TEX\
+%D representation. This is a rather clean and fast process. Filtering and testing
+%D takes place by redefining the internal representation macros.
+%D
+%D The third implementation may look a bit more messy in some respects. This is
+%D because in \TEX\ it's not that trivial to implement a tree handler. We use a
+%D stack for the \type {apply} element and other sequential content. Occasionally we
+%D need to peek into child elements which involves messy code. This implementation
+%D is closer to the normal \XML\ handling in \CONTEXT.
+%D
+%D This fourth variant just improves on the third. It uses some tricks available in
+%D \LUAMETATEX\ where we have extended the math machinery.
+
+%D We start with the parent elements and the option handler.
+
+\protected\def\xmlmathmldirective#1{\dosetvalue{MML#1}}
+
+\xmlinstalldirective{mathml}{xmlmathmldirective}
+
+%D In the styles, options can be set with:
+
+\protected\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua
+
+%D We will apply inner math to all bits and pieces made up by an \type {apply}.
+
+\def\MMLmathinner
+ {\ifinner
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\mathinner
+ \fi}
+
+%D Auxiliary MathML macros: (to be generalized)
+
+\def\mmlfirst #1{\xmlelement{#1}{1}} % we can move these inline if needed
+\def\mmlsecond #1{\xmlelement{#1}{2}}
+\def\mmlthird #1{\xmlelement{#1}{3}}
+\def\mmlprelast#1{\xmlelement{#1}{-2}}
+\def\mmllast #1{\xmlelement{#1}{-1}}
+
+\starttexdefinition doifelsemmlfunction #1
+ \xmldoifelse {#1} {/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:apply/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:ci[@type=='fn']} {
+ \firstoftwoarguments
+ } {
+ \secondoftwoarguments
+ }
+ }
+ }
+\stoptexdefinition
+
+%D A couple of lists:
+
+\convertargument
+ mml:times|mml:divide|mml:power|%
+ mml:lt|mml:gt|mml:eq|mml:leq|mml:geq|%
+ mml:in|mml:inverse|%
+ mml:fn|%
+ mml:floor|mml:ceiling|%
+ mml:mean|%
+ mml:selector|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:outerproduct|mml:innerproduct|mml:scalarproduct%
+\to \MMLcmainresetlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:fn%
+\to \MMLcfunctionlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs%
+\to \MMLcpurefunctionlist
+
+\convertargument
+ mml:diff|mml:partialdiff|mml:root%
+\to \MMLcconstructlist
+
+%D We use inner and grouping (begin/end and no b/e) else we get problems with
+%D 1/2(1+2) and alike. The problem with apply is that we need to take care of
+%D several situations, like:
+%D
+%D \starttyping
+%D <apply> <.../> ...
+%D <apply> <fn> ...
+%D <apply> <apply> <ci> ...
+%D <apply> <apply> <fn> <ci> ...
+%D \stoptyping
+%D
+%D Because we translated version 2 of this renderer into version 3 the following
+%D definitions may be sub optimal or more complex than actually needed.
+
+%D We will more more to lua ...
+
+% simple version
+
+\newcount\@MMLlevel \def\MMLcreset{\@MMLlevel\zerocount}
+
+\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist}
+
+\let\MMLdoL\donothing
+\let\MMLdoR\donothing
+
+\newcount\mmlapplydepth \def\MMLcreset{\mmlapplydepth\zerocount}
+
+\startxmlsetups mml:apply
+ \MMLmathinner {
+ % \xmldoif {#1} {/(\MMLcmainresetlist\string|\MMLctempresetlist)} {
+ % \MMLcreset
+ % }
+ \edef\mmlapplyopentoken {\xmlatt{#1}{open}}
+ \edef\mmlapplyclosetoken{\xmlatt{#1}{close}}
+ \ifcase\mmlapplydepth
+ \orelse\ifempty\mmlapplyopentoken
+ \def\mmlapplyopentoken {(}
+ \def\mmlapplyclosetoken{)}
+ \fi
+ \advance\mmlapplydepth\plusone
+ \begingroup
+ \ifempty\mmlapplyopentoken
+ \let\MMLdoL\donothing
+ \let\MMLdoR\donothing
+ \else
+ \edef\MMLdoL{\noexpand\left \mmlapplyopentoken }
+ \edef\MMLdoR{\noexpand\right\mmlapplyclosetoken}
+ \fi
+ \let\MMLctempresetlist\empty
+ \xmldoifelse {#1} {/mml:apply} {
+% % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
+% \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a]
+% % yet incomplete and rather untested
+% % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
+ } {% [b]
+% \MMLcreset
+ }
+% \MMLdoL
+% \mmlfirst{#1}
+% \ifconditional\somepostponedMMLactions
+% \postponedMMLactions
+% \else
+% \left(\MMLcreset\mmlsecond{#1}\right)
+% \fi
+% \MMLdoR
+% } {
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/tag()}}
+ \doifelsesetups {mml:apply:mml:\mmlapplyaction} {
+ \xmlsetup{#1}{mml:apply:mml:\mmlapplyaction}
+ } {
+% \MMLdoL
+ \xmlsetup{#1}{mml:\mmlapplyaction}
+% \MMLdoR
+ }
+% }
+ \endgroup
+ \advance\mmlapplydepth\minusone
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:apply
+ \xmlflush{#1}
+ \xmlall{#1}{../[position()>1]}
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:fn
+ \xmldoifelse {#1} {/mml:fn/mml:ci} {
+ \edef\mmlfnci{\xmlstripped{#1}{/mml:fn/mml:ci}}
+ \doifelsesetups{mmc:fn:\mmlfnci} {
+ \xmlsetup{#1}{mmc:fn:\mmlfnci}
+ } {
+ \MMLcreset
+ \MMLdoL
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \negthinspace % not enough
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+ \MMLdoR
+ }
+ } {
+ \MMLcreset
+ \MMLdoL
+ \xmlall{#1}{/*}
+ \MMLdoR
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:csymbol
+ \xmlsetup{#1}{mml:csymbol}% \MMLdoL/MMLdoR to be handled in plugin
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:ci
+ \xmlfirst{#1}{/mml:ci}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+\stopxmlsetups
+
+% reln
+
+\startxmlsetups mml:reln
+ \writestatus{XML}{MathML element "reln" is obsolete}
+\stopxmlsetups
+
+% fn
+
+% plusminus ±
+
+\startxmlsetups mmc:fn:\utfchar{"00B1}
+ \MMLdoL
+ \xmlconcat{#1}{/[position()>1]}{\utfchar{"00B1}}
+ \MMLdoR
+\stopxmlsetups
+
+% minusplus
+
+\startxmlsetups mmc:fn:\utfchar{"2213}
+ \MMLdoL
+ \xmlconcat{#1}{/[position()>1]}{\utfchar{"2213}}
+ \MMLdoR
+\stopxmlsetups
+
+\startxmlsetups mmc:fn
+ \begingroup
+ \edef\mmlnoffn{\xmlcount{#1}{/*}}
+ \ifnum\mmlnoffn>\plustwo
+ \def\MMCfnleft {\left(}
+ \def\MMCfnright{\right)}
+ \else
+ \let\MMCfnleft \relax
+ \let\MMCfnright\relax
+ \fi
+ \xmldoifelse {#1} {/mml:ci} {
+ \edef\mmlfnci{\xmltext{#1}{/mml:ci}}
+ \doifelsesetups{mmc:fn:\mmlfnci} {
+ \xmlsetup{#1}{mmc:fn:\mmlfnci}
+ } {
+ \MMLcreset
+ \mmlfirst{#1}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/(mml:plus\string|mml:minus)} {
+ \left(\mmlfirst{#1}\right)
+ } {
+ \mmlfirst{#1}
+ }
+ \ifnum\mmlnoffn>\plusone
+ \left(\xmlall{#1}{/!mml:apply}\right)
+ \fi
+ } {
+ \MMLcreset
+ \negthinspace
+ \MMCfnleft
+ \ifnum\mmlnoffn=\plustwo,\fi
+ \xmlconcat{#1}{/*}{2}{}{\MMLseparator,}
+ \MMCfnright
+ }
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mmc:fn:apply % where used?
+ \xmldoifelse {#1} {/mml:ci} {
+ \edef\mmlfnci{\xmltext{#1}{/mml:ci}}
+ \doifelsesetups{mmc:fn:\mmlfnci} {
+ \xmlsetup{#1}{mmc:fn:\mmlfnci}
+ } {
+ \MMLcreset
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \negthinspace
+ \left(\MMLcreset\xmlconcat{#1}{2}{}{\MMLseparator,}\right)
+ \fi
+ }
+ } {
+ \endgroup
+ \MMLcreset
+ \mmlfirst{#1}
+ }
+\stopxmlsetups
+
+%D The next definition provide a kind of plug-in mechanism (see the open math
+%D extension module).
+
+% http://www.publishers.com/somename
+%
+% called at the lua end
+
+\starttexdefinition mmlapplycsymbol #1#2#3#4
+ % #1=full url, #2=name, #3=encoding, #4=text
+ \doifelse {#3} {text} {
+ \text{#4}
+ } {
+ \doifelsesetups {mml:csymbol:#1} {
+ % full url
+ \fastsetup{mml:csymbol:#1}
+ } {
+ % somename (fallback)
+ \doifelsesetups {mml:csymbol:#2} {
+ \fastsetup{mml:csymbol:#2}
+ } {
+ \xmlval{mmc:cs}{#3}{}% todo
+ }
+ }
+ }
+\stoptexdefinition
+
+\startxmlsetups mml:csymbol
+ \mathml_csymbol{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:csymbol:cdots
+ \cdots
+\stopxmlsetups
+
+% \startxmlsetups mml:csymbol:<url> \stopxmlsetups
+
+%D Alternative b will convert periods into comma's:
+
+\setupMMLappearance[cn] [\c!alternative=\v!a]
+\setupMMLappearance[polar] [\c!alternative=\v!a] % a|b|c
+\setupMMLappearance[float] [\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[enotation][\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[base] [\c!symbol=\v!numbers] % digits|characters|text|no
+
+\startxmlsetups mml:cs \xmlcommand{#1}{/}{mml:cs:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:ci \xmlcommand{#1}{/}{mml:ci:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:cn \xmlcommand{#1}{/}{mml:cn:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+
+% helpers cn / todo: \mn{...}
+
+\startxmlsetups mml:cn:default
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+% helpers ci
+
+\startxmlsetups mml:ci:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:set
+ {\blackboard{\xmlflush{#1}}} % todo
+\stopxmlsetups
+
+\startxmlsetups mml:ci:vector
+ \overrightarrow{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:matrix
+ {\bi\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:function
+ \xmlflush{#1}% \negthinspace
+\stopxmlsetups
+
+\startxmlsetups mml:ci:fn
+ \xmlsetup{#1}{mml:ci:function}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+% helpers ci
+
+\startxmlsetups mml:cn:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:integer
+ \edef\mmlintegerbase{\xmlattdef{#1}{base}{}}
+ \ifx\mmlintegerbase\empty
+ \xmlflush{#1}
+ \else
+ \doifelse \MMLbasesymbol \v!no {
+ \MMLcCNbasedata{\xmlflush{#1}}
+ } {
+ \MMLcCNbasedata{\xmlflush{#1}}\normalsubscript{
+ \hbox {\startimath
+ \mr
+ \scriptscriptstyle
+ \processaction
+ [\MMLbasesymbol]
+ [\v!characters=>\MMLcCNbasestring BODH,
+ \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
+ \s!unknown=>\mmlintegerbase]
+ \stopimath}
+ }
+ }
+ \fi
+\stopxmlsetups
+
+\def\MMLcCNbasedata#1%
+ {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi}
+
+\def\MMLcCNbasestring#1#2#3#4%
+ {\ifnum\mmlintegerbase= 2 #1\orelse
+ \ifnum\mmlintegerbase= 8 #2\orelse
+ \ifnum\mmlintegerbase=10 #3\orelse
+ \ifnum\mmlintegerbase=16 #4\else
+ \mmlintegerbase \fi}
+
+\startxmlsetups mml:cn:polar
+ \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:a
+ \mathml_cpolar_a{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:b
+ {\mr e}\normalsuperscript{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:c
+ \exp\left(\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex % todo ( )
+ \left(\xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}\thinspace{\mr i}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:float
+ \doifelse \MMLfloatsymbol \v!no {
+ % make sure that e shows up ok
+ \mathopnolimits{\xmlflush{#1}}
+ } {
+ % we should ignore \entities !
+ \edef\mmlfloatstring{\xmlflush{#1}}
+ \splitstring\mmlfloatstring\at e\to\first\and\last
+ \ifempty\first
+ \mmlfloatstring
+ \orelse\ifempty\last
+ \mmlfloatstring
+ \else
+ \first
+ \doifelse \MMLfloatsymbol {dot} \cdot \times
+ 10\normalsuperscript{\last}
+ \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:real
+ \xmlsetup{#1}{mml:cn:float}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:e-notation
+ \doifelse \MMLenotationsymbol \v!no {
+ \xmlsnippet{#1}{1}
+ \unskip\mathopnolimits{e}\ignorespaces
+ \xmlsnippet{#1}{3}
+ } {
+ \xmlsnippet{#1}{1}
+ \doifelse \MMLenotationsymbol {dot} \cdot
+ \times10\normalsuperscript{\xmlsnippet{#1}{3}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:logical
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:rational
+ \xmldoifelse {#1} {/mml:sep} {
+ \mmlfrac
+ {\xmlsnippet{#1}{1}}
+ {\xmlsnippet{#1}{3}}
+ } {
+ \xmlflush{#1}
+ }
+\stopxmlsetups
+
+% interval
+
+\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}]
+
+% when empty element, then it's an apply
+
+\startxmlsetups mml:interval
+ \doifelse {\xmltag{#1}} {apply} {
+ % #1 == apply
+ \let\mmlintervalfirst \mmlsecond
+ \let\mmlintervalsecond\mmlthird
+ \xmlsetup{#1}{mml:interval:\xmlattributedef{#1}{/mml:interval}{closure}{closed}}
+ } {
+ % #1 == interval
+ \let\mmlintervalfirst \mmlfirst
+ \let\mmlintervalsecond\mmlsecond
+ \xmlsetup{#1}{mml:interval:\xmlattdef{#1}{closure}{closed}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open-closed
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+ } {
+ \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed-open
+ \doifelse \MMLintervalalternative \v!b {
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
+ } {
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
+ } {
+ \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
+ }
+\stopxmlsetups
+
+% inverse
+
+\setfalse\xmlinversefunction
+
+\startxmlsetups mml:apply:inverse
+ \settrue\xmlinversefunction
+ \xmlsetup{#1}{mml:\xmlfilter{#1}{/mml:apply/*[2]/tag()}}
+\stopxmlsetups
+
+% condition
+
+% maybe a fast \xmlnonfirst
+
+% instead of the following we could do \xmlcontent{#1}{/mml:bvar} etc
+
+\startxmlsetups mml:bvar \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:uplimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:degree \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:logbase \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:fn \xmlflush{#1} \stopxmlsetups
+
+\startxmlsetups mml:condition
+% \xmldoif {#1} {/mml:bvar} {
+% \xmlfirst{#1}{/mml:bvar}\mid
+% }
+ \xmlall{#1}{/!(mml:condition\string|mml:bvar)}
+\stopxmlsetups
+
+% declare
+
+\setupMMLappearance[declare][\c!state=\v!start]
+
+\startxmlsetups mml:declare
+ \doif \MMLdeclarestate \v!start {
+ \mathopnolimits{declare}
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \thickspace
+ \mathopnolimits{as}
+ \thickspace
+ \fi
+ \mmlsecond{#1}
+ }
+\stopxmlsetups
+
+% lambda
+
+\setupMMLappearance[lambda][\c!alternative=b]
+
+\startxmlsetups mml:lambda
+ \begingroup
+ \doifelse \MMLlambdaalternative \v!a {
+ \lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\right)
+ } {
+ \ifnum\xmlcount{#1}{/mml:bvar}>\plusone
+ \left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right)
+ \else
+ \xmlfirst{#1}{/mml:bvar}
+ \fi
+ \mapsto
+ \MMLcreset
+ \xmlall{#1}{/!(mml:bvar|mml:lambda)}
+ }
+ \endgroup
+\stopxmlsetups
+
+% compose
+
+\startxmlsetups mml:compose
+ \begingroup
+ \MMLcreset
+% \let\MMLcCIfunction\firstofoneargument % brrr ? ? ?
+ \doifelsemmlfunction {#1} {
+ \left(\xmlconcat{#1}{/!mml:compose}{\circ}\right)
+ } {
+ \xmlconcat{#1}{/!mml:compose}{\circ}
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:image
+ \mathopnolimits{image} \left( {\mr\xmlfilter{#1}{/!mml:image/tag()}} \right)
+\stopxmlsetups
+
+\setupMMLappearance[piece][\c!separator=]
+
+\startxmlsetups mml:piecewise
+ \processaction
+ [\MMLpieceseparator]
+ [ \v!yes=>\def\theMMLpieceseparator{,&},
+ \v!no=>\def\theMMLpieceseparator{&},
+ \s!default=>\def\theMMLpieceseparator{&},
+ \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}]
+ \cases{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:piece
+ \mmlfirst{#1}\theMMLpieceseparator\mathematics{\mmlsecond{#1}}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:otherwise
+% \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr
+ \xmlflush{#1}&{\mr otherwise}\crcr
+\stopxmlsetups
+
+% end of piece
+
+\startxmlsetups mml:quotient
+ \lfloor\mmlsecond{#1}/\mmlthird{#1}\rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:factorial
+ \xmlall{#1}{/!factorial}!
+\stopxmlsetups
+
+\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a]
+
+\newcount\mmldividelevel
+
+\startxmlsetups mml:divide
+ \advance\mmldividelevel\plusone
+ \doifelse \MMLdividealternative \v!b {
+ \mmlsecond{#1}/\mmlthird{#1}
+ } {
+ \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold
+ \mmlsecond{#1}/\mmlthird{#1}
+ \else
+ \MMLcreset
+ \mmlfrac{\MMLcreset\mmlsecond{#1}}{\MMLcreset\mmlthird{#1}}
+ \fi
+ }
+ \advance\mmldividelevel\minusone
+\stopxmlsetups
+
+% min max
+
+\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+
+\startxmlsetups mml:minmax
+ \xmldoif {#1} {/mml:bvar} {
+ {}\normalsubscript{\xmlfirst{#1}{/mml:bvar}}
+ }
+ \left\{
+ \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,}
+ \right\}
+\stopxmlsetups
+
+% minus plus
+
+\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4
+\setupMMLappearance [sign] [\c!reduction=\v!yes]
+
+% alternative b -> geen sign
+
+% branch needed, else (a-b) + (c-d) goes wrong
+% reset check in case of (-x) + 37
+% reset check in case of (-x) + 37
+
+\newcount\mmlpluscounter
+
+\startxmlsetups mml:plus
+ \doifelse \MMLsignreduction \v!yes {
+ \MMLdoL
+ \xmlsetup{#1}{mml:plus:reset}
+ \xmlcommand{#1}{/!mml:plus}{mml:plus:body}
+ \MMLdoR
+ } {
+ \ifnum\xmlcount{#1}{/!mml:plus}=\plusone
+ +\xmlfirst{#1}{/!mml:plus}
+ \else
+ \MMLdoL
+ \xmlconcat{#1}{/!mml:plus}{+}
+ \MMLdoR
+ \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:plus:reset
+ \mmlpluscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:plus:body
+ \advance\mmlpluscounter\plusone
+ \ifnum\mmlpluscounter>\plusone
+ \xmldoifelse{#1}{/mml:minus} {
+ \ifnum\xmlcount{#1}{/!mml:minus}>\plusone
+ +
+ \fi
+ } {
+ \doifelse {\xmlatt{#1}{type}} {rational} {
+ % fraction
+ } {
+ +
+ }
+ }
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+\newcount\mmlminuscounter
+
+\startsetups mml:minus
+ \doifelse \MMLsignreduction \v!yes {
+ \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
+ -\xmlfirst{#1}{/!mml:minus}
+ \else
+ \MMLdoL
+ \xmlsetup{#1}{mml:minus:reset}
+ \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
+ \MMLdoR
+ \fi
+ } {
+ \left( % \MMLdoL
+ \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
+ -\xmlfirst{#1}{/!mml:minus}
+ \else
+ \xmlsetup{#1}{mml:minus:reset}
+ \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
+ \fi
+ \right) % \MMLdoR
+ }
+\stopsetups
+
+\startxmlsetups mml:minus:reset
+ \mmlminuscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:minus:body
+ % we can also use concat here
+ \advance\mmlminuscounter\plusone
+ \ifnum\mmlminuscounter>\plusone
+ -
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+% power
+
+\setupMMLappearance[power][\c!reduction=\v!yes]
+
+\let\MMLpowerelement\empty
+
+\startxmlsetups mml:power
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelse \MMLpowerreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist)} {
+ \gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef
+ \MMLcreset\mmlsecond{#1}
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \mmlsecond{#1}\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+\stopxmlsetups
+
+% rem
+
+\startxmlsetups mml:rem
+ \xmlconcat{#1}{/!mml:rem}{\mathopnolimits{mod}}
+\stopxmlsetups
+
+\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn
+
+\startxmlsetups mml:times
+ \setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}%
+ \doifelse\MMLtimesauto\v!no {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ } {
+ \xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one
+ \doifelseinset\MMLtimessymbol{\v!yes,\v!no} {
+ \let\MMLtimes@@symbol\v!yes
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ }
+ \doifelse\MMLtimes@@symbol\v!yes {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \doifelse\MMLtimes@@symbol{dot} {
+ \xmlconcat{#1}{/!mml:times}{\cdot}
+ } {
+ \doifelse\MMLtimes@@symbol{times} {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \xmlall{#1}{/!mml:times}
+ }
+ }
+ }
+\stopxmlsetups
+
+\setupMMLappearance[root][\c!symbol=\v!yes]
+
+\startxmlsetups mml:root
+ \xmldoifelse {#1} {/mml:degree} {
+ \root
+ \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
+ \of
+ } {
+ \sqrt
+ }
+ {\MMLcreset\xmlall{#1}{/!(mml:degree\string|mml:root)}}
+\stopxmlsetups
+
+% gcd
+
+\startxmlsetups mml:gcd
+ \begingroup
+ \gcd\left(\MMLcreset\xmlconcat{#1}{/!mml:gcd}{\MMLseparator,}\right)
+ \endgroup
+\stopxmlsetups
+
+% and or xor implies, not
+
+\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {\wedge} \stopxmlsetups
+\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {\vee} \stopxmlsetups
+\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {\mathopnolimits{xor}} \stopxmlsetups
+\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{\Rightarrow} \stopxmlsetups
+\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups
+
+% forall exists
+
+%D We need to shift left below rotated A.
+
+\startxmlsetups mml:forall
+ \forall \negthinspace \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\startxmlsetups mml:exists
+ \exists \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\def\mmlforallexistslist{mml:bvar\string|mml:forall\string|mml:exists\string|mml:condition}
+
+\startxmlsetups mml:forallexists
+ \normalsubscript{\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}}
+ \xmldoifelse {#1} {/mml:condition} {
+ \thickspace
+ \begingroup
+ \xmlfirst{#1}{/mml:condition}
+ \endgroup
+ \ifcase\xmlcount{#1}{/!(\mmlforallexistslist)}\relax
+ % nothing
+ \or
+ % == snelle volgende
+ \left\vert
+ \MMLcreset \medspace \xmlconcat{#1}{/!(\mmlforallexistslist)}{}
+ \right.
+ \else
+ % special case
+ \left\vert
+ \matrix {
+ \xmlconcat{#1}{/!(\mmlforallexistslist)}{\hfill\crcr}
+ }
+ \right.
+ \fi
+ } {
+ :\xmlfirst{#1}{/!(\mmlforallexistslist)}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:abs
+ \left\vert \MMLcreset\xmlall{#1}{/!mml:abs} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:conjugate % watch extra {}
+ {\overline{\MMLcreset\xmlall{#1}{/!mml:conjugate}}}
+\stopxmlsetups
+
+\startxmlsetups mml:arg
+ \mathopnolimits{arg} \left( \MMLcreset\xmlall{#1}{/!mml:arg} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:real
+ \Re \left( \MMLcreset \xmlall{#1}{/!mml:real} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:imaginary
+ \Im \ left( \MMLcreset \xmlall{#1}{/!mml:imaginary} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:lcm
+ \mathopnolimits{lcm} \left( \xmlconcat{#1}{/!mml:lcm}{\MMLseparator,} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:floor
+ \lfloor \xmlall{#1}{/!mml:floor} \rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:ceiling
+ \lceiling \xmlall{#1}{/!mml:ceiling} \rceiling
+\stopxmlsetups
+
+% relations
+
+% apply attr or eq
+
+\setupMMLappearance[relation][\c!align=\v!no]
+
+\xmlmapvalue {mml:relation} {eq} {=}
+\xmlmapvalue {mml:relation} {neq} {\neq}
+\xmlmapvalue {mml:relation} {gt} {>}
+\xmlmapvalue {mml:relation} {lt} {<}
+\xmlmapvalue {mml:relation} {geq} {\geq}
+\xmlmapvalue {mml:relation} {leq} {\leq}
+\xmlmapvalue {mml:relation} {equivalent} {\equiv}
+\xmlmapvalue {mml:relation} {approx} {\approx}
+\xmlmapvalue {mml:relation} {factorof} {\mid}
+
+\startxmlsetups mml:eq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:neq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:gt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:lt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:geq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:leq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:equivalent \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:approx \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:factorof \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+\startxmlsetups mml:relation
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/tag()}}
+ \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}}
+\stopxmlsetups
+
+\startxmlsetups mml:relation:default
+ \xmlconcatrange{#1}{/*}{2}{}{\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}}
+\stopxmlsetups
+\startxmlsetups mml:relation:last
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{-2}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
+ \mmlprelast{#1}&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}\mmllast{#1}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:first
+ \eqalign {
+ \mmlsecond{#1}\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}
+ &\xmlconcatrange{#1}{/*}{3}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:left
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:right
+ \eqalign {
+ &\xmlconcatrange{#1}{/*}{2}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:no
+ \xmlsetup{#1}{mml:relation:default}
+\stopxmlsetups
+\startxmlsetups mml:relation:yes
+ \xmlsetup{#1}{mml:relation:left}
+\stopxmlsetups
+
+% personal goody:
+
+\edef\MMLcmainresetlist{\MMLcmainresetlist\string|becomes}
+
+\xmlmapvalue {mml:relation} {mml:becomes} {:=}
+
+\startxmlsetups mml:becomes \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+% calculus and vector calculus
+
+\startxmlsetups mml:domainofapplication
+ \xmlall{#1}{/!mml:domainofapplication}
+\stopxmlsetups
+
+\setupMMLappearance[int][\c!location=\v!top]
+
+\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits}
+
+\startxmlsetups mml:int
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:domainofapplication} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:domainofapplication}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:condition} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:condition}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:lowlimit} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:lowlimit}}\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}
+ } {
+ % funny, why do we have lowlimit/uplimit then
+ \xmldoifelse {#1} {/mml:apply/mml:interval} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlindex{#1}{/mml:apply}{2}}\normalsuperscript{\xmlindex{#1}{/mml:apply}{3}}
+ } {
+ \int
+ }
+ }
+ }
+ }
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelsemmlfunction {#1} { % todo test
+ \xmlfirst{#1}{/mml:apply}
+ } {
+ % if there are too many () now, we need to be more clever
+ \left( \xmlfirst{#1}{/mml:apply} \right)
+ }
+ } {
+ \xmlfirst{#1}{/mml:ci}
+ }
+ \xmldoifelse {#1} {/mml:bvar} {
+ \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar}
+ } {
+ % nothing
+ }
+\stopxmlsetups
+
+\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
+
+\startxmlsetups mml:diff
+ \MMLcreset
+ \doifelse \MMLdiffalternative \v!a {
+ \xmldoifelse {#1} {/mml:lambda} {
+ % a special case (mathadore/openmath)
+ \mmlfrac {
+ d
+ \normalsuperscript
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ {\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}}
+ } {
+ d
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}}
+ \normalsuperscript
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \mmlfrac {
+ {\mr d}{
+ \xmldoifelse {#1} {/mml:degree} {
+ \normalsuperscript{\xmlconcat{#1}{/mml:degree}\empty}
+ } {
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlconcat{#1}{/mml:bvar/mml:degree}+}
+ }
+ }
+ }
+ \doif \MMLdifflocation \v!top {
+ \xmldoifelse {#1} {/mml:ci} {
+ \xmlfirst{#1}{/mml:ci}
+ } {
+ \MMLcreset
+ \ifnum\xmlcount{#1}{/mml:apply/*}>\plustwo % hack
+ \left(\xmlfirst{#1}{/mml:apply}\right)
+ \else
+ \xmlfirst{#1}{/mml:apply}
+ \fi
+ }
+ }
+ } {
+ {\mr d}
+ \xmlfirst{#1}{/mml:bvar/!mml:degree}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ \doifnot \MMLdifflocation \v!top {
+ \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right)
+ }
+ } {
+ % beware, the second {} is needed for the superscript
+ \xmlconcatrange{#1}{/*}{2}{}{}\normalsuperscript\prime
+ }
+ }
+ } {
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:ci)}
+ % there can be problems with nested diff's: \normalsuperscript\normalsuperscript{} error
+ % so we add an empty group here
+ {}\normalsuperscript
+ {
+ \xmldoifelse {#1} {/mml:degree} {
+ \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}}
+ \ifempty\mmldegree
+ % what to do here
+ \else
+ \dorecurse\mmldegree\prime
+ \fi
+ } {
+ \prime
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:partialdiff
+ \xmldoifelse {#1} {/mml:list} {
+ {\mr D}\normalsubscript{
+ \begingroup
+ \setfalse\mmllistdelimiters
+ \xmlall{#1}{/mml:list}
+ \endgroup
+ }
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \mmlfrac {
+ {\mr d}\normalsuperscript{
+ \xmldoifelse {#1} {/mml:degree} {
+ \xmlconcat{#1}{/mml:degree}\empty
+ } {
+ \xmlconcat{#1}{/mml:bvar/mml:degree}+
+ }
+ }
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoif {#1}{/mml:bvar/!mml:degree} {
+ \xmlfirst{#1}{/mml:bvar/!mml:degree} \,
+ }
+ {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:divergence \mathopnolimits{div} \xmlall{#1}{/!mml:divergence} \stopxmlsetups
+\startxmlsetups mml:grad \mathopnolimits{grad} \xmlall{#1}{/!mml:grad} \stopxmlsetups
+\startxmlsetups mml:curl \mathopnolimits{curl} \xmlall{#1}{/!mml:curl} \stopxmlsetups
+\startxmlsetups mml:laplacian \nabla\normalsuperscript2 \xmlall{#1}{/!mml:laplacian} \stopxmlsetups
+\startxmlsetups mml:ident \mathopnolimits{identity} \xmlall{#1}{/!mml:ident} \stopxmlsetups
+
+\setupMMLappearance[domain] [symbol=]
+\setupMMLappearance[codomain][symbol=]
+
+\startxmlsetups mml:domain
+ \doifelsenothing \MMLdomainsymbol {
+ \mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain}
+ } {
+ \MMLdomainsymbol\normalsubscript{\xmlall{#1}{/!mml:domain}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:codomain
+ \doifelsenothing \MMLcodomainsymbol {
+ \mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain}
+ } {
+ \MMLcodomainsymbol\normalsubscript{\xmlall{#1}{/!mml:codomain}}
+ }
+\stopxmlsetups
+
+% theory of sets
+
+\startxmlsetups mml:set
+ \left\{
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition}
+ } {
+ \xmlconcat{#1}{/!mml:set}{\MMLseparator,}
+ }
+ \right\}
+ \relax % needed
+\stopxmlsetups
+
+\settrue\mmllistdelimiters
+
+\startxmlsetups mml:list
+ \begingroup
+ \ifconditional\mmllistdelimiters\left [\fi
+ \begingroup
+ \settrue\mmllistdelimiters
+ \xmlconcat{#1}{/!mml:list}{\MMLseparator,}
+ \endgroup
+ \ifconditional\mmllistdelimiters\right]\fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:union \mmlsecond{#1} \cup \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:intersect \mmlsecond{#1} \cap \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:in \mmlsecond{#1} \in \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notin \mmlsecond{#1} {\not\in} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:subset \mmlsecond{#1} \subset \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:prsubset \mmlsecond{#1} \subseteq \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notsubset \mmlsecond{#1} {\not\subset} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notprsubset \mmlsecond{#1} {\not\subseteq} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:setdiff \mmlsecond{#1} \setminus \mmlthird{#1} \stopxmlsetups
+
+\startxmlsetups mml:card
+ \left\vert \xmlall{#1}{/!mml:card} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:cartesianproduct
+ \xmlconcat{#1}{/!mml:cartesianproduct}{\times}
+\stopxmlsetups
+
+% sequences and series
+
+\setupMMLappearance[sum] [\c!location=\v!top]
+\setupMMLappearance[product][\c!location=\v!top]
+
+\xmlmapvalue {mml:sumprod} {sum} {\sum}
+\xmlmapvalue {mml:sumprod} {product} {\prod}
+
+\startxmlsetups mml:sum \edef\mmlsumprodname{sum} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+
+\def\mmlstackedsubscripts#1%
+ {\vbox
+ {\baselineskip\zeropoint % hack, taco vragen
+ \halign{\startimath\scriptstyle\hss\alignmark\alignmark\hss\stopimath\cr#1\crcr}}}
+
+% unfinished
+
+\startxmlsetups mml:sumprod
+ \begingroup
+ \xmldoifelse {#1} {/(mml:condition\string|mml:bvar\string|mml:lowlimit)} {
+ \def\mmlsumprodlower{
+ \normalsubscript{
+ \xmldoifelse {#1} {/mml:condition} {
+ \mmlstackedsubscripts{\xmlconcat{#1}{/mml:condition}{\crcr}}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}
+ \xmldoif{#1}{/mml:lowlimit}{=}
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ }
+ } {
+ \let\mmlsumprodlower\empty
+ }
+ \xmldoifelse {#1} {/mml:uplimit} {
+ \def\mmlsumprodupper{\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}}
+ } {
+ \let\mmlsumprodupper\empty
+ }
+ \xmldoif {#1} {/mml:interval} { % open math converter gives this
+ \edef\mmlintervalfrom{\xmlindex{#1}{/mml:interval}{1}}
+ \edef\mmlintervalto {\xmlindex{#1}{/mml:interval}{2}}
+ \ifempty\mmlintervalfrom \else
+ \def\mmlsumprodlower{\normalsubscript{\xmldoif{#1}{/mml:bvar}{\xmlfirst{#1}{/mml:bvar}{=}}\mmlintervalfrom}}
+ \fi
+ \ifempty\mmlintervalto \else
+ \def\mmlsumprodupper{\normalsuperscript{\mmlintervalto}}
+ \fi
+ }
+ \MMLcreset
+ \xmlval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:lambda/mml:apply} {
+ \xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda\string|mml:ci)}%
+ }
+ \endgroup
+\stopxmlsetups
+
+\setupMMLappearance[limit][\c!location=\v!top]
+
+\startxmlsetups mml:limit
+ \MMLcreset \lim
+ \doMMLlimits {limit}\normalsubscript{
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:condition}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}\rightarrow
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ \begingroup
+ % a bit of open math conversion mess, lambda needed for openmath, ok?
+ \MMLcreset
+ \xmlfirst{#1}{/mml:lambda/mml:apply}
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda)}
+ \endgroup
+\stopxmlsetups
+
+% consider a faster index
+
+\startxmlsetups mml:tendsto
+ \MMLcreset \mmlsecond{#1}
+ \xmlval {mml:tendsto:type} {\xmlattdef{#1}{type}{default}} {\rightarrow}
+ \MMLcreset \mmlthird{#1}
+\stopxmlsetups
+
+\xmlmapvalue {mml:tendsto:type} {above} {\downarrow}
+\xmlmapvalue {mml:tendsto:type} {below} {\uparrow}
+\xmlmapvalue {mml:tendsto:type} {default} {\rightarrow}
+
+% elementary classical functions
+
+\setupMMLappearance[log][\c!location=\v!right]
+
+\startxmlsetups mml:exp
+% {\mr e}\normalsuperscript{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
+ {\mr e}\normalsuperscript{\xmlfirst{#1}{/!mml:exp}}
+\stopxmlsetups
+
+\startxmlsetups mml:log
+ \xmldoifelse {#1} {/mml:logbase} {
+ \doifelse \MMLloglocation \v!left {
+ \mathop {
+ {}\normalsuperscript{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log}
+ }
+ } {
+ \mathopnolimits{log}\normalsubscript{\xmlfirst{#1}{/mml:logbase}}
+ }
+% \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+% \xmlsetup{#1}{mml:function} % todo, we start elsewhere
+% \mmlthird{#1}
+ } {
+ \mathopnolimits{log}
+% \MMLcreset
+% \xmlsetup{#1}{mml:function} % todo, we start elsewhere
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+% \mmlsecond{#1}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:ln
+ \mathopnolimits{ln}
+ \xmlsetup{#1}{mml:function}
+\stopxmlsetups
+
+% statistics
+
+\startxmlsetups mml:mean \overline {\mmlsecond{#1}} \stopxmlsetups
+\startxmlsetups mml:sdev \sigma \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:variance \sigma \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript2 \stopxmlsetups
+\startxmlsetups mml:median \mathopnolimits{median}\left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:mode \mathopnolimits{mode} \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+
+% moments
+
+\startxmlsetups mml:moment
+ \left\langle
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}\normalsuperscript{\xmlfirst{#1}{/mml:degree}}
+ \right\rangle
+ \xmldoif {#1} {mml:momentabout} {
+ \normalsubscript{\xmlfirst{#1}{mml:momentabout}}
+ }
+\stopxmlsetups
+
+% linear algebra
+
+\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
+
+\startxmlsetups mml:vector
+ \begingroup
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \doifelse\MMLvectordirection\v!horizontal {
+ \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right)
+ } {
+ \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right)
+ }
+ \else
+ \overrightarrow{\charhtstrut\mmlfirst{#1}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\settrue\MMCdelmatrix % ( ) when true
+
+\startxmlsetups mml:matrix
+ \begingroup
+ \MMLcreset
+ \ifconditional\MMCdelmatrix
+ \left(\matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}\right)
+ \else
+ \settrue\MMCdelmatrix
+ \matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow
+ \begingroup
+ \MMLcreset
+ \left(\xmlsetup{#1}{mml:matrixrow:do}\right)
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow:do
+ \xmlconcat{#1}{/*}{&}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:determinant
+ \begingroup
+ \setfalse\MMCdelmatrix
+ \left|\mmlsecond{#1}\right|
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:transpose
+ \mmlsecond{#1}\normalsuperscript{\mathopnolimits{T}}
+\stopxmlsetups
+
+\startxmlsetups mml:selector
+ \MMLmathinner{\mmlsecond{#1}\normalsubscript{\MMLcreset\xmlconcatrange{#1}{/*}{3}{}{\MMLseparator,}}}
+\stopxmlsetups
+
+\startxmlsetups mml:vectorproduct \mmlsecond{#1}\times \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:scalarproduct \mmlsecond{#1}\cdot \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:outerproduct \mmlsecond{#1}\otimes\mmlthird{#1} \stopxmlsetups
+
+% semantic mapping elements
+
+\setupMMLappearance[semantics][\c!state=\v!start]
+
+\startxmlsetups mml:semantics
+ \doifelse\MMLsemanticsstate\v!start {
+ \xmlall{#1}{/mml:annotation}
+ } {
+ \xmlall{#1}{/!mml:annotation}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:annotation
+ \xmldoifelse {#1} {.[oneof(@encoding,'TeX','tex','application/x-tex','TEX','ConTeXt','context','CONTEXT','ctx')]} {
+ \xmlflushcontext{#1}
+ } {
+ \xmldoifelse {#1} {.[oneof(@encoding,'calcmath','cm')]} {
+ \expanded{\calcmath{\xmlflush{#1}}}
+ } {
+ \xmldoifelse {#1} {.[oneof(@encoding,'asciimath','am')]} {
+ \ifdefined\asciimath
+ \expanded{\asciimath{\xmlflushpure{#1}}}
+ \else
+ \hbox{\tt no am loaded}
+ \fi
+ } {
+ \xmlall{#1}{../!mml:annotation}
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:annotation-xml
+ % maybe diagnostics
+\stopxmlsetups
+
+% misc
+
+\startxmlsetups mml:integers \integers \stopxmlsetups
+\startxmlsetups mml:reals \reals \stopxmlsetups
+\startxmlsetups mml:rationals \rationals \stopxmlsetups
+\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups
+\startxmlsetups mml:complexes \complexes \stopxmlsetups
+\startxmlsetups mml:primes \primes \stopxmlsetups
+\startxmlsetups mml:exponentiale \mathopnolimits{e} \stopxmlsetups
+\startxmlsetups mml:imaginaryi \mathopnolimits{i} \stopxmlsetups
+\startxmlsetups mml:notanumber \mathopnolimits{NaN} \stopxmlsetups
+\startxmlsetups mml:true \mathopnolimits{true} \stopxmlsetups
+\startxmlsetups mml:false \mathopnolimits{false} \stopxmlsetups
+\startxmlsetups mml:emptyset \mathopnolimits{Ø} \stopxmlsetups
+\startxmlsetups mml:pi \pi \stopxmlsetups
+\startxmlsetups mml:eulergamma \gamma \stopxmlsetups
+\startxmlsetups mml:infinity \infty \stopxmlsetups
+
+% gonio functions
+
+\setupMMLappearance[function][\c!reduction=\v!yes]
+
+% todo: \mfunction which adapts itself when registered as command
+
+% todo: \def\mmlcfunction#1#2{\mathopnolimits{#2}\xmlsetup{#1}{mml:function}}
+
+\startxmlsetups mml:sin \mathcommand {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sinh \mathcommand {sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cos \mathcommand {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cosh \mathcommand {cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tan \mathcommand {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tanh \mathcommand {tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cot \mathcommand {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:coth \mathcommand {coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csc \mathcommand {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csch \mathcommand {csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sec \mathcommand {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sech \mathcommand {sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+
+\startxmlsetups mml:arcsin \mathcommand {arcsin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsinh \mathcommand{arcsinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccos \mathcommand {arccos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccosh \mathcommand{arccosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arctan \mathcommand {arctan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arctanh \mathcommand{arctanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccot \mathcommand {arccot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccoth \mathcommand{arccoth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccsc \mathcommand {arccsc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccsch \mathcommand{arccsch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsec \mathcommand {arcsec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsech \mathcommand{arcsech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+
+\startxmlsetups mml:function
+ \ifempty\MMLpowerelement
+ \ifconditional\xmlinversefunction\normalsuperscript{-1}\fi
+ \setfalse\xmlinversefunction
+ \else
+ \normalsuperscript{\ifconditional\xmlinversefunction-\fi\MMLpowerelement}
+ \setfalse\xmlinversefunction
+ \glet\MMLpowerelement\empty
+ \fi
+ \xmlsetup{#1}{mml:function:argument}
+\stopxmlsetups
+
+\startxmlsetups mml:function:argument
+ \doifelse \MMLfunctionreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)}
+ \donefalse
+ \donetrue
+ } {
+ \donefalse
+ }
+ } {
+ \donetrue
+ }
+ % beware, we still flush from 2 up
+ \ifdone
+ \left(
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty
+ \right)
+ \else
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}
+ \fi
+\stopxmlsetups
+
+% PRESENTATION MATHML
+
+% helpers: maybe we can need a setting for the uprights
+
+\xmlmapvalue {mml:s} {normal} {\mathupright} % {\mathtf}
+\xmlmapvalue {mml:s} {double-struck} {\mathblackboard}
+\xmlmapvalue {mml:s} {italic} {\mathit}
+\xmlmapvalue {mml:s} {fraktur} {\mathfraktur}
+\xmlmapvalue {mml:s} {script} {\mathscript}
+\xmlmapvalue {mml:s} {bold} {\mb} % {\mathbf}
+\xmlmapvalue {mml:s} {bold-italic} {\mathbi}
+\xmlmapvalue {mml:s} {bold-fraktur} {\mathfraktur\mathbf}
+\xmlmapvalue {mml:s} {bold-script} {\mathscript\mathbf}
+\xmlmapvalue {mml:s} {sans-serif} {\mathss}
+\xmlmapvalue {mml:s} {bold-sans-serif} {\mathss\mathbf}
+\xmlmapvalue {mml:s} {sans-serif-italic} {\mathss\mathit}
+\xmlmapvalue {mml:s} {sans-serif-bold-italic} {\mathss\mathbi}
+\xmlmapvalue {mml:s} {monospace} {\mathtt}
+
+\xmlmapvalue {mml:l} {-} {\let\mmlfrac\tfrac}
+ \let\mmlfrac\frac
+\xmlmapvalue {mml:l} {+} {\let\mmlfrac\sfrac}
+
+\xmlmapvalue {mml:d} {true} {\displaystyle}
+\xmlmapvalue {mml:d} {false} {\textstyle} % or whatever
+
+\starttexdefinition setmmlmathstyle #1
+ \ifxmlattempty{#1}{displaystyle}\else
+ \xmlval{mml:d}\xmllastatt\empty
+ \fi
+ \ifxmlattempty{#1}{mathvariant}\else
+ \xmlval{mml:s}\xmllastatt\empty
+ \fi
+\stoptexdefinition
+
+\starttexdefinition setmmlscriptlevel #1
+ \ifxmlattempty{#1}{scriptlevel}
+ \let\mmlfrac\frac
+ \else
+ \xmlval{mml:l}\xmllastatt{\let\mmlfrac\frac}
+ \fi
+\stoptexdefinition
+
+\starttexdefinition setmmlmathcolor #1
+ \ifxmlattempty{#1}{mathcolor}\else
+ \directcolor[\xmllastatt]
+ \fi
+\stoptexdefinition
+
+\starttexdefinition setmmlmathproperties #1
+ % \ifxmlatt{#1}{displaystyle}\empty\else
+ \ifxmlattempty{#1}{displaystyle}\else
+ \xmlval{mml:d}\xmllastatt\empty
+ \fi
+ \ifxmlattempty{#1}{mathvariant}\else
+ \xmlval{mml:s}\xmllastatt\empty
+ \fi
+ \ifxmlattempty{#1}{scriptlevel}
+ \let\mmlfrac\frac
+ \else
+ \xmlval{mml:l}\xmllastatt{\let\mmlfrac\frac}
+ \fi
+ \ifxmlattempty{#1}{mathcolor}\else
+ \directcolor[\xmllastatt]
+ \fi
+\stoptexdefinition
+
+% todo: textbackgrounds / todo: can be combined with new grouping
+
+\starttexdefinition applymmlmathbackground #1#2
+ \ifxmlattempty{#1}{mathbackground}
+ #2
+ \else
+ \backgroundline[\xmllastatt]{#2}
+ \fi
+\stoptexdefinition
+
+\starttexdefinition applymmlsometext #1#2
+ \begingroup
+ \applymmlmathbackground {#1} {
+ \setmmlmathcolor {#1}
+ \setmmlmathstyle {#1}
+ #2
+ }
+ \endgroup
+\stoptexdefinition
+
+% setups
+
+\startxmlsetups mml:mi % todo: mathsize (unlikely) mathcolor (easy) mathbackground (easy)
+ \begingroup
+ \pushmathstyle % still needed ?
+ \setmmlmathproperties{#1}
+ \mathml_mi{#1}
+ \popmathstyle % still needed ?
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mn
+ \begingroup
+ \setmmlmathcolor{#1}
+ \mathml_mn{#1}
+ \endgroup
+\stopxmlsetups
+
+% <m:mo>-</m:mo><m:mn>2</m:mn> and <m:mn>1</m:mn><m:mo>-</m:mo><m:mn>2</m:mn>
+%
+% spacing between - and 2 is taken care of by tex itself
+
+\startxmlsetups mml:mo
+ \begingroup
+ \setmmlmathcolor{#1}
+ \ifxmlatt{#1}{maxsize}{1}
+ \settrue\mmlignoredelimiter
+ \orelse\ifxmlatt{#1}{stretchy}{false}
+ \settrue\mmlignoredelimiter
+ \fi
+ \ifxmlattempty{#1}{lspace}\else
+ \hskip\xmllastatt\relax % todo: check for dimension
+ \fi
+ \mathml_mo{#1}
+ \ifxmlattempty{#1}{rspace}\else
+ \hskip\xmllastatt\relax % todo: check for dimension
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mfenced % {} around separator is needed for spacing
+ \mathml_mfenced{#1}
+\stopxmlsetups
+
+\defineoverlay [mml:enclose:box] [\useMPgraphic{mml:enclose:box}]
+\defineoverlay [mml:enclose:roundedbox] [\useMPgraphic{mml:enclose:roundedbox}]
+\defineoverlay [mml:enclose:circle] [\useMPgraphic{mml:enclose:circle}]
+\defineoverlay [mml:enclose:left] [\useMPgraphic{mml:enclose:left}]
+\defineoverlay [mml:enclose:right] [\useMPgraphic{mml:enclose:right}]
+\defineoverlay [mml:enclose:top] [\useMPgraphic{mml:enclose:top}]
+\defineoverlay [mml:enclose:bottom] [\useMPgraphic{mml:enclose:bottom}]
+\defineoverlay [mml:enclose:updiagonalstrike] [\useMPgraphic{mml:enclose:updiagonalstrike}]
+\defineoverlay [mml:enclose:downdiagonalstrike] [\useMPgraphic{mml:enclose:downdiagonalstrike}]
+\defineoverlay [mml:enclose:horizontalstrike] [\useMPgraphic{mml:enclose:horizontalstrike}]
+\defineoverlay [mml:enclose:verticalstrike] [\useMPgraphic{mml:enclose:verticalstrike}]
+
+\startuseMPgraphic{mml:enclose:box}
+ draw OverlayBox withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:roundedbox}
+ draw OverlayBox cornered .5ExHeight withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:circle}
+ draw fullcircle xysized(bbwidth(OverlayBox),bbheight(OverlayBox)) withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:left}
+ draw leftboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:right}
+ draw rightboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:top}
+ draw topboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:bottom}
+ draw bottomboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:updiagonalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw llcorner p -- urcorner p withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:downdiagonalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw ulcorner p -- lrcorner p withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:horizontalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw .5[llcorner p,ulcorner p] -- .5[lrcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:verticalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw .5[llcorner p,lrcorner p] -- .5[ulcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+
+\startxmlsetups mml:menclose
+ \edef\mmlmenclosenotation{\mathml_menclosepattern{#1}}
+ \ifempty\mmlmenclosenotation
+ \xmlflush{#1}
+ \else
+ \doifelse \mmlmenclosenotation {mml:enclose:longdiv} {
+ \overline{\left)\strut\xmlflush{#1}\right.}
+ } {
+ \doifelse \mmlmenclosenotation {mml:enclose:actuarial} {
+ \overline{\left.\strut\xmlflush{#1}\right\vert}
+ } {
+ \doifelse \mmlmenclosenotation {mml:enclose:radical} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ % todo: no framed when longdiv, actuarial or radical ? spec ?
+ \vcenter {
+ \framed
+ [frame=off,strut=no,background={\mmlmenclosenotation}] % offset is kind of undefined
+ {
+ \startpickupmath
+ \expanded{\doifelseinset {mml:enclose:longdiv} {\mmlmenclosenotation}} {
+ \overline{\left)\strut\xmlflush{#1}\right.}
+ } {
+ \expanded{\doifelseinset {mml:enclose:actuarial} {\mmlmenclosenotation}} {
+ \overline{\left.\strut\xmlflush{#1}\right\vert}
+ } {
+ \expanded{\doifelseinset {mml:enclose:radical} {\mmlmenclosenotation}} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ \expanded{\doifelseinset {mml:enclose:rule} {\mmlmenclosenotation}} {
+ \overline{\strut\xmlflush{#1}}
+ } {
+ \xmlflush{#1}
+ }
+ }
+ }
+ }
+ \stoppickupmath
+ }
+ }
+ }
+ }
+ }
+ \fi
+\stopxmlsetups
+
+\xmlmapvalue {mml:mfrac:linethickness} {thin} {.2pt}
+\xmlmapvalue {mml:mfrac:linethickness} {medium} {.4pt}
+\xmlmapvalue {mml:mfrac:linethickness} {thick} {.8pt}
+\xmlmapvalue {mml:mfrac:linethickness} {0} {0pt}
+
+\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit
+ \begingroup
+ \edef\mmlfraclinethickness{\xmlatt{#1}{linethickness}}
+ \ifempty\mmlfraclinethickness
+ \doifelse{\xmlatt{#1}{bevelled}}{true} {
+ \left.\mmlfirst{#1}\middle/\mmlsecond{#1}\right.% \thinspace\middle/\thinspace
+ } {
+ \mmlfrac{\mmlfirst{#1}}{\mmlsecond{#1}}
+ }
+ \else % use \ifchknum
+ \doifelse {\xmlval{mml:mfrac:linethickness}{\mmlfraclinethickness}{}} {} {
+ \scratchdimen\xmlval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt}
+ } {
+ % probably not yet ok
+ \setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt}
+ }
+ {
+ {\mmlfirst{#1}}
+ \above\scratchdimen
+ {\mmlsecond{#1}}
+ }
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:ms
+ \hbox {
+ \tf % else encoding problems
+ \ifxmlattempty{#1}{lquote}\symbol[leftquotation]\else\xmllastatt\fi
+ \applymmlsometext{#1}{\xmlflush{#1}}
+ \ifxmlattempty{#1}{rquote}\symbol[rightquotation]\else\xmllastatt\fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mstyle
+ \begingroup
+ \pushmathstyle
+ \setmmlmathstyle{#1}
+ \setmmlscriptlevel{#1}
+ \xmlflush{#1}
+ \popmathstyle
+ \endgroup
+\stopxmlsetups
+
+\setupMMLappearance[text][\c!alternative=\v!b] % a=normal, b=keep spaces
+
+\startxmlsetups mml:mtext
+ \text {
+ \applymmlsometext{#1}{
+ \ifcstok{\MMLtextalternative}\v!a
+ \ignorespaces
+ \xmlflush{#1}
+ \removeunwantedspaces
+ \else
+ \xmlflush{#1}
+ \fi
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:merror
+ \hbox{\startimath\displaystyle\xmlflush{#1}\stopimath}
+\stopxmlsetups
+
+\startxmlsetups mml:mphantom
+ \phantom{\triggermathstyle\normalmathstyle\ignorespaces\xmlflush{#1}\removeunwantedspaces}
+\stopxmlsetups
+
+\startxmlsetups mml:mpadded % todo
+ \xmlflush{#1}
+\stopxmlsetups
+
+% mrow / option: no fenced
+
+\startxmlsetups mml:maction
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:mrow
+ \begingroup
+ \xmlflush{#1}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:msqrt
+ \sqrt{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:mroot
+ \root{\mmlsecond{#1}}\of{\mmlfirst{#1}}
+\stopxmlsetups
+
+\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base
+
+% brrr no { } when limop .. todo: better in lua
+% speed up with ifx and setups or just in lua
+
+\let\mmlnucleus\relax
+
+% maybe make helper
+% \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
+% \ifcstok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}\s!limop
+
+\startxmlsetups mml:msub
+ \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
+ \mmlfirst{#1}
+ \normalsubscript{\mmlsecond{#1}}
+ \orelse\ifcstok{\MMLscriptsalternative}\v!a
+ {\mmlfirst{#1}}
+ \normalsubscript{\mmlsecond{#1}}
+ \else
+ \mmlfirst{#1}
+ \normalsubscript{\mmlsecond{#1}}
+ \fi
+\stopxmlsetups
+
+\startxmlsetups mml:msup
+ \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
+ \mmlfirst{#1}
+ \normalsuperscript{\mmlsecond{#1}}
+ \orelse\ifcstok{\MMLscriptsalternative}\v!a
+ {\mmlfirst{#1}}
+ \normalsuperscript{\mmlsecond{#1}}
+ \else
+ \mmlfirst{#1}
+ \normalsuperscript{\mmlsecond{#1}}
+ \fi
+\stopxmlsetups
+
+% use mathclass number
+
+\startxmlsetups mml:msubsup
+ \iftok{\utfmathclass{\xmlraw{#1}{/mml:*[1]}}}{limop}
+ \mmlfirst{#1}
+ \normalsubscript{\mmlsecond{#1}}
+ \normalsuperscript{\mmlthird{#1}}
+ \orelse\ifcstok{\MMLscriptsalternative}\v!a
+ {\mmlfirst{#1}}
+ \normalsubscript{\mmlsecond{#1}}
+ \normalsuperscript{\mmlthird {#1}}
+ \else
+ \mmlfirst{#1}
+ \normalsubscript{\mmlsecond{#1}}
+ \normalsuperscript{\mmlthird {#1}}
+ \fi
+\stopxmlsetups
+
+% helpers
+
+\protected\def\mmlexecutecommand#1%
+ {\ifcsname#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi
+ \lastnamedcs}
+
+\let\mmlextensible\mathml_extensible
+
+\definemathtriplet [\v!mathematics] [mmlovertriplet] % or will we use a special instance
+\definemathtriplet [\v!mathematics] [mmlundertriplet] % or will we use a special instance
+\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance
+
+% common to munder/mover/munderover : will become core helper (speed up too)
+
+\starttexdefinition protected mmlfencedfirst #1
+ \xmlelement{#1}{1}
+\stoptexdefinition
+\starttexdefinition protected mmlfencedsecond #1
+ \xmlelement{#1}{2}
+\stoptexdefinition
+\starttexdefinition protected mmlfencedthird #1
+ \xmlelement{#1}{3}
+\stoptexdefinition
+
+% mover
+
+\starttexdefinition protected mmloverabove #1
+ \mmlexecutecommand{\utfmathfiller\mmlovertoken} {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition protected mmloverbase #1
+ \mmlexecutecommand{\utfmathfiller\mmlbasetoken} {\mmlfencedfirst{#1}} \relax
+\stoptexdefinition
+\starttexdefinition protected mmloverbasefiller #1
+ \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {\mmlfencedsecond{#1}} {}
+\stoptexdefinition
+\starttexdefinition protected mmloveraccent #1
+ \mmlexecutecommand{\utfmathcommandabove\mmlovertoken} \relax {\mmlfencedfirst{#1}}
+\stoptexdefinition
+
+\starttexdefinition protected mmlovertext #1
+ \mmlovertriplet {\mmloverbase{#1}} {\mmloverabove{#1}} {}
+\stoptexdefinition
+\starttexdefinition protected mmloveraccentchecker #1
+ \edef\mmlovertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \doifelseutfmathabove\mmlovertoken \mmloveraccent \mmlovertext {#1}
+\stoptexdefinition
+
+\startxmlsetups mml:mover
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathlimop\mmlbasetoken
+ {\mmllimopover{#1}}
+ {\doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1}}
+\stopxmlsetups
+
+\starttexdefinition mmllimopover #1
+ \mmlbasetoken\normalsuperscript{\mmlfencedsecond{#1}}
+\stoptexdefinition
+
+% munder
+
+\starttexdefinition protected mmlunderbelow #1
+ \mmlexecutecommand{\utfmathfiller\mmlundertoken} {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition protected mmlunderbase #1
+ \mmlexecutecommand{\utfmathfiller\mmlbasetoken} {\mmlfencedfirst{#1}} \relax
+\stoptexdefinition
+\starttexdefinition protected mmlunderbasefiller #1
+ \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {} {\mmlfencedsecond{#1}}
+\stoptexdefinition
+\starttexdefinition protected mmlunderaccent #1
+ \mmlexecutecommand{\utfmathcommandbelow\mmlundertoken} \relax {\mmlfencedfirst{#1}}
+\stoptexdefinition
+
+\starttexdefinition protected mmlundertext #1
+ \mmlundertriplet {\mmlunderbase{#1}} {} {\mmlunderbelow{#1}}
+\stoptexdefinition
+\starttexdefinition protected mmlunderaccentchecker #1
+ \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \doifelseutfmathbelow\mmlundertoken \mmlunderaccent \mmlundertext {#1}
+\stoptexdefinition
+
+\startxmlsetups mml:munder
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathlimop\mmlbasetoken
+ {\mmllimopunder{#1}}
+ {\doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1}}
+\stopxmlsetups
+
+\starttexdefinition mmllimopunder #1
+ \mmlbasetoken\normalsubscript{\mmlfencedsecond{#1}}
+\stoptexdefinition
+
+% munderover
+
+\starttexdefinition protected mmlunderoveraccentcheckerUO #1
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \edef\mmlovercommand {\utfmathcommandabove\mmlovertoken}
+ \edef\mmlbasecommand {\mmlovercommand\mmlundercommand}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}}
+ \orelse\ifcsname\mmlundercommand\endcsname
+ \ifcsname\mmlovercommand\endcsname
+ \lastnamedcs {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}}
+ \else
+ \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}\mmlfencedthird{#1}} {}
+ \fi
+ \orelse\ifcsname\mmlovercommand\endcsname
+ \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi
+\stoptexdefinition
+\starttexdefinition protected mmlunderoveraccentcheckerUT #1
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \edef\mmlbasecommand {\mmlundercommand text}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}}
+ \orelse\ifcsname\mmlundercommand\endcsname
+ \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}} {}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi
+\stoptexdefinition
+\starttexdefinition protected mmlunderoveraccentcheckerOT #1
+ \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken}
+ \edef\mmlbasecommand{\mmlovercommand text}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedsecond{#1}}
+ \orelse\ifcsname\mmlovercommand\endcsname
+ \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi
+\stoptexdefinition
+\starttexdefinition protected mmlunderoveraccentcheckerTT #1
+ \mmldoubletriplet {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition protected mmlunderoveraccentchecker #1
+ \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \edef\mmlovertoken {\mmlextensible{\xmlraw{#1}{/mml:*[3]}}}% /text()
+ \doifelseutfmathbelow\mmlundertoken {
+ \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerUO \mmlunderoveraccentcheckerUT {#1}
+ } {
+ \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerOT \mmlunderoveraccentcheckerTT {#1}
+ }
+\stoptexdefinition
+
+\starttexdefinition protected mmlunderoverbasefiller #1
+ \mmlexecutecommand{e\utfmathcommandfiller\mmlbasetoken} \relax {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}}
+\stoptexdefinition
+
+\startxmlsetups mml:munderover
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathlimop\mmlbasetoken
+ {\mmllimopunderover{#1}}
+ {\doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1}}
+\stopxmlsetups
+
+\starttexdefinition mmllimopunderover #1
+ \mmlbasetoken\normalsuperscript{\mmlfencedthird{#1}}\normalsubscript{\mmlfencedsecond{#1}}
+\stoptexdefinition
+
+% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd)
+
+\startxmlsetups mml:mtable % some more attributes need to be supported
+ \vcenter {
+ \hbox {% needed because otherwise positions make the vcenter wide
+ \mathml_mtable{#1}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mcolumn
+ \vbox{\mathml_mcolumn{#1}}% needs checking
+\stopxmlsetups
+
+\def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox}
+
+\def\mmlmcolumndigitspace {\mmlsetfakewidth {0}\kern\scratchdimen}
+\def\mmlmcolumndigitrule {\mmlsetfakewidth {0}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+\def\mmlmcolumnsymbolrule {\mmlsetfakewidth{\times}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+\def\mmlmcolumnpunctuationrule{\mmlsetfakewidth {.}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+
+\setupMMLappearance[mspace][\c!option=] % \v!test
+
+\startxmlsetups mml:mspace
+ \begingroup
+ \edef\mmlspacetext{\xmlatt{#1}{spacing}}
+ \ifempty\mmlspacetext
+ \scratchwidth \xmlattdef{#1}{width} \!!zeropoint % must be string
+ \scratchheight\xmlattdef{#1}{height}\!!zeropoint
+ \scratchdepth \xmlattdef{#1}{depth} \!!zeropoint
+ \ifdim\scratchheight=\zeropoint
+ \ifdim\scratchdepth=\zeropoint\else
+ \novrule\s!depth\scratchdepth\s!height\zeropoint\s!width\zeropoint
+ \fi
+ \else
+ \novrule\s!depth\zeropoint\s!height\scratchheight\s!width\zeropoint
+ \fi
+ \ifdim\scratchwidth=\zeropoint
+ \orelse\ifx\MMLmspaceoption\v!test
+ \hbox to \scratchwidth{\showstruts\strut\hss\lower2\exheight\hbox{\infofont\xmlattdef{#1}{width}}\hss\strut}
+ \else
+ \hskip\scratchwidth
+ \fi
+ \orelse\ifx\MMLmspaceoption\v!test
+ \hbox{\showstruts\strut\phantom{\triggermathstyle\normalmathstyle\mmlspacetext}\strut}
+ \else
+ \phantom{\triggermathstyle\normalmathstyle\mmlspacetext}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+% later we can do a better job by manipulating node lists
+
+% \startxmlsetups mml:mline
+% % new, rather undefined, we need to capture a few keywords
+% \edef\mmllinewidth {\xmlatt{#1}{linethickness}}
+% \edef\mmllinetext {\xmlatt{#1}{spacing}}
+% \edef\mmllinelength{\xmlattdef{#1}{length}\!!zeropoint}
+% \ifempty\mmllinewidth
+% \!!deptha.5\linewidth
+% \else
+% \!!deptha.5\dimexpr\mmllinewidth\relax
+% \fi
+% \!!heighta\!!deptha
+% \ifempty\mmllinetext
+% \ifempty\mmllinelength
+% \!!widtha\zeropoint
+% \else
+% \!!widtha\mmllinelength
+% \fi
+% \else
+% \setbox\scratchbox\hbox{\mathematics{\mathstyle{\mmllinetext}}}% not ok
+% \!!widtha\wd\scratchbox
+% \fi
+% \hbox{\vrule\s!width\!!widtha\s!depth\!!deptha\s!height\!!heighta}
+% \stopxmlsetups
+
+\startxmlsetups mml:mglyph % probably never ok (hbox is needed in order to switch to normal font)
+ \begingroup
+ \edef\mmlglyphfontfamily{\xmlatt {#1}{fontfamily}}
+ \edef\mmlglyphalt {\xmlattdef{#1}{alt}{unknown}}
+ \edef\mmlglyphindex {\xmlatt {#1}{index}}
+ \ifempty\mmlglyphfontfamily
+ \hbox{\tttf[no fontfamily specified for \mmlglyphalt]}
+ \orelse\ifempty\mmlglyphindex
+ \hbox{\tttf[no index specified for \mmlglyphalt]}
+ \else
+ \hbox{\getglyph\mmlglyphfontfamily\mmlglyphindex}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:maligngroup \stopxmlsetups % will be done when needed
+\startxmlsetups mml:malignmark \stopxmlsetups % will be done when needed
+
+\startxmlsetups mml:none \stopxmlsetups
+\startxmlsetups mml:mprescripts \stopxmlsetups
+
+\startxmlsetups mml:mmultiscripts
+ \mathml_mmultiscripts{#1}
+\stopxmlsetups
+
+% goodie
+
+\definebuffer[mml]
+
+\permanent\protected\def\stopmml{\xmlprocessbuffer{@mml@}{\thedefinedbuffer{mml}}{}}
+
+\stopmodule
+
+\protect \endinput
+
+% TODO:
+%
+% <apply><divide/>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% </apply>
diff --git a/tex/context/patterns/lmtx/lang-de.llg b/tex/context/patterns/mkxl/lang-de.llg
index 89b8eef1f..89b8eef1f 100644
--- a/tex/context/patterns/lmtx/lang-de.llg
+++ b/tex/context/patterns/mkxl/lang-de.llg
diff --git a/tex/context/patterns/lmtx/lang-en.llg b/tex/context/patterns/mkxl/lang-en.llg
index 5378e0aa9..5378e0aa9 100644
--- a/tex/context/patterns/lmtx/lang-en.llg
+++ b/tex/context/patterns/mkxl/lang-en.llg
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index a28630bfe..96393e4c2 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2021-06-04 17:20
+-- merge date : 2021-06-07 08:05
do -- begin closure to overcome local limits and interference