summaryrefslogtreecommitdiff
path: root/tex/context/base/math-noa.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/math-noa.lua')
-rw-r--r--tex/context/base/math-noa.lua245
1 files changed, 120 insertions, 125 deletions
diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua
index 5ac6d125d..8716ac726 100644
--- a/tex/context/base/math-noa.lua
+++ b/tex/context/base/math-noa.lua
@@ -61,15 +61,18 @@ local free_node = node.free
local new_node = node.new -- todo: pool: math_noad math_sub
local new_kern = nodes.pool.kern
+local new_rule = nodes.pool.rule
+local concat_nodes = nodes.concat
-local topoints = number.topoints
+local topoints = number.points
local fonthashes = fonts.hashes
local fontdata = fonthashes.identifiers
local fontcharacters = fonthashes.characters
local fontproperties = fonthashes.properties
local fontitalics = fonthashes.italics
-local fontquads = fonthashes.quads
+local fontemwidths = fonthashes.emwidths
+local fontexheights = fonthashes.exheights
local variables = interfaces.variables
local texattribute = tex.attribute
@@ -437,10 +440,20 @@ local mathpairs = characters.mathpairs
mathpairs[0x2032] = { [0x2032] = 0x2033, [0x2033] = 0x2034 } -- (prime,prime) (prime,doubleprime)
mathpairs[0x2033] = { [0x2032] = 0x2034 } -- (doubleprime,prime)
+mathpairs[0x222B] = { [0x222B] = 0x222C, [0x222C] = 0x222D }
+mathpairs[0x222C] = { [0x222B] = 0x222D }
+
+local validpair = {
+ [noad_rel] = true,
+ [noad_ord] = true,
+ [noad_opdisplaylimits] = true,
+ [noad_oplimits] = true,
+ [noad_opnolimits] = true,
+}
+
local function collapsepair(pointer,what,n,parent) -- todo: switch to turn in on and off
if parent then
- local subtype = parent.subtype
- if subtype == noad_rel or subtype == noad_ord then -- ord is new
+ if validpair[parent.subtype] then
local current_nucleus = parent.nucleus
if not parent.sub and not parent.sup and current_nucleus.id == math_char then
local current_char = current_nucleus.char
@@ -448,8 +461,7 @@ local function collapsepair(pointer,what,n,parent) -- todo: switch to turn in on
if mathpair then
local next_noad = parent.next
if next_noad and next_noad.id == math_noad then
- local next_subtype = next_noad.subtype
- if next_subtype == noad_rel or next_subtype == noad_ord then -- ord is new
+ if validpair[next_noad.subtype] then
local next_nucleus = next_noad.nucleus
if next_nucleus.id == math_char then
local next_char = next_nucleus.char
@@ -767,50 +779,67 @@ local a_mathitalics = attributes.private("mathitalics")
local italics = { }
local default_factor = 1/20
-local function getcorrection(method,font,char)
+local function getcorrection(method,font,char) -- -- or character.italic -- (this one is for tex)
- local correction
+ local correction, fromvisual
if method == 1 then
-- only font data triggered by fontitalics
local italics = fontitalics[font]
if italics then
local character = fontcharacters[font][char]
- correction = character and character.italic_correction -- or character.italic (this one is for tex)
+ if character then
+ correction = character.italic_correction
+ if correction and correction ~= 0 then
+ return correction, false
+ end
+ end
end
elseif method == 2 then
-- only font data triggered by fontdata
local character = fontcharacters[font][char]
- correction = character and character.italic_correction -- or character.italic (this one is for tex)
+ if character then
+ correction = character.italic_correction
+ if correction and correction ~= 0 then
+ return correction, false
+ end
+ end
elseif method == 3 then
-- only quad based by selective
local visual = chardata[char].visual
if not visual then
-- skip
elseif visual == "it" or visual == "bi" then
- correction = fontproperties[font].mathitalic_defaultvalue or default_factor*fontquads[font]
+ correction = fontproperties[font].mathitalic_defaultvalue or default_factor*fontemwidths[font]
+ if correction and correction ~= 0 then
+ return correction, true
+ end
end
elseif method == 4 then
-- combination of 1 and 3
local italics = fontitalics[font]
if italics then
local character = fontcharacters[font][char]
- correction = character and character.italic_correction -- or character.italic (this one is for tex)
+ if character then
+ correction = character.italic_correction
+ if correction and correction ~= 0 then
+ return correction, false
+ end
+ end
end
if not correction then
local visual = chardata[char].visual
if not visual then
-- skip
elseif visual == "it" or visual == "bi" then
- correction = fontproperties[font].mathitalic_defaultvalue or default_factor*fontquads[font]
+ correction = fontproperties[font].mathitalic_defaultvalue or default_factor*fontemwidths[font]
+ if correction and correction ~= 0 then
+ return correction, true
+ end
end
end
end
- if correction and correction ~= 0 then
- return correction
- end
-
end
local function insert_kern(current,kern)
@@ -822,20 +851,37 @@ local function insert_kern(current,kern)
return sub
end
--- noad_opdisplaylimits noad_oplimits noad_opnolimits
+local setcolor = nodes.tracers.colors.set
+local italic_kern = new_kern
+local c_positive_d = "trace:db"
+local c_negative_d = "trace:dr"
+
+trackers.register("math.italics", function(v)
+ if v then
+ italic_kern = function(k,font)
+ local ex = 1.5 * fontexheights[font]
+ if k > 0 then
+ return setcolor(new_rule(k,ex,ex),c_positive_d)
+ else
+ return concat_nodes {
+ old_kern(k),
+ setcolor(new_rule(-k,ex,ex),c_negative_d),
+ old_kern(k),
+ }
+ end
+ end
+ else
+ italic_kern = new_kern
+ end
+end)
italics[math_char] = function(pointer,what,n,parent)
local method = has_attribute(pointer,a_mathitalics)
if method and method > 0 then
local char = pointer.char
local font = font_of_family(pointer.fam) -- todo: table
- local correction = getcorrection(method,font,char)
-
- -- maybe also correction when next == nil
- -- when sub/sup -> already done
-
+ local correction, visual = getcorrection(method,font,char)
if correction then
- -- maybe only +/- when subtype == opdisplaylimits
local pid = parent.id
local sub, sup
if pid == math_noad then
@@ -843,30 +889,41 @@ italics[math_char] = function(pointer,what,n,parent)
sub = parent.sub
end
if sup or sub then
- if sup then
- parent.sup = insert_kern(sup,new_kern(correction))
- if trace_italics then
- report_italics("method %s: adding %s italic correction before superscript after %s (0x%05X)",
- method,number.points(correction),utfchar(char),char)
+ local subtype = parent.subtype
+ if subtype == noad_oplimits then
+ if sup then
+ parent.sup = insert_kern(sup,italic_kern(correction,font))
+ if trace_italics then
+ report_italics("method %s: adding %s italic correction for upper limit of %s (0x%05X)",
+ method,topoints(correction),utfchar(char),char)
+ end
end
- end
- if sub then
-local correction = - correction
- parent.sub = insert_kern(sub,new_kern(correction))
- if trace_italics then
- report_italics("method %s: adding %s italic correction before subscript after %s (0x%05X)",
- method,number.points(correction),utfchar(char),char)
+ if sub then
+ local correction = - correction
+ parent.sub = insert_kern(sub,italic_kern(correction,font))
+ if trace_italics then
+ report_italics("method %s: adding %s italic correction for lower limit of %s (0x%05X)",
+ method,topoints(correction),utfchar(char),char)
+ end
+ end
+ else
+ if sup then
+ parent.sup = insert_kern(sup,italic_kern(correction,font))
+ if trace_italics then
+ report_italics("method %s: adding %s italic correction before superscript after %s (0x%05X)",
+ method,topoints(correction),utfchar(char),char)
+ end
end
end
else
local next_noad = parent.next
if not next_noad then
- if true then -- this might become an option
+ if n== 1 then -- only at the outer level .. will become an option (always,endonly,none)
if trace_italics then
report_italics("method %s: adding %s italic correction between %s (0x%05X) and end math",
- method,number.points(correction),utfchar(char),char)
+ method,topoints(correction),utfchar(char),char)
end
- insert_node_after(parent,parent,new_kern(correction))
+ insert_node_after(parent,parent,italic_kern(correction,font))
end
elseif next_noad.id == math_noad then
local next_subtype = next_noad.subtype
@@ -874,12 +931,31 @@ local correction = - correction
local next_nucleus = next_noad.nucleus
if next_nucleus.id == math_char then
local next_char = next_nucleus.char
- if not chardata[next_char].italic then -- or category
- if trace_italics then
- report_italics("method %s: adding %s italic correction between %s (0x%05X) and %s (0x%05X)",
- method,number.points(correction),utfchar(char),char,utfchar(next_char),next_char)
+ local next_data = chardata[next_char]
+ local visual = next_data.visual
+ if visual == "it" or visual == "bi" then
+ -- if trace_italics then
+ -- report_italics("method %s: skipping %s italic correction between italic %s (0x%05X) and italic %s (0x%05X)",
+ -- method,topoints(correction),utfchar(char),char,utfchar(next_char),next_char)
+ -- end
+ else
+ local category = next_data.category
+ if category == "nd" or category == "ll" or category == "lu" then
+ if trace_italics then
+ report_italics("method %s: adding %s italic correction between italic %s (0x%05X) and non italic %s (0x%05X)",
+ method,topoints(correction),utfchar(char),char,utfchar(next_char),next_char)
+ end
+ insert_node_after(parent,parent,italic_kern(correction,font))
+ -- elseif next_data.height > (fontexheights[font]/2) then
+ -- if trace_italics then
+ -- report_italics("method %s: adding %s italic correction between %s (0x%05X) and ascending %s (0x%05X)",
+ -- method,topoints(correction),utfchar(char),char,utfchar(next_char),next_char)
+ -- end
+ -- insert_node_after(parent,parent,italic_kern(correction,font))
+ -- elseif trace_italics then
+ -- -- report_italics("method %s: skipping %s italic correction between %s (0x%05X) and %s (0x%05X)",
+ -- -- method,topoints(correction),utfchar(char),char,utfchar(next_char),next_char)
end
- insert_node_after(parent,parent,new_kern(correction))
end
end
end
@@ -889,28 +965,7 @@ local correction = - correction
end
end
--- italics[math_noad] = function(pointer,what,n,parent)
--- local nucleus = pointer.nucleus
--- if nucleus.id == math_char then
--- local method = has_attribute(pointer,a_mathitalics)
--- if method and method > 0 then
--- local char = nucleus.char
--- local font = font_of_family(nucleus.fam) -- todo: table
--- local correction = getcorrection(method,font,char)
--- if correction then
--- if trace_italics then
--- report_italics("method %s: adding %s italic correction between %s (0x%05X) and script",
--- method,number.points(correction),utfchar(char),char)
--- end
--- insert_node_after(nucleus,nucleus,new_kern(correction))
--- end
--- end
--- end
--- end
-
function handlers.italics(head,style,penalties)
--- nodes.showsimplelist(head)
--- inspect(nodes.totable(head))
processnoads(head,italics,"italics")
return true
end
@@ -925,66 +980,6 @@ enable = function()
enable = false
end
--- -- -- -- -- -- -- --
--- -- -- -- -- -- -- --
-
--- -- nice but not okay with multiple scripts (we need more clever hlist-shift checking then
---
--- local function processitalics(head,previous,previousmethod)
--- local current = head
--- while current do
--- local id = current.id
--- if id == glyph_code then
--- local method = has_attribute(current,a_mathitalics)
--- if method and method > 0 then -- keep method of previous
--- if previous then
--- local previousfont = previous.font
--- local previouschar = previous.char
--- local currentchar = current.char
--- local correction = getcorrection(previousmethod,previousfont,previouschar)
--- if correction then
--- if trace_italics then
--- report_italics("correction %s between U+%05X and U+%05X using method",topoints(correction),previouschar,currentchar,previousmethod)
--- end
--- insert_node_after(previous,previous,new_kern(correction))
--- else
--- if trace_italics then
--- report_italics("no correction between U+%05X and U+%05X",previouschar,currentchar)
--- end
--- end
--- end
--- previous, previousmethod = current, method
--- end
--- elseif id == hlist_code then
--- previous, previousmethod = processitalics(current.list,previous,previousmethod)
--- elseif id == vlist_code then
--- previous, previousmethod = processitalics(current.list,previous,previousmethod)
--- else
--- previous, previousmethod = nil
--- end
--- current = current.next
--- end
--- return previous, previousmethod
--- end
---
--- function handlers.italics(head,style,penalties)
--- processitalics(head)
--- return true
--- end
---
--- local enable
---
--- enable = function()
--- tasks.enableaction("math", "noads.handlers.italics")
--- if trace_italics then
--- report_italics("enabling math italics")
--- end
--- enable = false
--- end
-
--- -- -- -- -- -- -- --
--- -- -- -- -- -- -- --
-
-- best do this only on math mode (less overhead)
function mathematics.setitalics(n)