diff options
Diffstat (limited to 'tex/context/base/math-act.lua')
-rw-r--r-- | tex/context/base/math-act.lua | 808 |
1 files changed, 404 insertions, 404 deletions
diff --git a/tex/context/base/math-act.lua b/tex/context/base/math-act.lua index 875e200c1..4f9b3b7e8 100644 --- a/tex/context/base/math-act.lua +++ b/tex/context/base/math-act.lua @@ -1,404 +1,404 @@ -if not modules then modules = { } end modules ['math-act'] = {
- 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"
-}
-
--- Here we tweak some font properties (if needed).
-
-local type, next = type, next
-local fastcopy = table.fastcopy
-
-local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
-local report_math = logs.reporter("mathematics","initializing")
-
-local context = context
-local commands = commands
-local mathematics = mathematics
-local texdimen = tex.dimen
-local abs = math.abs
-
-local sequencers = utilities.sequencers
-local appendgroup = sequencers.appendgroup
-local appendaction = sequencers.appendaction
-
-local mathfontparameteractions = sequencers.new {
- name = "mathparameters",
- arguments = "target,original",
-}
-
-appendgroup("mathparameters","before") -- user
-appendgroup("mathparameters","system") -- private
-appendgroup("mathparameters","after" ) -- user
-
-function fonts.constructors.assignmathparameters(original,target)
- local runner = mathfontparameteractions.runner
- if runner then
- runner(original,target)
- end
-end
-
-function mathematics.initializeparameters(target,original)
- local mathparameters = original.mathparameters
- if mathparameters and next(mathparameters) then
- target.mathparameters = mathematics.dimensions(mathparameters)
- end
-end
-
-sequencers.appendaction("mathparameters","system","mathematics.initializeparameters")
-
-local how = {
- -- RadicalKernBeforeDegree = "horizontal",
- -- RadicalKernAfterDegree = "horizontal",
- ScriptPercentScaleDown = "unscaled",
- ScriptScriptPercentScaleDown = "unscaled",
- RadicalDegreeBottomRaisePercent = "unscaled"
-}
-
-function mathematics.scaleparameters(target,original)
- if not target.properties.math_is_scaled then
- local mathparameters = target.mathparameters
- if mathparameters and next(mathparameters) then
- local parameters = target.parameters
- local factor = parameters.factor
- local hfactor = parameters.hfactor
- local vfactor = parameters.vfactor
- for name, value in next, mathparameters do
- local h = how[name]
- if h == "unscaled" then
- -- kept
- elseif h == "horizontal" then
- value = value * hfactor
- elseif h == "vertical"then
- value = value * vfactor
- else
- value = value * factor
- end
- mathparameters[name] = value
- end
- end
- target.properties.math_is_scaled = true
- end
-end
-
-sequencers.appendaction("mathparameters","system","mathematics.scaleparameters")
-
-function mathematics.checkaccentbaseheight(target,original)
- local mathparameters = target.mathparameters
- if mathparameters and mathparameters.AccentBaseHeight == 0 then
- mathparameters.AccentBaseHeight = target.parameters.x_height -- needs checking
- end
-end
-
-sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
-
-function mathematics.checkprivateparameters(target,original)
- local mathparameters = target.mathparameters
- if mathparameters then
- local parameters = target.parameters
- if parameters then
- if not mathparameters.FractionDelimiterSize then
- mathparameters.FractionDelimiterSize = 1.01 * parameters.size
- end
- if not mathparameters.FractionDelimiterDisplayStyleSize then
- mathparameters.FractionDelimiterDisplayStyleSize = 2.40 * parameters.size
- end
- elseif target.properties then
- report_math("no parameters in font %a",target.properties.fullname or "?")
- else
- report_math("no parameters and properties in font")
- end
- end
-end
-
-sequencers.appendaction("mathparameters","system","mathematics.checkprivateparameters")
-
-function mathematics.overloadparameters(target,original)
- local mathparameters = target.mathparameters
- if mathparameters and next(mathparameters) then
- local goodies = target.goodies
- if goodies then
- for i=1,#goodies do
- local goodie = goodies[i]
- local mathematics = goodie.mathematics
- local parameters = mathematics and mathematics.parameters
- if parameters then
- if trace_defining then
- report_math("overloading math parameters in %a @ %p",target.properties.fullname,target.parameters.size)
- end
- for name, value in next, parameters do
- local tvalue = type(value)
- if tvalue == "string" then
- report_math("comment for math parameter %a: %s",name,value)
- else
- local oldvalue = mathparameters[name]
- local newvalue = oldvalue
- if oldvalue then
- if tvalue == "number" then
- newvalue = value
- elseif tvalue == "function" then
- newvalue = value(oldvalue,target,original)
- elseif not tvalue then
- newvalue = nil
- end
- if trace_defining and oldvalue ~= newvalue then
- report_math("overloading math parameter %a: %S => %S",name,oldvalue,newvalue)
- end
- else
- report_math("invalid math parameter %a",name)
- end
- mathparameters[name] = newvalue
- end
- end
- end
- end
- end
- end
-end
-
-sequencers.appendaction("mathparameters","system","mathematics.overloadparameters")
-
-local function applytweaks(when,target,original)
- local goodies = original.goodies
- if goodies then
- for i=1,#goodies do
- local goodie = goodies[i]
- local mathematics = goodie.mathematics
- local tweaks = mathematics and mathematics.tweaks
- if tweaks then
- tweaks = tweaks[when]
- if tweaks then
- if trace_defining then
- report_math("tweaking math of %a @ %p (%s)",target.properties.fullname,target.parameters.size,when)
- end
- for i=1,#tweaks do
- local tweak= tweaks[i]
- local tvalue = type(tweak)
- if tvalue == "function" then
- tweak(target,original)
- end
- end
- end
- end
- end
- end
-end
-
-function mathematics.tweakbeforecopyingfont(target,original)
- local mathparameters = target.mathparameters -- why not hasmath
- if mathparameters then
- applytweaks("beforecopying",target,original)
- end
-end
-
-function mathematics.tweakaftercopyingfont(target,original)
- local mathparameters = target.mathparameters -- why not hasmath
- if mathparameters then
- applytweaks("aftercopying",target,original)
- end
-end
-
-sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont")
-sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont")
-
-function mathematics.overloaddimensions(target,original,set)
- local goodies = target.goodies
- if goodies then
- for i=1,#goodies do
- local goodie = goodies[i]
- local mathematics = goodie.mathematics
- local dimensions = mathematics and mathematics.dimensions
- if dimensions then
- if trace_defining then
- report_math("overloading dimensions in %a @ %p",target.properties.fullname,target.parameters.size)
- end
- local characters = target.characters
- local parameters = target.parameters
- local factor = parameters.factor
- local hfactor = parameters.hfactor
- local vfactor = parameters.vfactor
- local addprivate = fonts.helpers.addprivate
- local function overload(dimensions)
- for unicode, data in next, dimensions do
- local character = characters[unicode]
- if character then
- --
- local width = data.width
- local height = data.height
- local depth = data.depth
- if trace_defining and (width or height or depth) then
- report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth)
- end
- if width then character.width = width * hfactor end
- if height then character.height = height * vfactor end
- if depth then character.depth = depth * vfactor end
- --
- local xoffset = data.xoffset
- local yoffset = data.yoffset
- if xoffset then
- xoffset = { "right", xoffset * hfactor }
- end
- if yoffset then
- yoffset = { "down", -yoffset * vfactor }
- end
- if xoffset or yoffset then
- local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) }
- if xoffset and yoffset then
- character.commands = { xoffset, yoffset, slot }
- elseif xoffset then
- character.commands = { xoffset, slot }
- else
- character.commands = { yoffset, slot }
- end
- character.index = nil
- end
- elseif trace_defining then
- report_math("no overloading dimensions of %C, not in font",unicode)
- end
- end
- end
- if set == nil then
- set = { "default" }
- end
- if set == "all" or set == true then
- for name, set in next, dimensions do
- overload(set)
- end
- else
- if type(set) == "string" then
- set = utilities.parsers.settings_to_array(set)
- end
- if type(set) == "table" then
- for i=1,#set do
- local d = dimensions[set[i]]
- if d then
- overload(d)
- end
- end
- end
- end
- end
- end
- end
-end
-
-sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
-
--- a couple of predefined tewaks:
-
-local tweaks = { }
-mathematics.tweaks = tweaks
-
-function tweaks.fixbadprime(target,original)
- target.characters[0xFE325] = target.characters[0x2032]
-end
-
--- helpers
-
-local setmetatableindex = table.setmetatableindex
-local family_font = node.family_font
-
-local fontcharacters = fonts.hashes.characters
-local extensibles = utilities.storage.allocate()
-fonts.hashes.extensibles = extensibles
-
-local chardata = characters.data
-local extensibles = mathematics.extensibles
-
--- we use numbers at the tex end (otherwise we could stick to chars)
-
-local e_left = extensibles.left
-local e_right = extensibles.right
-local e_horizontal = extensibles.horizontal
-local e_vertical = extensibles.vertical
-local e_mixed = extensibles.mixed
-local e_unknown = extensibles.unknown
-
-local unknown = { e_unknown, false, false }
-
-local function extensiblecode(font,unicode)
- local characters = fontcharacters[font]
- local character = characters[unicode]
- if not character then
- return unknown
- end
- local code = unicode
- local next = character.next
- while next do
- code = next
- character = characters[next]
- next = character.next
- end
- local char = chardata[unicode]
- local mathextensible = char and char.mathextensible
- if character.horiz_variants then
- if character.vert_variants then
- return { e_mixed, code, character }
- else
- local e = mathextensible and extensibles[mathextensible]
- return e and { e, code, character } or unknown
- end
- elseif character.vert_variants then
- local e = mathextensible and extensibles[mathextensible]
- return e and { e, code, character } or unknown
- else
- return unknown
- end
-end
-
-setmetatableindex(extensibles,function(extensibles,font)
- local codes = { }
- setmetatableindex(codes, function(codes,unicode)
- local status = extensiblecode(font,unicode)
- codes[unicode] = status
- return status
- end)
- extensibles[font] = codes
- return codes
-end)
-
-function mathematics.extensiblecode(family,unicode)
- return extensibles[family_font(family or 0)][unicode][1]
-end
-
-function commands.extensiblecode(family,unicode)
- context(extensibles[family_font(family or 0)][unicode][1])
-end
-
--- left : [head] ...
--- right : ... [head]
--- horizontal : [head] ... [head]
---
--- abs(right["start"] - right["end"]) | right.advance | characters[right.glyph].width
-
-function commands.horizontalcode(family,unicode)
- local font = family_font(family or 0)
- local data = extensibles[font][unicode]
- local kind = data[1]
- if kind == e_left then
- local charlist = data[3].horiz_variants
- local characters = fontcharacters[font]
- local left = charlist[1]
- texdimen.scratchleftoffset = abs((left["start"] or 0) - (left["end"] or 0))
- texdimen.scratchrightoffset = 0
- elseif kind == e_right then
- local charlist = data[3].horiz_variants
- local characters = fontcharacters[font]
- local right = charlist[#charlist]
- texdimen.scratchleftoffset = 0
- texdimen.scratchrightoffset = abs((right["start"] or 0) - (right["end"] or 0))
- elseif kind == e_horizontal then
- local charlist = data[3].horiz_variants
- local characters = fontcharacters[font]
- local left = charlist[1]
- local right = charlist[#charlist]
- texdimen.scratchleftoffset = abs((left["start"] or 0) - (left["end"] or 0))
- texdimen.scratchrightoffset = abs((right["start"] or 0) - (right["end"] or 0))
- else
- texdimen.scratchleftoffset = 0
- texdimen.scratchrightoffset = 0
- end
- context(kind)
-end
+if not modules then modules = { } end modules ['math-act'] = { + 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" +} + +-- Here we tweak some font properties (if needed). + +local type, next = type, next +local fastcopy = table.fastcopy + +local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) +local report_math = logs.reporter("mathematics","initializing") + +local context = context +local commands = commands +local mathematics = mathematics +local texdimen = tex.dimen +local abs = math.abs + +local sequencers = utilities.sequencers +local appendgroup = sequencers.appendgroup +local appendaction = sequencers.appendaction + +local mathfontparameteractions = sequencers.new { + name = "mathparameters", + arguments = "target,original", +} + +appendgroup("mathparameters","before") -- user +appendgroup("mathparameters","system") -- private +appendgroup("mathparameters","after" ) -- user + +function fonts.constructors.assignmathparameters(original,target) + local runner = mathfontparameteractions.runner + if runner then + runner(original,target) + end +end + +function mathematics.initializeparameters(target,original) + local mathparameters = original.mathparameters + if mathparameters and next(mathparameters) then + target.mathparameters = mathematics.dimensions(mathparameters) + end +end + +sequencers.appendaction("mathparameters","system","mathematics.initializeparameters") + +local how = { + -- RadicalKernBeforeDegree = "horizontal", + -- RadicalKernAfterDegree = "horizontal", + ScriptPercentScaleDown = "unscaled", + ScriptScriptPercentScaleDown = "unscaled", + RadicalDegreeBottomRaisePercent = "unscaled" +} + +function mathematics.scaleparameters(target,original) + if not target.properties.math_is_scaled then + local mathparameters = target.mathparameters + if mathparameters and next(mathparameters) then + local parameters = target.parameters + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + for name, value in next, mathparameters do + local h = how[name] + if h == "unscaled" then + -- kept + elseif h == "horizontal" then + value = value * hfactor + elseif h == "vertical"then + value = value * vfactor + else + value = value * factor + end + mathparameters[name] = value + end + end + target.properties.math_is_scaled = true + end +end + +sequencers.appendaction("mathparameters","system","mathematics.scaleparameters") + +function mathematics.checkaccentbaseheight(target,original) + local mathparameters = target.mathparameters + if mathparameters and mathparameters.AccentBaseHeight == 0 then + mathparameters.AccentBaseHeight = target.parameters.x_height -- needs checking + end +end + +sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead + +function mathematics.checkprivateparameters(target,original) + local mathparameters = target.mathparameters + if mathparameters then + local parameters = target.parameters + if parameters then + if not mathparameters.FractionDelimiterSize then + mathparameters.FractionDelimiterSize = 1.01 * parameters.size + end + if not mathparameters.FractionDelimiterDisplayStyleSize then + mathparameters.FractionDelimiterDisplayStyleSize = 2.40 * parameters.size + end + elseif target.properties then + report_math("no parameters in font %a",target.properties.fullname or "?") + else + report_math("no parameters and properties in font") + end + end +end + +sequencers.appendaction("mathparameters","system","mathematics.checkprivateparameters") + +function mathematics.overloadparameters(target,original) + local mathparameters = target.mathparameters + if mathparameters and next(mathparameters) then + local goodies = target.goodies + if goodies then + for i=1,#goodies do + local goodie = goodies[i] + local mathematics = goodie.mathematics + local parameters = mathematics and mathematics.parameters + if parameters then + if trace_defining then + report_math("overloading math parameters in %a @ %p",target.properties.fullname,target.parameters.size) + end + for name, value in next, parameters do + local tvalue = type(value) + if tvalue == "string" then + report_math("comment for math parameter %a: %s",name,value) + else + local oldvalue = mathparameters[name] + local newvalue = oldvalue + if oldvalue then + if tvalue == "number" then + newvalue = value + elseif tvalue == "function" then + newvalue = value(oldvalue,target,original) + elseif not tvalue then + newvalue = nil + end + if trace_defining and oldvalue ~= newvalue then + report_math("overloading math parameter %a: %S => %S",name,oldvalue,newvalue) + end + else + report_math("invalid math parameter %a",name) + end + mathparameters[name] = newvalue + end + end + end + end + end + end +end + +sequencers.appendaction("mathparameters","system","mathematics.overloadparameters") + +local function applytweaks(when,target,original) + local goodies = original.goodies + if goodies then + for i=1,#goodies do + local goodie = goodies[i] + local mathematics = goodie.mathematics + local tweaks = mathematics and mathematics.tweaks + if tweaks then + tweaks = tweaks[when] + if tweaks then + if trace_defining then + report_math("tweaking math of %a @ %p (%s)",target.properties.fullname,target.parameters.size,when) + end + for i=1,#tweaks do + local tweak= tweaks[i] + local tvalue = type(tweak) + if tvalue == "function" then + tweak(target,original) + end + end + end + end + end + end +end + +function mathematics.tweakbeforecopyingfont(target,original) + local mathparameters = target.mathparameters -- why not hasmath + if mathparameters then + applytweaks("beforecopying",target,original) + end +end + +function mathematics.tweakaftercopyingfont(target,original) + local mathparameters = target.mathparameters -- why not hasmath + if mathparameters then + applytweaks("aftercopying",target,original) + end +end + +sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont") +sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont") + +function mathematics.overloaddimensions(target,original,set) + local goodies = target.goodies + if goodies then + for i=1,#goodies do + local goodie = goodies[i] + local mathematics = goodie.mathematics + local dimensions = mathematics and mathematics.dimensions + if dimensions then + if trace_defining then + report_math("overloading dimensions in %a @ %p",target.properties.fullname,target.parameters.size) + end + local characters = target.characters + local parameters = target.parameters + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + local addprivate = fonts.helpers.addprivate + local function overload(dimensions) + for unicode, data in next, dimensions do + local character = characters[unicode] + if character then + -- + local width = data.width + local height = data.height + local depth = data.depth + if trace_defining and (width or height or depth) then + report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth) + end + if width then character.width = width * hfactor end + if height then character.height = height * vfactor end + if depth then character.depth = depth * vfactor end + -- + local xoffset = data.xoffset + local yoffset = data.yoffset + if xoffset then + xoffset = { "right", xoffset * hfactor } + end + if yoffset then + yoffset = { "down", -yoffset * vfactor } + end + if xoffset or yoffset then + local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) } + if xoffset and yoffset then + character.commands = { xoffset, yoffset, slot } + elseif xoffset then + character.commands = { xoffset, slot } + else + character.commands = { yoffset, slot } + end + character.index = nil + end + elseif trace_defining then + report_math("no overloading dimensions of %C, not in font",unicode) + end + end + end + if set == nil then + set = { "default" } + end + if set == "all" or set == true then + for name, set in next, dimensions do + overload(set) + end + else + if type(set) == "string" then + set = utilities.parsers.settings_to_array(set) + end + if type(set) == "table" then + for i=1,#set do + local d = dimensions[set[i]] + if d then + overload(d) + end + end + end + end + end + end + end +end + +sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions") + +-- a couple of predefined tewaks: + +local tweaks = { } +mathematics.tweaks = tweaks + +function tweaks.fixbadprime(target,original) + target.characters[0xFE325] = target.characters[0x2032] +end + +-- helpers + +local setmetatableindex = table.setmetatableindex +local family_font = node.family_font + +local fontcharacters = fonts.hashes.characters +local extensibles = utilities.storage.allocate() +fonts.hashes.extensibles = extensibles + +local chardata = characters.data +local extensibles = mathematics.extensibles + +-- we use numbers at the tex end (otherwise we could stick to chars) + +local e_left = extensibles.left +local e_right = extensibles.right +local e_horizontal = extensibles.horizontal +local e_vertical = extensibles.vertical +local e_mixed = extensibles.mixed +local e_unknown = extensibles.unknown + +local unknown = { e_unknown, false, false } + +local function extensiblecode(font,unicode) + local characters = fontcharacters[font] + local character = characters[unicode] + if not character then + return unknown + end + local code = unicode + local next = character.next + while next do + code = next + character = characters[next] + next = character.next + end + local char = chardata[unicode] + local mathextensible = char and char.mathextensible + if character.horiz_variants then + if character.vert_variants then + return { e_mixed, code, character } + else + local e = mathextensible and extensibles[mathextensible] + return e and { e, code, character } or unknown + end + elseif character.vert_variants then + local e = mathextensible and extensibles[mathextensible] + return e and { e, code, character } or unknown + else + return unknown + end +end + +setmetatableindex(extensibles,function(extensibles,font) + local codes = { } + setmetatableindex(codes, function(codes,unicode) + local status = extensiblecode(font,unicode) + codes[unicode] = status + return status + end) + extensibles[font] = codes + return codes +end) + +function mathematics.extensiblecode(family,unicode) + return extensibles[family_font(family or 0)][unicode][1] +end + +function commands.extensiblecode(family,unicode) + context(extensibles[family_font(family or 0)][unicode][1]) +end + +-- left : [head] ... +-- right : ... [head] +-- horizontal : [head] ... [head] +-- +-- abs(right["start"] - right["end"]) | right.advance | characters[right.glyph].width + +function commands.horizontalcode(family,unicode) + local font = family_font(family or 0) + local data = extensibles[font][unicode] + local kind = data[1] + if kind == e_left then + local charlist = data[3].horiz_variants + local characters = fontcharacters[font] + local left = charlist[1] + texdimen.scratchleftoffset = abs((left["start"] or 0) - (left["end"] or 0)) + texdimen.scratchrightoffset = 0 + elseif kind == e_right then + local charlist = data[3].horiz_variants + local characters = fontcharacters[font] + local right = charlist[#charlist] + texdimen.scratchleftoffset = 0 + texdimen.scratchrightoffset = abs((right["start"] or 0) - (right["end"] or 0)) + elseif kind == e_horizontal then + local charlist = data[3].horiz_variants + local characters = fontcharacters[font] + local left = charlist[1] + local right = charlist[#charlist] + texdimen.scratchleftoffset = abs((left["start"] or 0) - (left["end"] or 0)) + texdimen.scratchrightoffset = abs((right["start"] or 0) - (right["end"] or 0)) + else + texdimen.scratchleftoffset = 0 + texdimen.scratchrightoffset = 0 + end + context(kind) +end |