summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/math-tag.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/math-tag.lmt')
-rw-r--r--tex/context/base/mkiv/math-tag.lmt596
1 files changed, 0 insertions, 596 deletions
diff --git a/tex/context/base/mkiv/math-tag.lmt b/tex/context/base/mkiv/math-tag.lmt
deleted file mode 100644
index eb58b5450..000000000
--- a/tex/context/base/mkiv/math-tag.lmt
+++ /dev/null
@@ -1,596 +0,0 @@
-if not modules then modules = { } end modules ['math-tag'] = {
- version = 1.001,
- comment = "companion to math-ini.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- todo: have a local list with local tags that then get appended
--- todo: use tex.getmathcodes (no table)
-
--- use lpeg matchers
-
-local find, match = string.find, string.match
-local insert, remove, concat = table.insert, table.remove, table.concat
-
-local attributes = attributes
-local nodes = nodes
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-
-local getnext = nuts.getnext
-local getid = nuts.getid
-local getchar = nuts.getchar
-local getfont = nuts.getfont
-local getlist = nuts.getlist
-local getfield = nuts.getfield
-local getdisc = nuts.getdisc
-local getsubtype = nuts.getsubtype
-local getattr = nuts.getattr
-local getattrlist = nuts.getattrlist
-local setattr = nuts.setattr
------ getcomponents = nuts.getcomponents -- not really needed
-local getwidth = nuts.getwidth
-
-local getnucleus = nuts.getnucleus
-local getsub = nuts.getsub
-local getsup = nuts.getsup
-
-local set_attributes = nuts.setattributes
-
-local nextnode = nuts.traversers.node
-
-local nodecodes = nodes.nodecodes
-
-local noad_code = nodecodes.noad -- attr nucleus sub sup
-local accent_code = nodecodes.accent -- attr nucleus sub sup accent
-local radical_code = nodecodes.radical -- attr nucleus sub sup left degree
-local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right
-local subbox_code = nodecodes.subbox -- attr list
-local submlist_code = nodecodes.submlist -- attr list
-local mathchar_code = nodecodes.mathchar -- attr fam char
-local mathtextchar_code = nodecodes.mathtextchar -- attr fam char
-local delimiter_code = nodecodes.delimiter -- attr small_fam small_char large_fam large_char
-local style_code = nodecodes.style -- attr style
-local choice_code = nodecodes.choice -- attr display text script scriptscript
-local fence_code = nodecodes.fence -- attr subtype
-
-local accentcodes = nodes.accentcodes
-local fencecodes = nodes.fencecodes
-
-local fixedtopaccent_code = accentcodes.fixedtop
-local fixedbottomaccent_code = accentcodes.fixedbottom
-local fixedbothaccent_code = accentcodes.fixedboth
-
-local leftfence_code = fencecodes.left
-local middlefence_code = fencecodes.middle
-local rightfence_code = fencecodes.right
-
-local kerncodes = nodes.kerncodes
-
-local fontkern_code = kerncodes.fontkern
-local italickern_code = kerncodes.italickern
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local glyph_code = nodecodes.glyph
-local disc_code = nodecodes.disc
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local math_code = nodecodes.math
-
-local processnoads = noads.process
-
-local a_tagged = attributes.private('tagged')
-local a_mathcategory = attributes.private('mathcategory')
-local a_mathmode = attributes.private('mathmode')
-
-local tags = structures.tags
-
-local start_tagged = tags.start
-local restart_tagged = tags.restart
-local stop_tagged = tags.stop
-local taglist = tags.taglist
-
-local chardata = characters.data
-
-local getmathcodes = tex.getmathcodes
-local mathcodes = mathematics.codes
-local ordinary_mathcode = mathcodes.ordinary
-local variable_mathcode = mathcodes.variable
-
-local fromunicode16 = fonts.mappings.fromunicode16
-local fontcharacters = fonts.hashes.characters
-
-local report_tags = logs.reporter("structure","tags")
-
-local process
-
-local function processsubsup(start)
- -- At some point we might need to add an attribute signaling the
- -- super- and subscripts because TeX and MathML use a different
- -- order. The mrows are needed to keep mn's separated.
- local nucleus = getnucleus(start)
- local sup = getsup(start)
- local sub = getsub(start)
- if sub then
- if sup then
- setattr(start,a_tagged,start_tagged("msubsup"))
- -- start_tagged("mrow")
- process(nucleus)
- -- stop_tagged()
- start_tagged("mrow", { subscript = true })
- process(sub)
- stop_tagged()
- start_tagged("mrow", { superscript = true })
- process(sup)
- stop_tagged()
- stop_tagged()
- else
- setattr(start,a_tagged,start_tagged("msub"))
- -- start_tagged("mrow")
- process(nucleus)
- -- stop_tagged()
- start_tagged("mrow")
- process(sub)
- stop_tagged()
- stop_tagged()
- end
- elseif sup then
- setattr(start,a_tagged,start_tagged("msup"))
- -- start_tagged("mrow")
- process(nucleus)
- -- stop_tagged()
- start_tagged("mrow")
- process(sup)
- stop_tagged()
- stop_tagged()
- else
- process(nucleus)
- end
-end
-
--- todo: check function here and keep attribute the same
-
--- todo: variants -> original
-
-local actionstack = { }
-local fencesstack = { }
-
--- glyph nodes and such can happen in under and over stuff
-
--- local function getunicode(n) -- instead of getchar
--- local char = getchar(n)
--- -- local font = getfontoffamily(getfield(n,"fam"))
--- local font = getfont(n)
--- local data = fontcharacters[font][char]
--- return data.unicode or char
--- end
-
-local function getunicode(n) -- instead of getchar
- -- local char, font = isglyph(n) -- no, we have a mathchar
- local char, font = getchar(n), getfont(n)
- local data = fontcharacters[font][char]
- return data.unicode or char -- can be a table but unlikely for math characters
-end
-
--------------------
-
-local content = { }
-local found = false
-
-content[mathchar_code] = function() found = true end
-
-local function hascontent(head)
- found = false
- processnoads(head,content,"content")
- return found
-end
-
---------------------
-
--- todo: use properties
-
--- local function showtag(n,id,old)
--- local attr = getattr(n,a_tagged)
--- local curr = tags.current()
--- report_tags("%s, node %s, attr %s:%s (%s), top %s (%s)",
--- old and "before" or "after ",
--- nodecodes[id],
--- getattrlist(n),
--- attr or "?",attr and taglist[attr].tagname or "?",
--- curr or "?",curr and taglist[curr].tagname or "?"
--- )
--- end
-
-process = function(start) -- we cannot use the processor as we have no finalizers (yet)
- local mtexttag = nil
- while start do
- local id = getid(start)
--- showtag(start,id,true)
- if id == glyph_code or id == disc_code then
- if not mtexttag then
- mtexttag = start_tagged("mtext")
- end
- setattr(start,a_tagged,mtexttag)
- elseif mtexttag and id == kern_code and (getsubtype(start) == fontkern_code or getsubtype(start) == italickern_code) then -- italickern
- setattr(start,a_tagged,mtexttag)
- else
- if mtexttag then
- stop_tagged()
- mtexttag = nil
- end
- if id == mathchar_code then
- local char = getchar(start)
- local code = getmathcodes(char)
- local tag
- if code == ordinary_mathcode or code == variable_mathcode then
- local ch = chardata[char]
- local mc = ch and ch.mathclass
- if mc == "number" then
- tag = "mn"
- elseif mc == "variable" or not mc then -- variable is default
- tag = "mi"
- else
- tag = "mo"
- end
- else
- tag = "mo"
- end
- local a = getattr(start,a_mathcategory)
- if a then
- setattr(start,a_tagged,start_tagged(tag,{ mathcategory = a }))
- else
- setattr(start,a_tagged,start_tagged(tag)) -- todo: a_mathcategory
- end
- stop_tagged()
- -- showtag(start,id,false)
- break -- okay?
- elseif id == mathtextchar_code then -- or id == glyph_code
- -- check for code
- local a = getattr(start,a_mathcategory)
- if a then
- setattr(start,a_tagged,start_tagged("ms",{ mathcategory = a })) -- mtext
- else
- setattr(start,a_tagged,start_tagged("ms")) -- mtext
- end
- stop_tagged()
- -- showtag(start,id,false)
- break
- elseif id == delimiter_code then
- -- check for code
- setattr(start,a_tagged,start_tagged("mo"))
- stop_tagged()
- -- showtag(start,id,false)
- break
- elseif id == style_code then
- -- has a next
- elseif id == noad_code then
- -- setattr(start,a_tagged,tags.current())
- processsubsup(start)
- elseif id == subbox_code or id == hlist_code or id == vlist_code then
- -- keep an eye on subbox_code and see what ends up in there
- local attr = getattr(start,a_tagged)
- if not attr then
- -- just skip
- else
- local specification = taglist[attr]
- if specification then
- local tag = specification.tagname
- if tag == "formulacaption" then
- -- skip
- elseif tag == "mstacker" then
- local list = getlist(start)
- if list then
- process(list)
- end
- else
- if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then
- tag = "mtext"
- end
- local text = start_tagged(tag)
- setattr(start,a_tagged,text)
- local list = getlist(start)
- if not list then
- -- empty list
- elseif not attr then
- -- box comes from strange place
- set_attributes(list,a_tagged,text) -- only the first node ?
- else
- -- Beware, the first node in list is the actual list so we definitely
- -- need to nest. This approach is a hack, maybe I'll make a proper
- -- nesting feature to deal with this at another level. Here we just
- -- fake structure by enforcing the inner one.
- --
- -- todo: have a local list with local tags that then get appended
- --
- local tagdata = specification.taglist
- local common = #tagdata + 1
- local function runner(list,depth) -- quite inefficient
- local cache = { } -- we can have nested unboxed mess so best local to runner
- local keep = nil
- -- local keep = { } -- win case we might need to move keep outside
- for n, id, subtype in nextnode, list do
- local mth = id == math_code and subtype
- if mth == 0 then -- hm left_code
- -- insert(keep,text)
- keep = text
- text = start_tagged("mrow")
- common = common + 1
- end
- local aa = getattr(n,a_tagged)
- if aa then
- local ac = cache[aa]
- if not ac then
- local tagdata = taglist[aa].taglist
- local extra = #tagdata
- if common <= extra then
- for i=common,extra do
- ac = restart_tagged(tagdata[i]) -- can be made faster
- end
- for i=common,extra do
- stop_tagged() -- can be made faster
- end
- else
- ac = text
- end
- cache[aa] = ac
- end
- setattr(n,a_tagged,ac)
- else
- setattr(n,a_tagged,text)
- end
- if id == hlist_code or id == vlist_code then
- runner(getlist(n),depth+1)
- elseif id == glyph_code then
- -- this should not be needed
- -- local components = getcomponents(n) -- unlikely set
- -- if components then
- -- runner(getcomponent,depth+1)
- -- end
- elseif id == disc_code then
- -- this should not be needed
- local pre, post, replace = getdisc(n)
- if pre then
- runner(pre,depth+1)
- end
- if post then
- runner(post,depth+1)
- end
- if replace then
- runner(replace,depth+1)
- end
- end
- if mth == 1 then
- stop_tagged()
- -- text = remove(keep)
- text = keep
- common = common - 1
- end
- end
- end
- runner(list,0)
- end
- stop_tagged()
- end
- end
- end
- elseif id == submlist_code then -- normally a hbox
- local list = getlist(start)
- if list then
- local attr = getattr(start,a_tagged)
- local last = attr and taglist[attr]
- if last then
- local tag = last.tagname
- local detail = last.detail
- if tag == "maction" then
- if detail == "" then
- setattr(start,a_tagged,start_tagged("mrow"))
- process(list)
- stop_tagged()
- elseif actionstack[#actionstack] == action then
- setattr(start,a_tagged,start_tagged("mrow"))
- process(list)
- stop_tagged()
- else
- insert(actionstack,action)
- setattr(start,a_tagged,start_tagged("mrow",{ detail = action }))
- process(list)
- stop_tagged()
- remove(actionstack)
- end
- elseif tag == "mstacker" then -- or tag == "mstackertop" or tag == "mstackermid" or tag == "mstackerbot" then
- -- looks like it gets processed twice
- -- do we still end up here ?
- setattr(start,a_tagged,restart_tagged(attr)) -- so we just reuse the attribute
- process(list)
- stop_tagged()
- else
- setattr(start,a_tagged,start_tagged("mrow"))
- process(list)
- stop_tagged()
- end
- else -- never happens, we're always document
- setattr(start,a_tagged,start_tagged("mrow"))
- process(list)
- stop_tagged()
- end
- end
- elseif id == fraction_code then
- local num = getfield(start,"num")
- local denom = getfield(start,"denom")
- local left = getfield(start,"left")
- local right = getfield(start,"right")
- if left then
- setattr(left,a_tagged,start_tagged("mo"))
- process(left)
- stop_tagged()
- end
- setattr(start,a_tagged,start_tagged("mfrac"))
- process(num)
- process(denom)
- stop_tagged()
- if right then
- setattr(right,a_tagged,start_tagged("mo"))
- process(right)
- stop_tagged()
- end
- elseif id == choice_code then
- local display = getfield(start,"display")
- local text = getfield(start,"text")
- local script = getfield(start,"script")
- local scriptscript = getfield(start,"scriptscript")
- if display then
- process(display)
- end
- if text then
- process(text)
- end
- if script then
- process(script)
- end
- if scriptscript then
- process(scriptscript)
- end
- elseif id == fence_code then
- local subtype = getsubtype(start)
- local delim = getfield(start,"delimiter")
- if subtype == leftfence_code then
- -- left
- local properties = { }
- insert(fencesstack,properties)
- setattr(start,a_tagged,start_tagged("mfenced",properties)) -- needs checking
- if delim then
- start_tagged("ignore")
- local chr = getchar(delim)
- if chr ~= 0 then
- properties.left = chr
- end
- process(delim)
- stop_tagged()
- end
- start_tagged("mrow") -- begin of subsequence
- elseif subtype == middlefence_code then
- -- middle
- if delim then
- start_tagged("ignore")
- local top = fencesstack[#fencesstack]
- local chr = getchar(delim)
- if chr ~= 0 then
- local mid = top.middle
- if mid then
- mid[#mid+1] = chr
- else
- top.middle = { chr }
- end
- end
- process(delim)
- stop_tagged()
- end
- stop_tagged() -- end of subsequence
- start_tagged("mrow") -- begin of subsequence
- elseif subtype == rightfence_code then
- local properties = remove(fencesstack)
- if not properties then
- report_tags("missing right fence")
- properties = { }
- end
- if delim then
- start_tagged("ignore")
- local chr = getchar(delim)
- if chr ~= 0 then
- properties.right = chr
- end
- process(delim)
- stop_tagged()
- end
- stop_tagged() -- end of subsequence
- stop_tagged()
- else
- -- can't happen
- end
- elseif id == radical_code then
- local left = getfield(start,"left")
- local degree = getfield(start,"degree")
- if left then
- start_tagged("ignore")
- process(left) -- root symbol, ignored
- stop_tagged()
- end
- if degree and hascontent(degree) then
- setattr(start,a_tagged,start_tagged("mroot"))
- processsubsup(start)
- process(degree)
- stop_tagged()
- else
- setattr(start,a_tagged,start_tagged("msqrt"))
- processsubsup(start)
- stop_tagged()
- end
- elseif id == accent_code then
- local subtype = getsubtype(start)
- local accent = getfield(start,"accent")
- local bot_accent = getfield(start,"bot_accent")
- if bot_accent then
- if accent then
- setattr(start,a_tagged,start_tagged("munderover", {
- accent = true,
- top = getunicode(accent),
- bottom = getunicode(bot_accent),
- topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code,
- bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code,
- }))
- processsubsup(start)
- process(bot_accent)
- process(accent)
- stop_tagged()
- else
- setattr(start,a_tagged,start_tagged("munder", {
- accent = true,
- bottom = getunicode(bot_accent),
- bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code,
- }))
- processsubsup(start)
- process(bot_accent)
- stop_tagged()
- end
- elseif accent then
- setattr(start,a_tagged,start_tagged("mover", {
- accent = true,
- top = getunicode(accent),
- topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code,
- }))
- processsubsup(start)
- process(accent)
- stop_tagged()
- else
- processsubsup(start)
- end
- elseif id == glue_code then
- -- setattr(start,a_tagged,start_tagged("mspace",{ width = getwidth(start) }))
- setattr(start,a_tagged,start_tagged("mspace"))
- stop_tagged()
- else
- setattr(start,a_tagged,start_tagged("merror", { detail = nodecodes[i] }))
- stop_tagged()
- end
- end
--- showtag(start,id,false)
- start = getnext(start)
- end
- if mtexttag then
- stop_tagged()
- end
-end
-
-function noads.handlers.tags(head,style,penalties)
- start_tagged("math", { mode = (getattr(head,a_mathmode) == 1) and "display" or "inline" })
- setattr(head,a_tagged,start_tagged("mrow"))
--- showtag(head,getid(head),true)
- process(head)
--- showtag(head,getid(head),false)
- stop_tagged()
- stop_tagged()
-end