summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/math-noa.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-08-07 12:17:12 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-08-07 12:17:12 +0200
commit58574b14679ae5796ea24a506ba27faf838c10ba (patch)
treee25dbc01e72202d3f568e8b1cf3437fd3b0967e9 /tex/context/base/mkiv/math-noa.lua
parent5c6090af6fb0808017d6f2fe263b90e2efa0ae5e (diff)
downloadcontext-58574b14679ae5796ea24a506ba27faf838c10ba.tar.gz
2017-08-07 11:35:00
Diffstat (limited to 'tex/context/base/mkiv/math-noa.lua')
-rw-r--r--tex/context/base/mkiv/math-noa.lua1403
1 files changed, 719 insertions, 684 deletions
diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua
index bd1d551e7..317b2b6f1 100644
--- a/tex/context/base/mkiv/math-noa.lua
+++ b/tex/context/base/mkiv/math-noa.lua
@@ -538,20 +538,20 @@ end
do
- local a_mathalphabet = privateattribute("mathalphabet")
- local a_mathgreek = privateattribute("mathgreek")
+ local a_mathalphabet = privateattribute("mathalphabet")
+ local a_mathgreek = privateattribute("mathgreek")
- processors.relocate = { }
+ local relocate = { }
+
+ local remapalphabets = mathematics.remapalphabets
+ local fallbackstyleattr = mathematics.fallbackstyleattr
+ local setnodecolor = nodes.tracers.colors.set
local function report_remap(tag,id,old,new,extra)
report_remapping("remapping %s in font (%s,%s) from %C to %C%s",
tag,id,fontdata[id].properties.fontname or "",old,new,extra)
end
- local remapalphabets = mathematics.remapalphabets
- local fallbackstyleattr = mathematics.fallbackstyleattr
- local setnodecolor = nodes.tracers.colors.set
-
local function checked(pointer)
local char = getchar(pointer)
local font = getfont(pointer)
@@ -573,7 +573,7 @@ do
end
end
- processors.relocate[math_char] = function(pointer)
+ relocate[math_char] = function(pointer)
local g = getattr(pointer,a_mathgreek) or 0
local a = getattr(pointer,a_mathalphabet) or 0
local char = getchar(pointer)
@@ -640,20 +640,20 @@ do
end
end
- processors.relocate[math_textchar] = function(pointer)
+ relocate[math_textchar] = function(pointer)
if trace_analyzing then
setnodecolor(pointer,"font:init")
end
end
- processors.relocate[math_delim] = function(pointer)
+ relocate[math_delim] = function(pointer)
if trace_analyzing then
setnodecolor(pointer,"font:fina")
end
end
function handlers.relocate(head,style,penalties)
- processnoads(head,processors.relocate,"relocate")
+ processnoads(head,relocate,"relocate")
return true
end
@@ -661,32 +661,36 @@ end
-- rendering (beware, not exported)
-processors.render = { }
-
-local rendersets = mathematics.renderings.numbers or { } -- store
+do
-processors.render[math_char] = function(pointer)
- local attr = getattr(pointer,a_mathrendering)
- if attr and attr > 0 then
- local char = getchar(pointer)
- local renderset = rendersets[attr]
- if renderset then
- local newchar = renderset[char]
- if newchar then
- local font = getfont(pointer)
- local characters = fontcharacters[font]
- if characters and characters[newchar] then
- setchar(pointer,newchar)
- setattr(pointer,a_exportstatus,char)
+ local render = { }
+
+ local rendersets = mathematics.renderings.numbers or { } -- store
+
+ render[math_char] = function(pointer)
+ local attr = getattr(pointer,a_mathrendering)
+ if attr and attr > 0 then
+ local char = getchar(pointer)
+ local renderset = rendersets[attr]
+ if renderset then
+ local newchar = renderset[char]
+ if newchar then
+ local font = getfont(pointer)
+ local characters = fontcharacters[font]
+ if characters and characters[newchar] then
+ setchar(pointer,newchar)
+ setattr(pointer,a_exportstatus,char)
+ end
end
end
end
end
-end
-function handlers.render(head,style,penalties)
- processnoads(head,processors.render,"render")
- return true
+ function handlers.render(head,style,penalties)
+ processnoads(head,render,"render")
+ return true
+ end
+
end
-- some resize options (this works ok because the content is
@@ -699,347 +703,361 @@ end
-- todo: just replace the character by an ord noad
-- and remove the right delimiter as well
-local a_mathsize = privateattribute("mathsize") -- this might move into other fence code
-local resize = { }
-processors.resize = resize
+do
-resize[math_fence] = function(pointer)
- local subtype = getsubtype(pointer)
- if subtype == left_fence_code or subtype == right_fence_code then
- local a = getattr(pointer,a_mathsize)
- if a and a > 0 then
- local method, size = div(a,100), a % 100
- setattr(pointer,a_mathsize,0)
- local delimiter = getfield(pointer,"delim")
- local chr = getfield(delimiter,"small_char")
- if chr > 0 then
- local fam = getfield(delimiter,"small_fam")
- local id = font_of_family(fam)
- if id > 0 then
- setfield(delimiter,"small_char",mathematics.big(fontdata[id],chr,size,method))
+ local a_mathsize = privateattribute("mathsize") -- this might move into other fence code
+ local resize = { }
+
+ resize[math_fence] = function(pointer)
+ local subtype = getsubtype(pointer)
+ if subtype == left_fence_code or subtype == right_fence_code then
+ local a = getattr(pointer,a_mathsize)
+ if a and a > 0 then
+ local method, size = div(a,100), a % 100
+ setattr(pointer,a_mathsize,0)
+ local delimiter = getfield(pointer,"delim")
+ local chr = getfield(delimiter,"small_char")
+ if chr > 0 then
+ local fam = getfield(delimiter,"small_fam")
+ local id = font_of_family(fam)
+ if id > 0 then
+ setfield(delimiter,"small_char",mathematics.big(fontdata[id],chr,size,method))
+ end
end
end
end
end
-end
-function handlers.resize(head,style,penalties)
- processnoads(head,resize,"resize")
- return true
+ function handlers.resize(head,style,penalties)
+ processnoads(head,resize,"resize")
+ return true
+ end
+
end
-- still not perfect:
-local a_autofence = privateattribute("mathautofence")
-local autofences = { }
-processors.autofences = autofences
-local dummyfencechar = 0x2E
-
-local function makefence(what,char)
- local d = new_delimiter()
- local f = new_fence()
- if char then
- local sym = getnucleus(char)
- local chr = getchar(sym)
- local fam = getfield(sym,"fam")
- if chr == dummyfencechar then
- chr = 0
+do
+
+ local a_autofence = privateattribute("mathautofence")
+ local autofences = { }
+ local dummyfencechar = 0x2E
+
+ local function makefence(what,char)
+ local d = new_delimiter()
+ local f = new_fence()
+ if char then
+ local sym = getnucleus(char)
+ local chr = getchar(sym)
+ local fam = getfield(sym,"fam")
+ if chr == dummyfencechar then
+ chr = 0
+ end
+ setfield(d,"small_char",chr)
+ setfield(d,"small_fam", fam)
+ flush_node(sym)
end
- setfield(d,"small_char",chr)
- setfield(d,"small_fam", fam)
- flush_node(sym)
- end
- setsubtype(f,what)
- setfield(f,"delim",d)
- setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what]
- return f
-end
+ setsubtype(f,what)
+ setfield(f,"delim",d)
+ setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what]
+ return f
+ end
-local function makelist(noad,f_o,o_next,c_prev,f_c,middle)
- local list = new_submlist()
- setlist(list,f_o)
- setsubtype(noad,noad_inner)
- setnucleus(noad,list)
- setlink(f_o,o_next)
- setlink(c_prev,f_c)
- if middle and next(middle) then
- local prev = f_o
- local current = o_next
- while current ~= f_c do
- local m = middle[current]
- if m then
- local next = getnext(current)
- local fence = makefence(middle_fence_code,current)
- setnucleus(current)
- flush_node(current)
- middle[current] = nil
- -- replace_node
- setlink(prev,fence,next)
- prev = fence
- current = next
- else
- prev = current
- current = getnext(current)
+ local function makelist(noad,f_o,o_next,c_prev,f_c,middle)
+ local list = new_submlist()
+ setlist(list,f_o)
+ setsubtype(noad,noad_inner)
+ setnucleus(noad,list)
+ setlink(f_o,o_next)
+ setlink(c_prev,f_c)
+ if middle and next(middle) then
+ local prev = f_o
+ local current = o_next
+ while current ~= f_c do
+ local m = middle[current]
+ if m then
+ local next = getnext(current)
+ local fence = makefence(middle_fence_code,current)
+ setnucleus(current)
+ flush_node(current)
+ middle[current] = nil
+ -- replace_node
+ setlink(prev,fence,next)
+ prev = fence
+ current = next
+ else
+ prev = current
+ current = getnext(current)
+ end
end
end
end
-end
-local function convert_both(open,close,middle)
- local o_prev, o_next = getboth(open)
- local c_prev, c_next = getboth(close)
- if o_next == close then
- return close
- else
+ local function convert_both(open,close,middle)
+ local o_prev, o_next = getboth(open)
+ local c_prev, c_next = getboth(close)
+ if o_next == close then
+ return close
+ else
+ local f_o = makefence(left_fence_code,open)
+ local f_c = makefence(right_fence_code,close)
+ makelist(open,f_o,o_next,c_prev,f_c,middle)
+ setnucleus(close)
+ flush_node(close)
+ if c_next then
+ setprev(c_next,open)
+ end
+ setnext(open,c_next)
+ return open
+ end
+ end
+
+ local function convert_open(open,last,middle)
local f_o = makefence(left_fence_code,open)
- local f_c = makefence(right_fence_code,close)
- makelist(open,f_o,o_next,c_prev,f_c,middle)
- setnucleus(close)
- flush_node(close)
- if c_next then
- setprev(c_next,open)
+ local f_c = makefence(right_fence_code)
+ local o_prev, o_next = getboth(open)
+ local l_prev, l_next = getboth(last)
+ makelist(open,f_o,o_next,last,f_c,middle)
+ if l_next then
+ setprev(l_next,open)
end
- setnext(open,c_next)
+ setnext(open,l_next)
return open
end
-end
-
-local function convert_open(open,last,middle)
- local f_o = makefence(left_fence_code,open)
- local f_c = makefence(right_fence_code)
- local o_prev, o_next = getboth(open)
- local l_prev, l_next = getboth(last)
- makelist(open,f_o,o_next,last,f_c,middle)
- if l_next then
- setprev(l_next,open)
- end
- setnext(open,l_next)
- return open
-end
-local function convert_close(close,first,middle)
- local f_o = makefence(left_fence_code)
- local f_c = makefence(right_fence_code,close)
- local c_prev = getprev(close)
- makelist(close,f_o,first,c_prev,f_c,middle)
- return close
-end
+ local function convert_close(close,first,middle)
+ local f_o = makefence(left_fence_code)
+ local f_c = makefence(right_fence_code,close)
+ local c_prev = getprev(close)
+ makelist(close,f_o,first,c_prev,f_c,middle)
+ return close
+ end
-local stacks = setmetatableindex("table")
-
-local function processfences(pointer,n,parent)
- local current = pointer
- local last = pointer
- local start = pointer
- local done = false
- local initial = pointer
- local stack = nil
- local middle = nil -- todo: use properties
- while current do
- local id = getid(current)
- if id == math_noad then
- local a = getattr(current,a_autofence)
- if a and a > 0 then
- local stack = stacks[n]
- setattr(current,a_autofence,0)
- if a == 1 or (a == 4 and (not stack or #stack == 0)) then
- if trace_fences then
- report_fences("%2i: pushing open on stack",n)
- end
- insert(stack,current)
- elseif a == 2 or a == 4 then
- local open = remove(stack)
- if open then
+ local stacks = setmetatableindex("table")
+
+ local function processfences(pointer,n,parent)
+ local current = pointer
+ local last = pointer
+ local start = pointer
+ local done = false
+ local initial = pointer
+ local stack = nil
+ local middle = nil -- todo: use properties
+ while current do
+ local id = getid(current)
+ if id == math_noad then
+ local a = getattr(current,a_autofence)
+ if a and a > 0 then
+ local stack = stacks[n]
+ setattr(current,a_autofence,0)
+ if a == 1 or (a == 4 and (not stack or #stack == 0)) then
if trace_fences then
- report_fences("%2i: handling %s, stack depth %i",n,"both",#stack+1)
+ report_fences("%2i: pushing open on stack",n)
+ end
+ insert(stack,current)
+ elseif a == 2 or a == 4 then
+ local open = remove(stack)
+ if open then
+ if trace_fences then
+ report_fences("%2i: handling %s, stack depth %i",n,"both",#stack+1)
+ end
+ current = convert_both(open,current,middle)
+ elseif current == start then
+ -- skip
+ else
+ if trace_fences then
+ report_fences("%2i: handling %s, stack depth %i",n,"close",#stack+1)
+ end
+ current = convert_close(current,initial,middle)
+ if not parent then
+ initial = current
+ end
end
- current = convert_both(open,current,middle)
- elseif current == start then
- -- skip
- else
if trace_fences then
- report_fences("%2i: handling %s, stack depth %i",n,"close",#stack+1)
+ report_fences("%2i: popping close from stack",n)
end
- current = convert_close(current,initial,middle)
- if not parent then
- initial = current
+ elseif a == 3 then
+ if trace_fences then
+ report_fences("%2i: registering middle",n)
+ end
+ if middle then
+ middle[current] = last
+ else
+ middle = { [current] = last }
end
end
- if trace_fences then
- report_fences("%2i: popping close from stack",n)
- end
- elseif a == 3 then
- if trace_fences then
- report_fences("%2i: registering middle",n)
- end
- if middle then
- middle[current] = last
- else
- middle = { [current] = last }
- end
+ done = true
+ else
+ processstep(current,processfences,n+1,id)
end
- done = true
else
- processstep(current,processfences,n+1,id)
+ -- next at current level
+ processstep(current,processfences,n,id)
end
- else
- -- next at current level
- processstep(current,processfences,n,id)
+ last = current
+ current = getnext(current)
end
- last = current
- current = getnext(current)
- end
- if done then
- local stack = stacks[n]
- local s = #stack
- if s > 0 then
- if trace_fences then
- report_fences("%2i: handling %s stack levels",n,s)
- end
- for i=1,s do
- local open = remove(stack)
+ if done then
+ local stack = stacks[n]
+ local s = #stack
+ if s > 0 then
if trace_fences then
- report_fences("%2i: handling %s, stack depth %i",n,"open",#stack)
+ report_fences("%2i: handling %s stack levels",n,s)
+ end
+ for i=1,s do
+ local open = remove(stack)
+ if trace_fences then
+ report_fences("%2i: handling %s, stack depth %i",n,"open",#stack)
+ end
+ last = convert_open(open,last,middle)
end
- last = convert_open(open,last,middle)
end
end
end
-end
--- we can have a first changed node .. an option is to have a leading dummy node in math
--- lists like the par node as it can save a lot of mess
+ -- we can have a first changed node .. an option is to have a leading dummy node in math
+ -- lists like the par node as it can save a lot of mess
-local enabled = false
+ local enabled = false
-implement {
- name = "enableautofences",
- onlyonce = true,
- actions = function()
- enableaction("math","noads.handlers.autofences")
- enabled = true
- end
-}
+ implement {
+ name = "enableautofences",
+ onlyonce = true,
+ actions = function()
+ enableaction("math","noads.handlers.autofences")
+ enabled = true
+ end
+ }
-function handlers.autofences(head,style,penalties)
- if enabled then -- tex.modes.c_math_fences_auto
- -- inspect(nodes.totree(head))
- processfences(tonut(head),1)
- -- inspect(nodes.totree(head))
+ function handlers.autofences(head,style,penalties)
+ if enabled then -- tex.modes.c_math_fences_auto
+ -- inspect(nodes.totree(head))
+ processfences(tonut(head),1)
+ -- inspect(nodes.totree(head))
+ end
end
+
end
-- normalize scripts
-local unscript = { } noads.processors.unscript = unscript
-local superscripts = characters.superscripts
-local subscripts = characters.subscripts
-local fractions = characters.fractions
-local replaced = { }
-
-local function replace(pointer,what,n,parent)
- pointer = parent -- we're following the parent list (chars trigger this)
- local next = getnext(pointer)
- local start_super, stop_super, start_sub, stop_sub
- local mode = "unset"
- while next and getid(next) == math_noad do
- local nextnucleus = getnucleus(next)
- if nextnucleus and getid(nextnucleus) == math_char and not getsub(next) and not getsup(next) then
- local char = getchar(nextnucleus)
- local s = superscripts[char]
- if s then
- if not start_super then
- start_super = next
- mode = "super"
- elseif mode == "sub" then
- break
- end
- stop_super = next
- next = getnext(next)
- setchar(nextnucleus,s)
- replaced[char] = (replaced[char] or 0) + 1
- if trace_normalizing then
- report_normalizing("superscript %C becomes %C",char,s)
- end
- else
- local s = subscripts[char]
+do
+
+ local unscript = { } noads.processors.unscript = unscript
+ local superscripts = characters.superscripts
+ local subscripts = characters.subscripts
+ local fractions = characters.fractions
+ local replaced = { }
+
+ local function replace(pointer,what,n,parent)
+ pointer = parent -- we're following the parent list (chars trigger this)
+ local next = getnext(pointer)
+ local start_super, stop_super, start_sub, stop_sub
+ local mode = "unset"
+ while next and getid(next) == math_noad do
+ local nextnucleus = getnucleus(next)
+ if nextnucleus and getid(nextnucleus) == math_char and not getsub(next) and not getsup(next) then
+ local char = getchar(nextnucleus)
+ local s = superscripts[char]
if s then
- if not start_sub then
- start_sub = next
- mode = "sub"
- elseif mode == "super" then
+ if not start_super then
+ start_super = next
+ mode = "super"
+ elseif mode == "sub" then
break
end
- stop_sub = next
+ stop_super = next
next = getnext(next)
setchar(nextnucleus,s)
replaced[char] = (replaced[char] or 0) + 1
if trace_normalizing then
- report_normalizing("subscript %C becomes %C",char,s)
+ report_normalizing("superscript %C becomes %C",char,s)
end
else
- break
+ local s = subscripts[char]
+ if s then
+ if not start_sub then
+ start_sub = next
+ mode = "sub"
+ elseif mode == "super" then
+ break
+ end
+ stop_sub = next
+ next = getnext(next)
+ setchar(nextnucleus,s)
+ replaced[char] = (replaced[char] or 0) + 1
+ if trace_normalizing then
+ report_normalizing("subscript %C becomes %C",char,s)
+ end
+ else
+ break
+ end
end
+ else
+ break
end
- else
- break
end
- end
- if start_super then
- if start_super == stop_super then
- setsup(pointer,getnucleus(start_super))
- else
- local list = new_submlist() -- todo attr
- setlist(list,start_super)
- setsup(pointer,list)
- end
- if mode == "super" then
- setnext(pointer,getnext(stop_super))
- end
- setnext(stop_super)
- end
- if start_sub then
- if start_sub == stop_sub then
- setsub(pointer,getnucleus(start_sub))
- else
- local list = new_submlist() -- todo attr
- setlist(list,start_sub)
- setsub(pointer,list)
+ if start_super then
+ if start_super == stop_super then
+ setsup(pointer,getnucleus(start_super))
+ else
+ local list = new_submlist() -- todo attr
+ setlist(list,start_super)
+ setsup(pointer,list)
+ end
+ if mode == "super" then
+ setnext(pointer,getnext(stop_super))
+ end
+ setnext(stop_super)
end
- if mode == "sub" then
- setnext(pointer,getnext(stop_sub))
+ if start_sub then
+ if start_sub == stop_sub then
+ setsub(pointer,getnucleus(start_sub))
+ else
+ local list = new_submlist() -- todo attr
+ setlist(list,start_sub)
+ setsub(pointer,list)
+ end
+ if mode == "sub" then
+ setnext(pointer,getnext(stop_sub))
+ end
+ setnext(stop_sub)
end
- setnext(stop_sub)
+ -- we could return stop
end
- -- we could return stop
-end
-unscript[math_char] = replace -- not noads as we need to recurse
+ unscript[math_char] = replace -- not noads as we need to recurse
+
+ function handlers.unscript(head,style,penalties)
+ processnoads(head,unscript,"unscript")
+ -- processnoads(head,checkers,"checkers")
+ return true
+ end
-function handlers.unscript(head,style,penalties)
- processnoads(head,unscript,"unscript")
--- processnoads(head,checkers,"checkers")
- return true
end
-local function collected(list)
- if list and next(list) then
- local n, t = 0, { }
- for k, v in sortedhash(list) do
- n = n + v
- t[#t+1] = formatters["%C"](k)
+do
+
+ local function collected(list)
+ if list and next(list) then
+ local n, t = 0, { }
+ for k, v in sortedhash(list) do
+ n = n + v
+ t[#t+1] = formatters["%C"](k)
+ end
+ return formatters["% t (n=%s)"](t,n)
end
- return formatters["% t (n=%s)"](t,n)
end
-end
-statistics.register("math script replacements", function()
- return collected(replaced)
-end)
+ statistics.register("math script replacements", function()
+ return collected(replaced)
+ end)
-statistics.register("unknown math characters", function()
- return collected(unknowns)
-end)
+ statistics.register("unknown math characters", function()
+ return collected(unknowns)
+ end)
+
+end
-- math alternates: (in xits lgf: $ABC$ $\cal ABC$ $\mathalternate{cal}\cal ABC$)
-- math alternates: (in lucidaot lgf: $ABC \mathalternate{italic} ABC$)
@@ -1083,7 +1101,7 @@ do
alternates = alternates,
registered = registered,
presets = { },
-hashes = setmetatableindex("table")
+ hashes = setmetatableindex("table")
}
resources.mathalternates = mathalternates
end
@@ -1262,67 +1280,59 @@ end
-- some juggling that we want to avoid but we need to do something here (in fact, we could
-- better fix the width of the character
-local a_mathitalics = privateattribute("mathitalics")
+do
-local italics = { }
-local default_factor = 1/20
+ local a_mathitalics = privateattribute("mathitalics")
-local setcolor = nodes.tracers.colors.set
-local resetcolor = nodes.tracers.colors.reset
-local italic_kern = new_kern
+ local italics = { }
+ local default_factor = 1/20
-local c_positive_d = "trace:dg"
-local c_negative_d = "trace:dr"
+ local setcolor = nodes.tracers.colors.set
+ local resetcolor = nodes.tracers.colors.reset
+ local italic_kern = new_kern
-local function insert_kern(current,kern)
- local sub = new_submlist()
- local noad = new_noad()
- setlist(sub,kern)
- setnext(kern,noad)
- setnucleus(noad,current)
- return sub
-end
+ local c_positive_d = "trace:dg"
+ local c_negative_d = "trace:dr"
-registertracker("math.italics.visualize", function(v)
- if v then
- italic_kern = function(k)
- local n = new_kern(k)
- set_visual(n,"italic")
- return n
- end
- else
- italic_kern = new_kern
+ local function insert_kern(current,kern)
+ local sub = new_submlist()
+ local noad = new_noad()
+ setlist(sub,kern)
+ setnext(kern,noad)
+ setnucleus(noad,current)
+ return sub
end
-end)
-local function getcorrection(method,font,char) -- -- or character.italic -- (this one is for tex)
+ registertracker("math.italics.visualize", function(v)
+ if v then
+ italic_kern = function(k)
+ local n = new_kern(k)
+ set_visual(n,"italic")
+ return n
+ end
+ else
+ italic_kern = new_kern
+ end
+ end)
- local visual = chardata[char].visual
+ local function getcorrection(method,font,char) -- -- or character.italic -- (this one is for tex)
- if method == 1 then
- -- check on state
- local italics = fontitalics[font]
- if italics then
- local character = fontcharacters[font][char]
- if character then
- local correction = character.italic
- if correction and correction ~= 0 then
- return correction, visual
+ local visual = chardata[char].visual
+
+ if method == 1 then
+ -- check on state
+ local italics = fontitalics[font]
+ if italics then
+ local character = fontcharacters[font][char]
+ if character then
+ local correction = character.italic
+ if correction and correction ~= 0 then
+ return correction, visual
+ end
end
end
- end
- elseif method == 2 then
- -- no check
- local character = fontcharacters[font][char]
- if character then
- local correction = character.italic
- if correction and correction ~= 0 then
- return correction, visual
- end
- end
- elseif method == 3 then
- -- check on visual
- if visual == "it" or visual == "bi" then
+ elseif method == 2 then
+ -- no check
local character = fontcharacters[font][char]
if character then
local correction = character.italic
@@ -1330,109 +1340,121 @@ local function getcorrection(method,font,char) -- -- or character.italic -- (thi
return correction, visual
end
end
- end
- elseif method == 4 then
- -- combination of 1 and 3
- local italics = fontitalics[font]
- if italics and (visual == "it" or visual == "bi") then
- local character = fontcharacters[font][char]
- if character then
- local correction = character.italic
- if correction and correction ~= 0 then
- return correction, visual
+ elseif method == 3 then
+ -- check on visual
+ if visual == "it" or visual == "bi" then
+ local character = fontcharacters[font][char]
+ if character then
+ local correction = character.italic
+ if correction and correction ~= 0 then
+ return correction, visual
+ end
+ end
+ end
+ elseif method == 4 then
+ -- combination of 1 and 3
+ local italics = fontitalics[font]
+ if italics and (visual == "it" or visual == "bi") then
+ local character = fontcharacters[font][char]
+ if character then
+ local correction = character.italic
+ if correction and correction ~= 0 then
+ return correction, visual
+ end
end
end
end
- end
-end
+ end
-italics[math_char] = function(pointer,what,n,parent)
- local method = getattr(pointer,a_mathitalics)
- if method and method > 0 and method < 100 then
- local char = getchar(pointer)
- local font = getfont(pointer)
- local correction, visual = getcorrection(method,font,char)
- if correction and correction ~= 0 then
- local next_noad = getnext(parent)
- if not next_noad then
- if n == 1 then
- -- only at the outer level .. will become an option (always,endonly,none)
- if trace_italics then
- report_italics("method %a, flagging italic correction %p between %C and end math",method,correction,char)
- end
- if correction > 0 then
- correction = correction + 100
- else
- correction = correction - 100
+ italics[math_char] = function(pointer,what,n,parent)
+ local method = getattr(pointer,a_mathitalics)
+ if method and method > 0 and method < 100 then
+ local char = getchar(pointer)
+ local font = getfont(pointer)
+ local correction, visual = getcorrection(method,font,char)
+ if correction and correction ~= 0 then
+ local next_noad = getnext(parent)
+ if not next_noad then
+ if n == 1 then
+ -- only at the outer level .. will become an option (always,endonly,none)
+ if trace_italics then
+ report_italics("method %a, flagging italic correction %p between %C and end math",method,correction,char)
+ end
+ if correction > 0 then
+ correction = correction + 100
+ else
+ correction = correction - 100
+ end
+ setattr(pointer,a_mathitalics,correction)
+ setattr(parent,a_mathitalics,correction)
end
- setattr(pointer,a_mathitalics,correction)
- setattr(parent,a_mathitalics,correction)
end
end
end
end
-end
-function handlers.italics(head,style,penalties)
- processnoads(head,italics,"italics")
- return true
-end
+ function handlers.italics(head,style,penalties)
+ processnoads(head,italics,"italics")
+ return true
+ end
-local enable
+ local enable
-enable = function()
- enableaction("math", "noads.handlers.italics")
- if trace_italics then
- report_italics("enabling math italics")
+ enable = function()
+ enableaction("math", "noads.handlers.italics")
+ if trace_italics then
+ report_italics("enabling math italics")
+ end
+ -- we enable math (unless already enabled elsewhere)
+ typesetters.italics.enablemath()
+ enable = false
end
- -- we enable math (unless already enabled elsewhere)
- typesetters.italics.enablemath()
- enable = false
-end
--- best do this only on math mode (less overhead)
+ -- best do this only on math mode (less overhead)
-function mathematics.setitalics(name)
- if enable then
- enable()
+ function mathematics.setitalics(name)
+ if enable then
+ enable()
+ end
+ texsetattribute(a_mathitalics,name and name ~= v_reset and tonumber(name) or unsetvalue) -- maybe also v_none
end
- texsetattribute(a_mathitalics,name and name ~= v_reset and tonumber(name) or unsetvalue) -- maybe also v_none
-end
-function mathematics.getitalics(name)
- if enable then
- enable()
+ function mathematics.getitalics(name)
+ if enable then
+ enable()
+ end
+ context(name and name ~= v_reset and tonumber(name) or unsetvalue)
end
- context(name and name ~= v_reset and tonumber(name) or unsetvalue)
-end
-function mathematics.resetitalics()
- texsetattribute(a_mathitalics,unsetvalue)
-end
+ function mathematics.resetitalics()
+ texsetattribute(a_mathitalics,unsetvalue)
+ end
-implement {
- name = "initializemathitalics",
- actions = enable,
- onlyonce = true,
-}
+ implement {
+ name = "initializemathitalics",
+ actions = enable,
+ onlyonce = true,
+ }
-implement {
- name = "setmathitalics",
- actions = mathematics.setitalics,
- arguments = "string",
-}
+ implement {
+ name = "setmathitalics",
+ actions = mathematics.setitalics,
+ arguments = "string",
+ }
-implement {
- name = "getmathitalics",
- actions = mathematics.getitalics,
- arguments = "string",
-}
+ implement {
+ name = "getmathitalics",
+ actions = mathematics.getitalics,
+ arguments = "string",
+ }
-implement {
- name = "resetmathitalics",
- actions = mathematics.resetitalics
-}
+ implement {
+ name = "resetmathitalics",
+ actions = mathematics.resetitalics
+ }
+
+end
do
@@ -1512,290 +1534,301 @@ end
-- primes and such
-local collapse = { } processors.collapse = collapse
-
-local mathpairs = characters.mathpairs -- next will move to char-def
-
--- I should redo this: ligatures but only when attribute. Adn then the prime anchoring will
--- be the only one left. Then the mathpairs definitions might go from char-def to here.
-
--- 0x02B9 modifier
-
--- mathpairs[0x2032] = { [0x2032] = 0x2033, [0x2033] = 0x2034, [0x2034] = 0x2057 } -- (prime,prime) (prime,doubleprime) (prime,tripleprime)
--- mathpairs[0x2033] = { [0x2032] = 0x2034, [0x2033] = 0x2057 } -- (doubleprime,prime) (doubleprime,doubleprime)
--- mathpairs[0x2034] = { [0x2032] = 0x2057 } -- (tripleprime,prime)
+do
--- mathpairs[0x2035] = { [0x2035] = 0x2036, [0x2036] = 0x2037 } -- (reversedprime,reversedprime) (reversedprime,doublereversedprime)
--- mathpairs[0x2036] = { [0x2035] = 0x2037 } -- (doublereversedprime,reversedprime)
+ -- is validpair stil needed?
+
+ local collapse = { }
+ local mathlists = characters.mathlists
+ local validpair = {
+ [noad_ord] = true,
+ [noad_rel] = true,
+ [noad_bin] = true, -- new
+ [noad_open] = true, -- new
+ [noad_close] = true, -- new
+ [noad_punct] = true, -- new
+ [noad_opdisplaylimits] = true,
+ [noad_oplimits] = true,
+ [noad_opnolimits] = true,
+ }
--- mathpairs[0x222B] = { [0x222B] = 0x222C, [0x222C] = 0x222D } -- integrals
--- mathpairs[0x222C] = { [0x222B] = 0x222D }
+ local reported = setmetatableindex("table")
+
+ collapse[math_char] = function(pointer,what,n,parent)
+
+ if parent and mathlists[getchar(pointer)] then
+ local found, last, lucleus, lsup, lsub
+ local tree = mathlists
+ local current = parent
+ while current and validpair[getsubtype(current)] do
+ local nucleus = getnucleus(current) -- == pointer
+ local sub = getsub(current)
+ local sup = getsup(current)
+ local char = getchar(nucleus)
+ if char then
+ local match = tree[char]
+ if match then
+ local ligature = match.ligature
+ if ligature then
+ found = ligature
+ last = current
+ lucleus = nucleus
+ lsup = sup
+ lsub = sub
+ end
+ tree = match
+ if sub or sup then
+ break
+ else
+ current = getnext(current)
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if found and last and lucleus then
+ local id = getfont(lucleus)
+ local characters = fontcharacters[id]
+ local replace = characters and characters[found]
+ if not replace then
+ if not reported[id][found] then
+ reported[id][found] = true
+ report_collapsing("missing ligature %C",found)
+ end
+ elseif trace_collapsing then
+ report_collapsing("creating ligature %C",found)
+ end
+ setchar(pointer,found)
+ local l = getnext(last)
+ local c = getnext(parent)
+ if lsub then
+ setsub(parent,lsub)
+ setsub(last)
+ end
+ if lsup then
+ setsup(parent,lsup)
+ setsup(last)
+ end
+ while c ~= l do
+ local n = getnext(c)
+ flush_node(c)
+ c = n
+ end
+ setlink(parent,l)
+ end
+ end
+ end
--- mathpairs[0x007C] = { [0x007C] = 0x2016, [0x2016] = 0x2980 } -- bar+bar=double bar+double=triple
--- mathpairs[0x2016] = { [0x007C] = 0x2980, [0x02B9] = 0x2016 } -- double+bar=triple
+ function noads.handlers.collapse(head,style,penalties)
+ processnoads(head,collapse,"collapse")
+ return true
+ end
-local movesub = {
- -- primes
- [0x2032] = 0xFE932,
- [0x2033] = 0xFE933,
- [0x2034] = 0xFE934,
- [0x2057] = 0xFE957,
- -- reverse primes
- [0x2035] = 0xFE935,
- [0x2036] = 0xFE936,
- [0x2037] = 0xFE937,
-}
+end
-mathematics.virtualize(movesub)
-
--- local movesub = {
--- -- primes
--- [0x2032] = 0x2032,
--- [0x2033] = 0x2033,
--- [0x2034] = 0x2034,
--- [0x2057] = 0x2057,
--- -- reverse primes
--- [0x2035] = 0x2035,
--- [0x2036] = 0x2036,
--- [0x2037] = 0x2037,
--- }
+do
+ -- inner under over vcenter
+
+ local fixscripts = { }
+ local movesub = {
+ -- primes
+ [0x2032] = 0xFE932,
+ [0x2033] = 0xFE933,
+ [0x2034] = 0xFE934,
+ [0x2057] = 0xFE957,
+ -- reverse primes
+ [0x2035] = 0xFE935,
+ [0x2036] = 0xFE936,
+ [0x2037] = 0xFE937,
+ }
--- inner under over vcenter
-
-local validpair = {
- [noad_ord] = true,
- [noad_rel] = true,
- [noad_bin] = true, -- new
- [noad_open] = true, -- new
- [noad_close] = true, -- new
- [noad_punct] = true, -- new
- [noad_opdisplaylimits] = true,
- [noad_oplimits] = true,
- [noad_opnolimits] = true,
-}
+ mathematics.virtualize(movesub)
-local options_supported = tokens.defined("Unosuperscript")
+ local options_supported = tokens.defined("Unosuperscript")
-local function fixsupscript(parent,current,current_char,new_char)
- if new_char ~= current_char and new_char ~= true then
- setchar(current,new_char)
- if trace_collapsing then
- report_collapsing("fixing subscript, replacing supscript %U by %U",current_char,new_char)
+ local function fixsupscript(parent,current,current_char,new_char)
+ if new_char ~= current_char and new_char ~= true then
+ setchar(current,new_char)
+ if trace_collapsing then
+ report_collapsing("fixing subscript, replacing supscript %U by %U",current_char,new_char)
+ end
+ else
+ if trace_collapsing then
+ report_collapsing("fixing subscript, supscript %U",current_char)
+ end
end
- else
- if trace_collapsing then
- report_collapsing("fixing subscript, supscript %U",current_char)
+ if options_supported then
+ setfield(parent,"options",0x08+0x22)
end
end
- if options_supported then
- setfield(parent,"options",0x08+0x22)
- end
-end
-local function movesubscript(parent,current_nucleus,current_char,new_char)
- local prev = getprev(parent)
- if prev and getid(prev) == math_noad then
- local psup = getsup(prev)
- local psub = getsub(prev)
- if not psup and not psub then
- -- {f} {'}_n => f_n^'
- fixsupscript(prev,current_nucleus,current_char,new_char)
- local nucleus = getnucleus(parent)
- local sub = getsub(parent)
- setsup(prev,nucleus)
- setsub(prev,sub)
- local dummy = copy_node(nucleus)
- setchar(dummy,0)
- setnucleus(parent,dummy)
- setsub(parent)
- elseif not psup then
- -- {f} {'}_n => f_n^'
- fixsupscript(prev,current_nucleus,current_char,new_char)
- local nucleus = getnucleus(parent)
- setsup(prev,nucleus)
- local dummy = copy_node(nucleus)
- setchar(dummy,0)
- setnucleus(parent,dummy)
+ local function movesubscript(parent,current_nucleus,current_char,new_char)
+ local prev = getprev(parent)
+ if prev and getid(prev) == math_noad then
+ local psup = getsup(prev)
+ local psub = getsub(prev)
+ if not psup and not psub then
+ -- {f} {'}_n => f_n^'
+ fixsupscript(prev,current_nucleus,current_char,new_char)
+ local nucleus = getnucleus(parent)
+ local sub = getsub(parent)
+ setsup(prev,nucleus)
+ setsub(prev,sub)
+ local dummy = copy_node(nucleus)
+ setchar(dummy,0)
+ setnucleus(parent,dummy)
+ setsub(parent)
+ elseif not psup then
+ -- {f} {'}_n => f_n^'
+ fixsupscript(prev,current_nucleus,current_char,new_char)
+ local nucleus = getnucleus(parent)
+ setsup(prev,nucleus)
+ local dummy = copy_node(nucleus)
+ setchar(dummy,0)
+ setnucleus(parent,dummy)
+ end
end
end
-end
--- this is not that efficient as we are actually doing kind of ligatures
-
-local function collapsepair(pointer,what,n,parent,nested) -- todo: switch to turn in on and off
- if parent then
- if validpair[getsubtype(parent)] then
- local current_nucleus = getnucleus(parent)
- if getid(current_nucleus) == math_char then
- local current_char = getchar(current_nucleus)
- local p_sub = getsub(parent)
- local p_sup = getsup(parent)
- if not p_sub and not p_sup then
- local mathpair = mathpairs[current_char]
- if mathpair then
- local next_noad = getnext(parent)
- if next_noad and getid(next_noad) == math_noad and validpair[getsubtype(next_noad)] then
- local next_nucleus = getnucleus(next_noad)
- if getid(next_nucleus) == math_char then
- local next_char = getchar(next_nucleus)
- local newchar = mathpair[next_char]
- if newchar then
- local id = getfont(current_nucleus)
- local characters = fontcharacters[id]
- local replace = characters and characters[newchar]
- if replace then
- if trace_collapsing then
- report_collapsing("%U + %U => %U",current_char,next_char,newchar)
- end
- setchar(current_nucleus,newchar)
- local next_next_noad = getnext(next_noad)
- if next_next_noad then
- setlink(parent,next_next_noad)
- else
- setnext(parent)
- end
- local nsup = getsup(next_noad)
- local nsub = getsub(next_noad)
- if nsup then
- setsup(parent,nsup)
- setsup(next_noad)
- end
- if nsub then
- setsub(parent,nsub)
- setsub(next_noad)
- end
- flush_node(next_noad)
- collapsepair(pointer,what,n,parent,true)
- end
- end
- end
- end
- end
- elseif p_sup then
- if getid(p_sup) == math_char then
- local current_char = getchar(p_sup)
- local new_char = movesub[current_char]
- if new_char then
- fixsupscript(parent,p_sup,current_char,new_char)
- end
+ fixscripts[math_char] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off
+ if parent then
+ local nucleus = getnucleus(parent)
+ if getid(nucleus) == math_char then
+ local current_char = getchar(nucleus)
+ local sub = getsub(parent)
+ local sup = getsup(parent)
+ if sup and getid(sup) == math_char then
+ local oldchar = getchar(sup)
+ local newchar = movesub[oldchar]
+ if newchar then
+ fixsupscript(parent,sup,oldchar,newchar)
end
- return
end
- local current_char = getchar(current_nucleus)
- local new_char = movesub[current_char]
- if new_char then
- movesubscript(parent,current_nucleus,current_char,new_char)
+ if sub then
+ local oldchar = getchar(nucleus)
+ local newchar = movesub[oldchar]
+ if newchar then
+ movesubscript(parent,nucleus,oldchar,newchar)
+ end
end
end
end
end
-end
-collapse[math_char] = collapsepair
+ function noads.handlers.fixscripts(head,style,penalties)
+ processnoads(head,fixscripts,"fixscripts")
+ return true
+ end
-function noads.handlers.collapse(head,style,penalties)
- processnoads(head,collapse,"collapse")
- return true
end
-- variants
-local variants = { }
-
-local validvariants = { -- fast check on valid
- [0x2229] = 0xFE00, [0x222A] = 0xFE00,
- [0x2268] = 0xFE00, [0x2269] = 0xFE00,
- [0x2272] = 0xFE00, [0x2273] = 0xFE00,
- [0x228A] = 0xFE00, [0x228B] = 0xFE00,
- [0x2293] = 0xFE00, [0x2294] = 0xFE00,
- [0x2295] = 0xFE00,
- [0x2297] = 0xFE00,
- [0x229C] = 0xFE00,
- [0x22DA] = 0xFE00, [0x22DB] = 0xFE00,
- [0x2A3C] = 0xFE00, [0x2A3D] = 0xFE00,
- [0x2A9D] = 0xFE00, [0x2A9E] = 0xFE00,
- [0x2AAC] = 0xFE00, [0x2AAD] = 0xFE00,
- [0x2ACB] = 0xFE00, [0x2ACC] = 0xFE00,
-}
+do
+
+ local variants = { }
+ local validvariants = { -- fast check on valid
+ [0x2229] = 0xFE00, [0x222A] = 0xFE00,
+ [0x2268] = 0xFE00, [0x2269] = 0xFE00,
+ [0x2272] = 0xFE00, [0x2273] = 0xFE00,
+ [0x228A] = 0xFE00, [0x228B] = 0xFE00,
+ [0x2293] = 0xFE00, [0x2294] = 0xFE00,
+ [0x2295] = 0xFE00,
+ [0x2297] = 0xFE00,
+ [0x229C] = 0xFE00,
+ [0x22DA] = 0xFE00, [0x22DB] = 0xFE00,
+ [0x2A3C] = 0xFE00, [0x2A3D] = 0xFE00,
+ [0x2A9D] = 0xFE00, [0x2A9E] = 0xFE00,
+ [0x2AAC] = 0xFE00, [0x2AAD] = 0xFE00,
+ [0x2ACB] = 0xFE00, [0x2ACC] = 0xFE00,
+ }
-variants[math_char] = function(pointer,what,n,parent) -- also set export value
- local char = getchar(pointer)
- local selector = validvariants[char]
- if selector then
- local next = getnext(parent)
- if next and getid(next) == math_noad then
- local nucleus = getnucleus(next)
- if nucleus and getid(nucleus) == math_char and getchar(nucleus) == selector then
- local variant
- local tfmdata = fontdata[getfont(pointer)]
- local mathvariants = tfmdata.resources.variants -- and variantdata
- if mathvariants then
- mathvariants = mathvariants[selector]
+ variants[math_char] = function(pointer,what,n,parent) -- also set export value
+ local char = getchar(pointer)
+ local selector = validvariants[char]
+ if selector then
+ local next = getnext(parent)
+ if next and getid(next) == math_noad then
+ local nucleus = getnucleus(next)
+ if nucleus and getid(nucleus) == math_char and getchar(nucleus) == selector then
+ local variant
+ local tfmdata = fontdata[getfont(pointer)]
+ local mathvariants = tfmdata.resources.variants -- and variantdata
if mathvariants then
- variant = mathvariants[char]
- end
- end
- if variant then
- setchar(pointer,variant)
- setattr(pointer,a_exportstatus,char) -- we don't export the variant as it's visual markup
- if trace_variants then
- report_variants("variant (%U,%U) replaced by %U",char,selector,variant)
+ mathvariants = mathvariants[selector]
+ if mathvariants then
+ variant = mathvariants[char]
+ end
end
- else
- if trace_variants then
- report_variants("no variant (%U,%U)",char,selector)
+ if variant then
+ setchar(pointer,variant)
+ setattr(pointer,a_exportstatus,char) -- we don't export the variant as it's visual markup
+ if trace_variants then
+ report_variants("variant (%U,%U) replaced by %U",char,selector,variant)
+ end
+ else
+ if trace_variants then
+ report_variants("no variant (%U,%U)",char,selector)
+ end
end
+ setprev(next,pointer)
+ setnext(parent,getnext(next))
+ flush_node(next)
end
- setprev(next,pointer)
- setnext(parent,getnext(next))
- flush_node(next)
end
end
end
-end
-function handlers.variants(head,style,penalties)
- processnoads(head,variants,"unicode variant")
- return true
+ function handlers.variants(head,style,penalties)
+ processnoads(head,variants,"unicode variant")
+ return true
+ end
+
end
-- for manuals
-local classes = { }
-
-local colors = {
- [noad_rel] = "trace:dr",
- [noad_ord] = "trace:db",
- [noad_bin] = "trace:dg",
- [noad_open] = "trace:dm",
- [noad_close] = "trace:dm",
- [noad_punct] = "trace:dc",
- -- [noad_opdisplaylimits] = "",
- -- [noad_oplimits] = "",
- -- [noad_opnolimits] = "",
- -- [noad_inner = "",
- -- [noad_under = "",
- -- [noad_over = "",
- -- [noad_vcenter = "",
-}
+do
-classes[math_char] = function(pointer,what,n,parent)
- local color = colors[getsubtype(parent)]
- if color then
- setcolor(pointer,color)
- else
- resetcolor(pointer)
+ local classes = { }
+ local colors = {
+ [noad_rel] = "trace:dr",
+ [noad_ord] = "trace:db",
+ [noad_bin] = "trace:dg",
+ [noad_open] = "trace:dm",
+ [noad_close] = "trace:dm",
+ [noad_punct] = "trace:dc",
+ -- [noad_opdisplaylimits] = "",
+ -- [noad_oplimits] = "",
+ -- [noad_opnolimits] = "",
+ -- [noad_inner = "",
+ -- [noad_under = "",
+ -- [noad_over = "",
+ -- [noad_vcenter = "",
+ }
+
+ classes[math_char] = function(pointer,what,n,parent)
+ local color = colors[getsubtype(parent)]
+ if color then
+ setcolor(pointer,color)
+ else
+ resetcolor(pointer)
+ end
end
-end
-function handlers.classes(head,style,penalties)
- processnoads(head,classes,"classes")
- return true
-end
+ function handlers.classes(head,style,penalties)
+ processnoads(head,classes,"classes")
+ return true
+ end
-registertracker("math.classes",function(v)
- setaction("math","noads.handlers.classes",v)
-end)
+ registertracker("math.classes",function(v)
+ setaction("math","noads.handlers.classes",v)
+ end)
+
+end
-- experimental
@@ -1813,9 +1846,7 @@ do
local categories = { }
local numbers = { }
local a_mathdomain = privateattribute("mathdomain")
-
mathematics.domains = categories
-
local permitted = {
ordinary = noad_ord,
binary = noad_bin,
@@ -1968,17 +1999,21 @@ end)
-- also for me
-local applyvisuals = nuts.applyvisuals
-local visual = false
+do
-function handlers.makeup(head)
- applyvisuals(tonut(head),visual)
-end
+ local applyvisuals = nuts.applyvisuals
+ local visual = false
-registertracker("math.makeup",function(v)
- visual = v
- setaction("math","noads.handlers.makeup",v)
-end)
+ function handlers.makeup(head)
+ applyvisuals(tonut(head),visual)
+ end
+
+ registertracker("math.makeup",function(v)
+ visual = v
+ setaction("math","noads.handlers.makeup",v)
+ end)
+
+end
-- the normal builder