diff options
353 files changed, 9622 insertions, 7170 deletions
diff --git a/color/icc/context/colorprofiles.xml b/color/icc/context/colorprofiles.xml index b570849c5..6c7e43397 100644 --- a/color/icc/context/colorprofiles.xml +++ b/color/icc/context/colorprofiles.xml @@ -163,7 +163,7 @@ </profile> <profile> - <filename>ISOcoated_v2_eci_300.icc</filename> + <filename>ISOcoated_v2_300_eci.icc</filename> <colorspace>CMYK</colorspace> <class>prtr</class> <id>FOGRA39</id> diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index 9e370b2d5..b81d50a32 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -194,7 +194,7 @@ local function list_specifications(t,info) fontweight(entry.fontweight), } end - aux.formatcolumns(s) + utilities.formatters.formatcolumns(s) for k=1,#s do texio.write_nl(s[k]) end @@ -221,7 +221,7 @@ local function list_matches(t,info) subfont(entry.subfont) } end - aux.formatcolumns(s) + utilities.formatters.formatcolumns(s) for k=1,#s do texio.write_nl(s[k]) end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 68ee3d2c1..ef6ccbfb6 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -52,6 +52,7 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } +local string = string local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower local lpegmatch = lpeg.match @@ -199,11 +200,6 @@ end string.padd = string.rpadd -function is_number(str) -- tonumber - return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1 -end - - function string:split_settings() -- no {} handling, see l-aux for lpeg variant if find(self,"=") then local t = { } @@ -547,12 +543,10 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -table.join = table.concat - +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match local getmetatable, setmetatable = getmetatable, setmetatable -local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs -- Starting with version 5.2 Lua no longer provide ipairs, which makes -- sense. As we already used the for loop and # in most places the @@ -1452,7 +1446,9 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte, find, gsub = string.byte, string.find, string.gsub +local io = io +local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format +local concat = table.concat if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1463,9 +1459,7 @@ end function io.loaddata(filename,textmode) local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- collectgarbage("step") -- sometimes makes a big difference in mem consumption local data = f:read('*all') - -- garbagecollector.check(data) f:close() return data else @@ -1477,7 +1471,7 @@ function io.savedata(filename,data,joiner) local f = io.open(filename,"wb") if f then if type(data) == "table" then - f:write(table.join(data,joiner or "")) + f:write(concat(data,joiner or "")) elseif type(data) == "function" then data(f) else @@ -1603,12 +1597,12 @@ function io.ask(question,default,options) while true do io.write(question) if options then - io.write(string.format(" [%s]",table.concat(options,"|"))) + io.write(format(" [%s]",concat(options,"|"))) end if default then - io.write(string.format(" [%s]",default)) + io.write(format(" [%s]",default)) end - io.write(string.format(" ")) + io.write(format(" ")) local answer = io.read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then @@ -1682,7 +1676,8 @@ local tostring = tostring local format, floor, insert, match = string.format, math.floor, table.insert, string.match local lpegmatch = lpeg.match -number = number or { } +number = number or { } +local number = number -- a,b,c,d,e,f = number.toset(100101) @@ -1759,6 +1754,8 @@ if not modules then modules = { } end modules ['l-set'] = { license = "see context related readme files" } +-- This will become obsolete when we have the bitset library embedded. + set = set or { } local nums = { } @@ -1840,10 +1837,10 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute +local os = os local find, format, gsub, upper = string.find, string.format, string.gsub, string.upper local random, ceil = math.random, math.ceil local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -- The following code permits traversing the environment table, at least -- in luatex. Internally all environment names are uppercase. @@ -2193,12 +2190,15 @@ if not modules then modules = { } end modules ['l-file'] = { -- needs a cleanup file = file or { } +local file = file local insert, concat = table.insert, table.concat local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char local lpegmatch = lpeg.match local getcurrentdir = lfs.currentdir +local P, R, S, C, Cs, Cp, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc + local function dirname(name,default) return match(name,"^(.+)[/\\].-$") or (default or "") end @@ -2416,11 +2416,11 @@ end -- also rewrite previous -local letter = lpeg.R("az","AZ") + lpeg.S("_-+") -local separator = lpeg.P("://") +local letter = R("az","AZ") + S("_-+") +local separator = P("://") -local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/") -local rootbased = lpeg.P("/") + letter*lpeg.P(":") +local qualified = P(".")^0 * P("/") + letter*P(":") + letter^1*separator + letter^1 * P("/") +local rootbased = P("/") + letter*P(":") -- ./name ../name /name c: :// name/name @@ -2432,14 +2432,16 @@ function file.is_rootbased_path(filename) return lpegmatch(rootbased,filename) ~= nil end -local slash = lpeg.S("\\/") -local period = lpeg.P(".") -local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":") -local path = lpeg.C(((1-slash)^0 * slash)^0) -local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1)) -local base = lpeg.C((1-suffix)^0) +-- actually these are schemes + +local slash = S("\\/") +local period = P(".") +local drive = C(R("az","AZ")) * P(":") +local path = C(((1-slash)^0 * slash)^0) +local suffix = period * C(P(1-period)^0 * P(-1)) +local base = C((1-suffix)^0) -local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) function file.splitname(str) -- returns drive, path, base, suffix return lpegmatch(pattern,str) @@ -2467,6 +2469,7 @@ if not modules then modules = { } end modules ['l-md5'] = { -- This also provides file checksums and checkers. +local md5, file = md5, file local gsub, format, byte = string.gsub, string.format, string.byte local function convert(str,fmt) @@ -2547,7 +2550,8 @@ local lpegmatch, lpegP, lpegC, lpegR, lpegS, lpegCs, lpegCc = lpeg.match, lpeg.P -- / \ / \ -- urn:example:animal:ferret:nose -url = url or { } +url = url or { } +local url = url local function tochar(s) return char(tonumber(s,16)) @@ -2687,20 +2691,30 @@ if not modules then modules = { } end modules ['l-dir'] = { local type = type local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local concat = table.concat local lpegmatch = lpeg.match +local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V + dir = dir or { } +local dir = dir +local lfs = lfs + +local attributes = lfs.attributes +local walkdir = lfs.dir +local isdir = lfs.isdir +local isfile = lfs.isfile +local mkdir = lfs.mkdir +local chdir = lfs.chdir +local currentdir = lfs.currentdir -- handy function dir.current() - return (gsub(lfs.currentdir(),"\\","/")) + return (gsub(currentdir(),"\\","/")) end --- optimizing for no string.find (*) does not save time - -local attributes = lfs.attributes -local walkdir = lfs.dir +-- optimizing for no find (*) does not save time local function glob_pattern(path,patt,recurse,action) local ok, scanner @@ -2756,8 +2770,6 @@ end dir.collect_pattern = collect_pattern -local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V - local pattern = Ct { [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3), [2] = C(((1-S("*?/"))^0 * P("/"))^0), @@ -2780,7 +2792,7 @@ local function glob(str,t) for s=1,#str do glob(str[s],t) end - elseif lfs.isfile(str) then + elseif isfile(str) then t(str) else local split = lpegmatch(pattern,str) @@ -2799,7 +2811,7 @@ local function glob(str,t) glob(str[s],t) end return t - elseif lfs.isfile(str) then + elseif isfile(str) then local t = t or { } t[#t+1] = str return t @@ -2863,13 +2875,13 @@ dir.globfiles = globfiles -- print(dir.ls("*.tex")) function dir.ls(pattern) - return table.concat(glob(pattern),"\n") + return concat(glob(pattern),"\n") end local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then -- os.type == "windows" +if find(os.getenv("PATH"),";") then -- os.type == "windows" function dir.mkdirs(...) local str, pth, t = "", "", { ... } @@ -2918,11 +2930,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" else pth = pth .. "/" .. s end - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end @@ -2937,11 +2949,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" if not first then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then - local d = lfs.currentdir() - if lfs.chdir(first) then + local d = currentdir() + if chdir(first) then first = dir.current() end - lfs.chdir(d) + chdir(d) end end if not first then @@ -2982,26 +2994,26 @@ else else pth = pth .. "/" .. s end - if make_indeed and not first and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not first and not isdir(pth) then + mkdir(pth) end end else pth = "." for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end function dir.expand_name(str) -- will be merged with cleanpath and collapsepath if not find(str,"^/") then - str = lfs.currentdir() .. "/" .. str + str = currentdir() .. "/" .. str end str = gsub(str,"//","/") str = gsub(str,"/%./","/") @@ -3025,10 +3037,11 @@ if not modules then modules = { } end modules ['l-boolean'] = { license = "see context related readme files" } -boolean = boolean or { } - local type, tonumber = type, tonumber +boolean = boolean or { } +local boolean = boolean + function boolean.tonumber(b) if b then return 1 else return 0 end end @@ -3109,6 +3122,8 @@ if not unicode then end +local unicode = unicode + utf = utf or unicode.utf8 local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub @@ -3280,7 +3295,7 @@ end function unicode.utfcodes(str) local t = { } - for k,v in string.utfvalues(str) do + for k,v in utfvalues(str) do t[#t+1] = format("0x%04X",k) end return concat(t,separator or " ") @@ -3339,7 +3354,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-utils'] = { +if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3353,13 +3368,11 @@ local gsub, format = string.gsub, string.format local concat = table.concat local type, next = type, next -if not utils then utils = { } end -if not utils.merger then utils.merger = { } end -if not utils.lua then utils.lua = { } end - -utils.report = utils.report or print +utilities = utilities or {} +utilities.merger = utilities.merger or { } +utilities.report = utilities.report or print -local merger = utils.merger +local merger = utilities.merger merger.strip_comment = true @@ -3396,9 +3409,9 @@ end local function self_load(name) local data = io.loaddata(name) or "" if data == "" then - utils.report("merge: unknown file %s",name) + utilities.report("merge: unknown file %s",name) else - utils.report("merge: inserting %s",name) + utilities.report("merge: inserting %s",name) end return data or "" end @@ -3409,10 +3422,10 @@ local function self_save(name, data) -- saves some 20K local n = #data data = gsub(data,"%-%-~[^\n\r]*[\r\n]","") - utils.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) + utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) end io.savedata(name,data) - utils.report("merge: saving %s",name) + utilities.report("merge: saving %s",name) end end @@ -3429,7 +3442,7 @@ local function self_libs(libs,list) local lib = libs[i] for j=1,#list do local pth = gsub(list[j],"\\","/") -- file.clean_path - utils.report("merge: checking library path %s",pth) + utilities.report("merge: checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then foundpath = pth @@ -3438,30 +3451,30 @@ local function self_libs(libs,list) if foundpath then break end end if foundpath then - utils.report("merge: using library path %s",foundpath) + utilities.report("merge: using library path %s",foundpath) local right, wrong = { }, { } for i=1,#libs do local lib = libs[i] local fullname = foundpath .. "/" .. lib if lfs.isfile(fullname) then - utils.report("merge: using library %s",fullname) + utilities.report("merge: using library %s",fullname) right[#right+1] = lib result[#result+1] = m_begin_closure result[#result+1] = io.loaddata(fullname,true) result[#result+1] = m_end_closure else - utils.report("merge: skipping library %s",fullname) + utilities.report("merge: skipping library %s",fullname) wrong[#wrong+1] = lib end end if #right > 0 then - utils.report("merge: used libraries: %s",concat(right," ")) + utilities.report("merge: used libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("merge: skipped libraries: %s",concat(wrong," ")) + utilities.report("merge: skipped libraries: %s",concat(wrong," ")) end else - utils.report("merge: no valid library path found") + utilities.report("merge: no valid library path found") end return concat(result, "\n\n") end @@ -3480,8 +3493,25 @@ function merger.selfclean(name) self_save(name,self_swap(self_load(name),self_nothing())) end -function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true - utils.report("lua: compiling %s into %s",luafile,lucfile) + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.lua = utilities.merger or { } +utilities.report = utilities.report or print + +function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) os.remove(lucfile) local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) if strip ~= false then @@ -3489,7 +3519,7 @@ function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=f end local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utils.report("lua: removing %s",luafile) + utilities.report("lua: removing %s",luafile) os.remove(luafile) end return done @@ -3501,7 +3531,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-aux'] = { +if not modules then modules = { } end modules ['util-prs'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3509,15 +3539,16 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } --- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end - -aux = aux or { } +utilities = utilities or {} +utilities.parsers = utilities.parsers or { } +local parsers = utilities.parsers +parsers.patterns = parsers.patterns or { } +local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg +local lpegmatch = lpeg.match local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type -local lpegmatch = lpeg.match - -local P, R, V = lpeg.P, lpeg.R, lpeg.V +local sortedhash = table.sortedhash local escape, left, right = P("\\"), P('{'), P('}') @@ -3526,23 +3557,23 @@ lpeg.patterns.balanced = P { [2] = left * V(1) * right } -local space = lpeg.P(' ') -local equal = lpeg.P("=") -local comma = lpeg.P(",") -local lbrace = lpeg.P("{") -local rbrace = lpeg.P("}") +local space = P(' ') +local equal = P("=") +local comma = P(",") +local lbrace = P("{") +local rbrace = P("}") local nobrace = 1 - (lbrace+rbrace) -local nested = lpeg.P { lbrace * (nobrace + lpeg.V(1))^0 * rbrace } +local nested = P { lbrace * (nobrace + V(1))^0 * rbrace } local spaces = space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) -local key = lpeg.C((1-equal-comma)^1) -local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C("")) +local key = C((1-equal-comma)^1) +local pattern_a = (space+comma)^0 * (key * equal * value + key * C("")) local pattern_c = (space+comma)^0 * (key * equal * value) -local key = lpeg.C((1-space-equal-comma)^1) -local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + lpeg.C(""))) +local key = C((1-space-equal-comma)^1) +local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C(""))) -- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored @@ -3556,11 +3587,11 @@ local pattern_a_s = (pattern_a/set)^1 local pattern_b_s = (pattern_b/set)^1 local pattern_c_s = (pattern_c/set)^1 -aux.settings_to_hash_pattern_a = pattern_a_s -aux.settings_to_hash_pattern_b = pattern_b_s -aux.settings_to_hash_pattern_c = pattern_c_s +parsers.patterns.settings_to_hash_a = pattern_a_s +parsers.patterns.settings_to_hash_b = pattern_b_s +parsers.patterns.settings_to_hash_c = pattern_c_s -function aux.make_settings_to_hash_pattern(set,how) +function parsers.make_settings_to_hash_pattern(set,how) if how == "strict" then return (pattern_c/set)^1 elseif how == "tolerant" then @@ -3570,7 +3601,7 @@ function aux.make_settings_to_hash_pattern(set,how) end end -function aux.settings_to_hash(str,existing) +function parsers.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_a_s,str) @@ -3580,7 +3611,7 @@ function aux.settings_to_hash(str,existing) end end -function aux.settings_to_hash_tolerant(str,existing) +function parsers.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_b_s,str) @@ -3590,7 +3621,7 @@ function aux.settings_to_hash_tolerant(str,existing) end end -function aux.settings_to_hash_strict(str,existing) +function parsers.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_c_s,str) @@ -3601,16 +3632,16 @@ function aux.settings_to_hash_strict(str,existing) end local separator = comma * space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(separator*value)^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) +local pattern = Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored -aux.settings_to_array_pattern = pattern +parsers.patterns.settings_to_array = pattern -- we could use a weak table as cache -function aux.settings_to_array(str) +function parsers.settings_to_array(str) if not str or str == "" then return { } else @@ -3622,14 +3653,14 @@ local function set(t,v) t[#t+1] = v end -local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(separator*value)^0 * lpeg.Carg(1) +local value = P(Carg(1)*value) / set +local pattern = value*(separator*value)^0 * Carg(1) -function aux.add_settings_to_array(t,str) +function parsers.add_settings_to_array(t,str) return lpegmatch(pattern,str,nil,t) end -function aux.hash_to_string(h,separator,yes,no,strict,omit) +function parsers.hash_to_string(h,separator,yes,no,strict,omit) if h then local t, s = { }, table.sortedkeys(h) omit = omit and table.tohash(omit) @@ -3658,7 +3689,7 @@ function aux.hash_to_string(h,separator,yes,no,strict,omit) end end -function aux.array_to_string(a,separator) +function parsers.array_to_string(a,separator) if a then return concat(a,separator or ",") else @@ -3666,7 +3697,7 @@ function aux.array_to_string(a,separator) end end -function aux.settings_to_set(str,t) -- tohash? +function parsers.settings_to_set(str,t) -- tohash? -- todo: lpeg -- duplicate anyway t = t or { } for s in gmatch(str,"%s*([^, ]+)") do -- space added t[s] = true @@ -3674,9 +3705,9 @@ function aux.settings_to_set(str,t) -- tohash? return t end -function aux.simple_hash_to_string(h, separator) +function parsers.simple_hash_to_string(h, separator) local t = { } - for k, v in table.sortedhash(h) do + for k, v in sortedhash(h) do if v then t[#t+1] = k end @@ -3684,43 +3715,44 @@ function aux.simple_hash_to_string(h, separator) return concat(t,separator or ",") end -local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace -local pattern = lpeg.Ct((space + value)^0) +local value = lbrace * C((nobrace + nested)^0) * rbrace +local pattern = Ct((space + value)^0) -function aux.arguments_to_table(str) +function parsers.arguments_to_table(str) return lpegmatch(pattern,str) end --- temporary here +-- temporary here (unoptimized) -function aux.getparameters(self,class,parentclass,settings) +function parsers.getparameters(self,class,parentclass,settings) local sc = self[class] if not sc then sc = table.clone(self[parent]) self[class] = sc end - aux.settings_to_hash(settings,sc) + parsers.settings_to_hash(settings,sc) end --- temporary here -local digit = lpeg.R("09") -local period = lpeg.P(".") -local zero = lpeg.P("0") -local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") -local number = digit^1 * (case_1 + case_2) -local stripper = lpeg.Cs((number + 1)^0) +end -- of closure +do -- create closure to overcome 200 locals limit -lpeg.patterns.strip_zeros = stripper +if not modules then modules = { } end modules ['util-tab'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} -function aux.strip_zeros(str) - return lpegmatch(stripper,str) -end +utilities = utilities or {} +utilities.tables = utilities.tables or { } +local tables = utilities.tables + +local concat, format, gmatch = table.concat, string.format, string.gmatch -function aux.definetable(target) -- defines undefined tables +function tables.definetable(target) -- defines undefined tables local composed, t = nil, { } for name in gmatch(target,"([^%.]+)") do if composed then @@ -3733,7 +3765,7 @@ function aux.definetable(target) -- defines undefined tables return concat(t,"\n") end -function aux.accesstable(target) +function tables.accesstable(target) local t = _G for name in gmatch(target,"([^%.]+)") do t = t[name] @@ -3742,10 +3774,48 @@ function aux.accesstable(target) end --- as we use this a lot ... +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-fmt'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or { } +utilities.formatters = utilities.formatters or { } +local formatters = utilities.formatters + +local concat, format = table.concat, string.format +local tostring, type = tostring, type +local strip = string.strip + +local P, R, Cs = lpeg.P, lpeg.R, lpeg.Cs +local lpegmatch = lpeg.match +-- temporary here -function aux.formatcolumns(result,between) +local digit = R("09") +local period = P(".") +local zero = P("0") +local trailingzeros = zero^0 * -digit -- suggested by Roberto R +local case_1 = period * trailingzeros / "" +local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number = digit^1 * (case_1 + case_2) +local stripper = Cs((number + 1)^0) + + +lpeg.patterns.strip_zeros = stripper + +function formatters.strip_zeros(str) + return lpegmatch(stripper,str) +end + +function formatters.formatcolumns(result,between) if result and #result > 0 then between = between or " " local widths, numbers = { }, { } @@ -3790,10 +3860,10 @@ function aux.formatcolumns(result,between) end end end - local template = string.strip(concat(widths)) + local template = strip(concat(widths)) for i=1,#result do local str = format(template,unpack(result[i])) - result[i] = string.strip(str) + result[i] = strip(str) end end return result @@ -3804,6 +3874,115 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util.deb'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the <anonymous> tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local format, find = string.format, string.find +local is_boolean = string.is_boolean + +utilities = utilities or { } +utilities.debugger = utilities.debugger or { } +local debugger = utilities.debugger + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end + +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '<anonymous>' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end + +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +end + + + + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['trac-inf'] = { version = 1.001, comment = "companion to trac-inf.mkiv", @@ -3820,14 +3999,13 @@ if not modules then modules = { } end modules ['trac-inf'] = { local format = string.format local clock = os.gettimeofday or os.clock -- should go in environment -local statusinfo, n, registered = { }, 0, { } - -statistics = statistics or { } +statistics = statistics or { } +local statistics = statistics statistics.enable = true statistics.threshold = 0.05 -local timers = { } +local statusinfo, n, registered, timers = { }, 0, { }, { } local function hastiming(instance) return instance and timers[instance] @@ -3995,7 +4173,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['trac-set'] = { +if not modules then modules = { } end modules ['trac-set'] = { -- might become util-set.lua version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4007,8 +4185,12 @@ local type, next, tostring = type, next, tostring local concat = table.concat local format, find, lower, gsub, simpleesc = string.format, string.find, string.lower, string.gsub, string.simpleesc local is_boolean = string.is_boolean +local settings_to_hash = utilities.parsers.settings_to_hash -setters = { } +utilities = utilities or { } +local utilities = utilities +utilities.setters = utilities.setters or { } +local setters = utilities.setters local data = { } -- maybe just local @@ -4064,7 +4246,7 @@ end local function set(t,what,newvalue) local data, done = t.data, t.done if type(what) == "string" then - what = aux.settings_to_hash(what) -- inefficient but ok + what = settings_to_hash(what) -- inefficient but ok end for w, value in next, what do if value == "" then @@ -4191,18 +4373,20 @@ end -- we could have used a bit of oo and the trackers:enable syntax but -- there is already a lot of code around using the singular tracker --- we could make this into a module +-- we could make this into a module but we also want the rest avaliable + +local enable, disable, register, list, show = setters.enable, setters.disable, setters.register, setters.list, setters.show function setters.new(name) - local t + local t -- we need to access it in t t = { data = { }, -- indexed, but also default and value fields name = name, - enable = function(...) setters.enable (t,...) end, - disable = function(...) setters.disable (t,...) end, - register = function(...) setters.register(t,...) end, - list = function(...) setters.list (t,...) end, - show = function(...) setters.show (t,...) end, + enable = function(...) enable (t,...) end, + disable = function(...) disable (t,...) end, + register = function(...) register(t,...) end, + list = function(...) list (t,...) end, + show = function(...) show (t,...) end, } data[name] = t return t @@ -4212,13 +4396,18 @@ trackers = setters.new("trackers") directives = setters.new("directives") experiments = setters.new("experiments") +local t_enable, t_disable = trackers .enable, trackers .disable +local d_enable, d_disable = directives .enable, directives .disable +local e_enable, e_disable = experiments.enable, experiments.disable + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end + if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) + d_enable(environment.engineflags.directives) end -- nice trick: we overload two of the directives related functions with variants that @@ -4232,30 +4421,24 @@ end local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) -local enable = directives.enable -local disable = directives.disable - function directives.enable(...) report("directives","enabling: %s",concat({...}," ")) - enable(...) + d_enable(...) end function directives.disable(...) report("directives","disabling: %s",concat({...}," ")) - disable(...) + d_disable(...) end -local enable = experiments.enable -local disable = experiments.disable - function experiments.enable(...) report("experiments","enabling: %s",concat({...}," ")) - enable(...) + e_enable(...) end function experiments.disable(...) report("experiments","disabling: %s",concat({...}," ")) - disable(...) + e_disable(...) end -- a useful example @@ -4264,136 +4447,20 @@ directives.register("system.nostatistics", function(v) statistics.enable = not v end) +directives.register("system.nolibraries", function(v) + libraries = nil -- we discard this tracing for security +end) + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) -end - - -end -- of closure - -do -- create closure to overcome 200 locals limit - -if not modules then modules = { } end modules ['trac-tra'] = { - version = 1.001, - comment = "companion to trac-tra.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- the <anonymous> tag is kind of generic and used for functions that are not --- bound to a variable, like node.new, node.copy etc (contrary to for instance --- node.has_attribute which is bound to a has_attribute local variable in mkiv) - -local debug = require "debug" - -local getinfo = debug.getinfo -local type, next = type, next -local format, find = string.format, string.find -local is_boolean = string.is_boolean - -debugger = debugger or { } - -local counters = { } -local names = { } - --- one - -local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end - if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' - else - -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) - end - else - return "unknown" - end -end - -function debugger.showstats(printer,threshold) - printer = printer or texio.write or print - threshold = threshold or 0 - local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end - end - grandtotal = grandtotal + count - functions = functions + 1 - end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) -end - --- two - - --- rest - -function debugger.savestats(filename,threshold) - local f = io.open(filename,'w') - if f then - debugger.showstats(function(str) f:write(str) end,threshold) - f:close() - end -end - -function debugger.enable() - debug.sethook(hook,"c") -end - -function debugger.disable() - debug.sethook() -end - -local function trace_calls(n) - debugger.enable() - luatex.register_stop_actions(function() - debugger.disable() - debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) - end) - trace_calls = function() end -end - -if directives then - directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling + d_enable(environment.engineflags.directives) end - - - - end -- of closure do -- create closure to overcome 200 locals limit @@ -4422,7 +4489,8 @@ provide an <l n='xml'/> structured file. Actually, any logging that is hooked into callbacks will be \XML\ by default.</p> --ldx]]-- -logs = logs or { } +logs = logs or { } +local logs = logs --[[ldx-- <p>This looks pretty ugly but we need to speed things up a bit.</p> @@ -4665,8 +4733,8 @@ function noplog.simple(fmt,...) -- todo: fmt,s end end -if utils then - utils.report = function(...) logs.simple(...) end +if utilities then + utilities.report = function(...) logs.simple(...) end end function logs.setprogram(newname,newbanner) @@ -4736,6 +4804,50 @@ function logs.fatal(where,...) end +function logs.obsolete(old,new) + local o = loadstring("return " .. new)() + if type(o) == "function" then + return function(...) + logs.report("system","function %s is obsolete, use %s",old,new) + loadstring(old .. "=" .. new .. " return ".. old)()(...) + end + elseif type(o) == "table" then + local t, m = { }, { } + m.__index = function(t,k) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + return o[k] + end + m.__newindex = function(t,k,v) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + o[k] = v + end + if libraries then + libraries.obsolete[old] = t -- true + end + setmetatable(t,m) + return t + end +end + +if tex.error then + + function logs.texerrormessage(...) -- for the moment we put this function here + tex.error(format(...), { }) + end + +else + + function logs.texerrormessage(...) -- for the moment we put this function here + local v = format(...) + tex.sprint(tex.ctxcatcodes,"\\errmessage{") + tex.sprint(tex.vrbcatcodes,v) + tex.print(tex.ctxcatcodes,"}") + end + +end + end -- of closure @@ -4762,7 +4874,8 @@ local trace_namespaces = false trackers.register("system.namespaces", function( local report_system = logs.new("system") -namespaces = { } +namespaces = namespaces or { } +local namespaces = namespaces local registered = { } @@ -4932,6 +5045,7 @@ local report_resolvers = logs.new("resolvers") local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find local unquote, quote = string.unquote, string.quote +local concat = table.concat -- precautions @@ -4956,6 +5070,8 @@ end -- environment environment = environment or { } +local environment = environment + environment.arguments = { } environment.files = { } environment.sortedflags = nil @@ -5078,7 +5194,7 @@ function environment.reconstruct_commandline(arg,noquote) result[#result+1] = a end end - return table.join(result," ") + return concat(result," ") else return "" end @@ -5248,6 +5364,7 @@ optimize the code.</p> --ldx]]-- xml = xml or { } +local xml = xml local concat, remove, insert = table.concat, table.remove, table.insert @@ -6453,6 +6570,8 @@ of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We will explain more about its usage in other documents.</p> --ldx]]-- +local xml = xml + local lpathcalls = 0 function xml.lpathcalls () return lpathcalls end local lpathcached = 0 function xml.lpathcached() return lpathcached end @@ -7647,6 +7766,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton local format, gsub, match = string.format, string.gsub, string.match local lpegmatch = lpeg.match +local xml = xml + --[[ldx-- <p>The following helper functions best belong to the <t>lxml-ini</t> module. Some are here because we need then in the <t>mk</t> @@ -7748,6 +7869,8 @@ local trace_manipulations = false trackers.register("lxml.manipulations", funct local report_xml = logs.new("xml") +local xml = xml + local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert @@ -8262,6 +8385,8 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } +local xml = xml + local finalizers = xml.finalizers.xml local xmlfilter = xml.filter -- we could inline this one for speed local xmltostring = xml.tostring @@ -8588,7 +8713,8 @@ local ostype, osname, ossetenv, osgetenv = os.type, os.name, os.setenv, os.geten -- we now split it over multiple files. As this file is now the -- starting point we introduce resolvers here. -resolvers = resolvers or { } +resolvers = resolvers or { } +local resolvers = resolvers -- We don't want the kpse library to kick in. Also, we want to be able to -- execute programs. Control over execution is implemented later. @@ -8812,6 +8938,8 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- As this bit of code is somewhat special it gets its own module. After -- all, when working on the main resolver code, I don't want to scroll -- past this every time. @@ -9119,6 +9247,8 @@ if not modules then modules = { } end modules ['data-env'] = { license = "see context related readme files", } +local resolvers = resolvers + local formats = { } resolvers.formats = formats local suffixes = { } resolvers.suffixes = suffixes local dangerous = { } resolvers.dangerous = dangerous @@ -9309,11 +9439,13 @@ local mkdirs, isdir = dir.mkdirs, lfs.isdir local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end) -local report_cache = logs.new("cache") - +local report_cache = logs.new("cache") local report_resolvers = logs.new("resolvers") -caches = caches or { } +local resolvers = resolvers + +caches = caches or { } +local caches = caches caches.base = caches.base or "luatex-cache" caches.more = caches.more or "context" @@ -9558,7 +9690,7 @@ function caches.savedata(filepath,filename,data,raw) end local cleanup = resolvers.boolean_variable("PURGECACHE", false) local strip = resolvers.boolean_variable("LUACSTRIP", true) - utils.lua.compile(tmaname, tmcname, cleanup, strip) + utilities.lua.compile(tmaname, tmcname, cleanup, strip) end -- moved from data-res: @@ -9620,7 +9752,7 @@ function caches.savecontent(cachename,dataname,content) if trace_locating then report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname) end - if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip + if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip if trace_locating then report_resolvers("'%s' compiled to '%s'",dataname,lucname) end @@ -9657,6 +9789,8 @@ local trace_locating = false trackers.register("resolvers.locating", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + resolvers.locators = { notfound = { nil } } -- locate databases resolvers.hashers = { notfound = { nil } } -- load databases resolvers.generators = { notfound = { nil } } -- generate databases @@ -9713,6 +9847,7 @@ if not modules then modules = { } end modules ['data-res'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local os = os local lpegP, lpegS, lpegR, lpegC, lpegCc, lpegCs, lpegCt = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns @@ -9726,10 +9861,14 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local expanded_path_from_list = resolvers.expanded_path_from_list local checked_variable = resolvers.checked_variable local split_configuration_path = resolvers.split_configuration_path +local initializesetter = utilities.setters.initialize + local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.setenv, os.getenv resolvers.cacheversion = '1.0.1' @@ -9949,7 +10088,7 @@ local function load_configuration_files() t[k] = v elseif kind == "table" then -- this operates on the table directly - setters.initialize(filename,k,v) + initializesetter(filename,k,v) -- this doesn't (maybe metatables some day) for kk, vv in next, v do -- vv = variable if vv ~= unset_variable then @@ -11122,6 +11261,8 @@ if not modules then modules = { } end modules ['data-pre'] = { local upper, lower, gsub = string.upper, string.lower, string.gsub +local resolvers = resolvers + local prefixes = { } local getenv = resolvers.getenv @@ -11235,6 +11376,8 @@ if not modules then modules = { } end modules ['data-inp'] = { license = "see context related readme files" } +local resolvers = resolvers + resolvers.finders = resolvers.finders or { } resolvers.openers = resolvers.openers or { } resolvers.loaders = resolvers.loaders or { } @@ -11256,7 +11399,7 @@ if not modules then modules = { } end modules ['data-out'] = { license = "see context related readme files" } -outputs = outputs or { } +-- not used yet @@ -11291,8 +11434,8 @@ table structures without bothering about the disk cache.</p> <p>Examples of usage can be found in the font related code.</p> --ldx]]-- -containers = containers or { } - +containers = containers or { } +local containers = containers containers.usecache = true local report_cache = logs.new("cache") @@ -11418,6 +11561,8 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- we will make a better format, maybe something xml or just text or lua resolvers.automounted = resolvers.automounted or { } @@ -11526,15 +11671,20 @@ local report_resolvers = logs.new("resolvers") -- zip:///texmf.zip?tree=/tex/texmf-local -- zip:///texmf-mine.zip?tree=/tex/texmf-projects -zip = zip or { } -zip.archives = zip.archives or { } -zip.registeredfiles = zip.registeredfiles or { } +local resolvers = resolvers + +zip = zip or { } +local zip = zip + +zip.archives = zip.archives or { } +local archives = zip.archives + +zip.registeredfiles = zip.registeredfiles or { } +local registeredfiles = zip.registeredfiles local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local locators, hashers, concatinators = resolvers.locators, resolvers.hashers, resolvers.concatinators -local archives = zip.archives - local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str @@ -11698,7 +11848,7 @@ function resolvers.usezipfile(zipname) zipname = validzip(zipname) local specification = resolvers.splitmethod(zipname) local zipfile = specification.path - if zipfile and not zip.registeredfiles[zipname] then + if zipfile and not registeredfiles[zipname] then local tree = url.query(specification.query).tree or "" local z = zip.openarchive(zipfile) if z then @@ -11709,7 +11859,7 @@ function resolvers.usezipfile(zipname) statistics.starttiming(instance) resolvers.prepend_hash('zip',zipname,zipfile) resolvers.extend_texmf_var(zipname) -- resets hashes too - zip.registeredfiles[zipname] = z + registeredfiles[zipname] = z instance.files[zipname] = resolvers.register_zip_file(z,tree or "") statistics.stoptiming(instance) elseif trace_locating then @@ -11769,6 +11919,8 @@ local unpack = unpack or table.unpack local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local done, found, notfound = { }, { }, resolvers.finders.notfound function resolvers.finders.tree(specification,filetype) @@ -11851,11 +12003,15 @@ if not modules then modules = { } end modules ['data-crl'] = { -- this one is replaced by data-sch.lua -- -curl = curl or { } - local gsub = string.gsub + +local resolvers = resolvers + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +curl = curl or { } +local curl = curl + local cached = { } function curl.fetch(protocol, name) -- todo: use socket library @@ -11925,6 +12081,8 @@ local report_resolvers = logs.new("resolvers") local gsub, insert = string.gsub, table.insert local unpack = unpack or table.unpack +local resolvers, package = resolvers, package + local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' local clibformats = { 'lib' } @@ -12079,6 +12237,8 @@ local type, next = type, next local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) +local resolvers = resolvers + local report_resolvers = logs.new("resolvers") function resolvers.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix @@ -12140,6 +12300,8 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local resolvers = resolvers + -- = << -- ? ?? -- < += @@ -12209,6 +12371,8 @@ local find, concat, upper, format = string.find, table.concat, string.upper, str resolvers.listers = resolvers.listers or { } +local resolvers = resolvers + local function tabstr(str) if type(str) == 'table' then return concat(str," | ") @@ -12258,9 +12422,15 @@ if not modules then modules = { } end modules ['luat-sta'] = { local gmatch, match = string.gmatch, string.match local type = type -states = states or { } -states.data = states.data or { } -states.hash = states.hash or { } +states = states or { } +local states = states + +states.data = states.data or { } +local data = states.data + +states.hash = states.hash or { } +local hash = states.hash + states.tag = states.tag or "" states.filename = states.filename or "" @@ -12270,7 +12440,7 @@ function states.save(filename,tag) io.savedata(filename, "-- generator : luat-sta.lua\n" .. "-- state tag : " .. tag .. "\n\n" .. - table.serialize(states.data[tag or states.tag] or {},true) + table.serialize(data[tag or states.tag] or {},true) ) end @@ -12278,11 +12448,11 @@ function states.load(filename,tag) states.filename = filename states.tag = tag or "whatever" states.filename = file.addsuffix(states.filename,'lus') - states.data[states.tag], states.hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } + data[states.tag], hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } end -function states.set_by_tag(tag,key,value,default,persistent) - local d, h = states.data[tag], states.hash[tag] +local function set_by_tag(tag,key,value,default,persistent) + local d, h = data[tag], hash[tag] if d then if type(d) == "table" then local dkey, hkey = key, key @@ -12312,17 +12482,17 @@ function states.set_by_tag(tag,key,value,default,persistent) d[dkey], h[hkey] = value, value elseif type(d) == "string" then -- weird - states.data[tag], states.hash[tag] = value, value + data[tag], hash[tag] = value, value end end end -function states.get_by_tag(tag,key,default) - local h = states.hash[tag] +local function get_by_tag(tag,key,default) + local h = hash[tag] if h and h[key] then return h[key] else - local d = states.data[tag] + local d = data[tag] if d then for k in gmatch(key,"[^%.]+") do local dk = d[k] @@ -12337,12 +12507,15 @@ function states.get_by_tag(tag,key,default) end end +states.set_by_tag = set_by_tag +states.get_by_tag = get_by_tag + function states.set(key,value,default,persistent) - states.set_by_tag(states.tag,key,value,default,persistent) + set_by_tag(states.tag,key,value,default,persistent) end function states.get(key,default) - return states.get_by_tag(states.tag,key,default) + return get_by_tag(states.tag,key,default) end @@ -12422,10 +12595,10 @@ function environment.make_format(name) local lucstubname = file.addsuffix(texbasename,"luc") -- pack libraries in stub logs.simple("creating initialization file: %s",luastubname) - utils.merger.selfcreate(usedlualibs,specificationpath,luastubname) + utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname) -- compile stub file (does not save that much as we don't use this stub at startup any more) local strip = resolvers.boolean_variable("LUACSTRIP", true) - if utils.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then + if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then logs.simple("using compiled initialization file: %s",lucstubname) usedluastub = lucstubname else @@ -12507,12 +12680,16 @@ own.libs = { -- order can be made better 'l-boolean.lua', 'l-unicode.lua', 'l-math.lua', - 'l-utils.lua', - 'l-aux.lua', + + 'util-mrg.lua', + 'util-lua.lua', + 'util-prs.lua', + 'util-tab.lua', + 'util-fmt.lua', + 'util-deb.lua', 'trac-inf.lua', 'trac-set.lua', - 'trac-tra.lua', 'trac-log.lua', 'trac-pro.lua', 'luat-env.lua', -- can come before inf (as in mkiv) @@ -12524,7 +12701,6 @@ own.libs = { -- order can be made better 'lxml-aux.lua', 'lxml-xml.lua', - 'data-ini.lua', 'data-exp.lua', 'data-env.lua', @@ -12589,6 +12765,7 @@ local function locate_libs() local filename = pth .. "/" .. lib local found = lfs.isfile(filename) if found then + package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require return pth end end @@ -13326,7 +13503,7 @@ if environment.argument("selfmerge") then runners.loadbase() local found = locate_libs() if found then - utils.merger.selfmerge(own.name,own.libs,{ found }) + utilities.merger.selfmerge(own.name,own.libs,{ found }) end elseif environment.argument("selfclean") then @@ -13334,7 +13511,7 @@ elseif environment.argument("selfclean") then -- remove embedded libraries runners.loadbase() - utils.merger.selfclean(own.name) + utilities.merger.selfclean(own.name) elseif environment.argument("selfupdate") then @@ -13599,6 +13776,7 @@ elseif false then else + runners.loadbase() runners.execute_ctx_script("mtx-base",filename) end diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb index e89a88060..5c9fa2c98 100644 --- a/scripts/context/ruby/base/tex.rb +++ b/scripts/context/ruby/base/tex.rb @@ -362,9 +362,9 @@ class TEX end rescue end - ['mpgraph.mp'].each do |file| - (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false - end + # ['mpgraph.mp'].each do |file| + # (File.delete(file) if (FileTest.size?(file) rescue 10) < 10) rescue false + # end end def backends() @@backends.keys.sort end diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 68ee3d2c1..ef6ccbfb6 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -52,6 +52,7 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } +local string = string local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower local lpegmatch = lpeg.match @@ -199,11 +200,6 @@ end string.padd = string.rpadd -function is_number(str) -- tonumber - return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1 -end - - function string:split_settings() -- no {} handling, see l-aux for lpeg variant if find(self,"=") then local t = { } @@ -547,12 +543,10 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -table.join = table.concat - +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match local getmetatable, setmetatable = getmetatable, setmetatable -local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs -- Starting with version 5.2 Lua no longer provide ipairs, which makes -- sense. As we already used the for loop and # in most places the @@ -1452,7 +1446,9 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte, find, gsub = string.byte, string.find, string.gsub +local io = io +local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format +local concat = table.concat if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1463,9 +1459,7 @@ end function io.loaddata(filename,textmode) local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- collectgarbage("step") -- sometimes makes a big difference in mem consumption local data = f:read('*all') - -- garbagecollector.check(data) f:close() return data else @@ -1477,7 +1471,7 @@ function io.savedata(filename,data,joiner) local f = io.open(filename,"wb") if f then if type(data) == "table" then - f:write(table.join(data,joiner or "")) + f:write(concat(data,joiner or "")) elseif type(data) == "function" then data(f) else @@ -1603,12 +1597,12 @@ function io.ask(question,default,options) while true do io.write(question) if options then - io.write(string.format(" [%s]",table.concat(options,"|"))) + io.write(format(" [%s]",concat(options,"|"))) end if default then - io.write(string.format(" [%s]",default)) + io.write(format(" [%s]",default)) end - io.write(string.format(" ")) + io.write(format(" ")) local answer = io.read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then @@ -1682,7 +1676,8 @@ local tostring = tostring local format, floor, insert, match = string.format, math.floor, table.insert, string.match local lpegmatch = lpeg.match -number = number or { } +number = number or { } +local number = number -- a,b,c,d,e,f = number.toset(100101) @@ -1759,6 +1754,8 @@ if not modules then modules = { } end modules ['l-set'] = { license = "see context related readme files" } +-- This will become obsolete when we have the bitset library embedded. + set = set or { } local nums = { } @@ -1840,10 +1837,10 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute +local os = os local find, format, gsub, upper = string.find, string.format, string.gsub, string.upper local random, ceil = math.random, math.ceil local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -- The following code permits traversing the environment table, at least -- in luatex. Internally all environment names are uppercase. @@ -2193,12 +2190,15 @@ if not modules then modules = { } end modules ['l-file'] = { -- needs a cleanup file = file or { } +local file = file local insert, concat = table.insert, table.concat local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char local lpegmatch = lpeg.match local getcurrentdir = lfs.currentdir +local P, R, S, C, Cs, Cp, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc + local function dirname(name,default) return match(name,"^(.+)[/\\].-$") or (default or "") end @@ -2416,11 +2416,11 @@ end -- also rewrite previous -local letter = lpeg.R("az","AZ") + lpeg.S("_-+") -local separator = lpeg.P("://") +local letter = R("az","AZ") + S("_-+") +local separator = P("://") -local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/") -local rootbased = lpeg.P("/") + letter*lpeg.P(":") +local qualified = P(".")^0 * P("/") + letter*P(":") + letter^1*separator + letter^1 * P("/") +local rootbased = P("/") + letter*P(":") -- ./name ../name /name c: :// name/name @@ -2432,14 +2432,16 @@ function file.is_rootbased_path(filename) return lpegmatch(rootbased,filename) ~= nil end -local slash = lpeg.S("\\/") -local period = lpeg.P(".") -local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":") -local path = lpeg.C(((1-slash)^0 * slash)^0) -local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1)) -local base = lpeg.C((1-suffix)^0) +-- actually these are schemes + +local slash = S("\\/") +local period = P(".") +local drive = C(R("az","AZ")) * P(":") +local path = C(((1-slash)^0 * slash)^0) +local suffix = period * C(P(1-period)^0 * P(-1)) +local base = C((1-suffix)^0) -local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) function file.splitname(str) -- returns drive, path, base, suffix return lpegmatch(pattern,str) @@ -2467,6 +2469,7 @@ if not modules then modules = { } end modules ['l-md5'] = { -- This also provides file checksums and checkers. +local md5, file = md5, file local gsub, format, byte = string.gsub, string.format, string.byte local function convert(str,fmt) @@ -2547,7 +2550,8 @@ local lpegmatch, lpegP, lpegC, lpegR, lpegS, lpegCs, lpegCc = lpeg.match, lpeg.P -- / \ / \ -- urn:example:animal:ferret:nose -url = url or { } +url = url or { } +local url = url local function tochar(s) return char(tonumber(s,16)) @@ -2687,20 +2691,30 @@ if not modules then modules = { } end modules ['l-dir'] = { local type = type local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local concat = table.concat local lpegmatch = lpeg.match +local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V + dir = dir or { } +local dir = dir +local lfs = lfs + +local attributes = lfs.attributes +local walkdir = lfs.dir +local isdir = lfs.isdir +local isfile = lfs.isfile +local mkdir = lfs.mkdir +local chdir = lfs.chdir +local currentdir = lfs.currentdir -- handy function dir.current() - return (gsub(lfs.currentdir(),"\\","/")) + return (gsub(currentdir(),"\\","/")) end --- optimizing for no string.find (*) does not save time - -local attributes = lfs.attributes -local walkdir = lfs.dir +-- optimizing for no find (*) does not save time local function glob_pattern(path,patt,recurse,action) local ok, scanner @@ -2756,8 +2770,6 @@ end dir.collect_pattern = collect_pattern -local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V - local pattern = Ct { [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3), [2] = C(((1-S("*?/"))^0 * P("/"))^0), @@ -2780,7 +2792,7 @@ local function glob(str,t) for s=1,#str do glob(str[s],t) end - elseif lfs.isfile(str) then + elseif isfile(str) then t(str) else local split = lpegmatch(pattern,str) @@ -2799,7 +2811,7 @@ local function glob(str,t) glob(str[s],t) end return t - elseif lfs.isfile(str) then + elseif isfile(str) then local t = t or { } t[#t+1] = str return t @@ -2863,13 +2875,13 @@ dir.globfiles = globfiles -- print(dir.ls("*.tex")) function dir.ls(pattern) - return table.concat(glob(pattern),"\n") + return concat(glob(pattern),"\n") end local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then -- os.type == "windows" +if find(os.getenv("PATH"),";") then -- os.type == "windows" function dir.mkdirs(...) local str, pth, t = "", "", { ... } @@ -2918,11 +2930,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" else pth = pth .. "/" .. s end - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end @@ -2937,11 +2949,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" if not first then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then - local d = lfs.currentdir() - if lfs.chdir(first) then + local d = currentdir() + if chdir(first) then first = dir.current() end - lfs.chdir(d) + chdir(d) end end if not first then @@ -2982,26 +2994,26 @@ else else pth = pth .. "/" .. s end - if make_indeed and not first and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not first and not isdir(pth) then + mkdir(pth) end end else pth = "." for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end function dir.expand_name(str) -- will be merged with cleanpath and collapsepath if not find(str,"^/") then - str = lfs.currentdir() .. "/" .. str + str = currentdir() .. "/" .. str end str = gsub(str,"//","/") str = gsub(str,"/%./","/") @@ -3025,10 +3037,11 @@ if not modules then modules = { } end modules ['l-boolean'] = { license = "see context related readme files" } -boolean = boolean or { } - local type, tonumber = type, tonumber +boolean = boolean or { } +local boolean = boolean + function boolean.tonumber(b) if b then return 1 else return 0 end end @@ -3109,6 +3122,8 @@ if not unicode then end +local unicode = unicode + utf = utf or unicode.utf8 local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub @@ -3280,7 +3295,7 @@ end function unicode.utfcodes(str) local t = { } - for k,v in string.utfvalues(str) do + for k,v in utfvalues(str) do t[#t+1] = format("0x%04X",k) end return concat(t,separator or " ") @@ -3339,7 +3354,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-utils'] = { +if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3353,13 +3368,11 @@ local gsub, format = string.gsub, string.format local concat = table.concat local type, next = type, next -if not utils then utils = { } end -if not utils.merger then utils.merger = { } end -if not utils.lua then utils.lua = { } end - -utils.report = utils.report or print +utilities = utilities or {} +utilities.merger = utilities.merger or { } +utilities.report = utilities.report or print -local merger = utils.merger +local merger = utilities.merger merger.strip_comment = true @@ -3396,9 +3409,9 @@ end local function self_load(name) local data = io.loaddata(name) or "" if data == "" then - utils.report("merge: unknown file %s",name) + utilities.report("merge: unknown file %s",name) else - utils.report("merge: inserting %s",name) + utilities.report("merge: inserting %s",name) end return data or "" end @@ -3409,10 +3422,10 @@ local function self_save(name, data) -- saves some 20K local n = #data data = gsub(data,"%-%-~[^\n\r]*[\r\n]","") - utils.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) + utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) end io.savedata(name,data) - utils.report("merge: saving %s",name) + utilities.report("merge: saving %s",name) end end @@ -3429,7 +3442,7 @@ local function self_libs(libs,list) local lib = libs[i] for j=1,#list do local pth = gsub(list[j],"\\","/") -- file.clean_path - utils.report("merge: checking library path %s",pth) + utilities.report("merge: checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then foundpath = pth @@ -3438,30 +3451,30 @@ local function self_libs(libs,list) if foundpath then break end end if foundpath then - utils.report("merge: using library path %s",foundpath) + utilities.report("merge: using library path %s",foundpath) local right, wrong = { }, { } for i=1,#libs do local lib = libs[i] local fullname = foundpath .. "/" .. lib if lfs.isfile(fullname) then - utils.report("merge: using library %s",fullname) + utilities.report("merge: using library %s",fullname) right[#right+1] = lib result[#result+1] = m_begin_closure result[#result+1] = io.loaddata(fullname,true) result[#result+1] = m_end_closure else - utils.report("merge: skipping library %s",fullname) + utilities.report("merge: skipping library %s",fullname) wrong[#wrong+1] = lib end end if #right > 0 then - utils.report("merge: used libraries: %s",concat(right," ")) + utilities.report("merge: used libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("merge: skipped libraries: %s",concat(wrong," ")) + utilities.report("merge: skipped libraries: %s",concat(wrong," ")) end else - utils.report("merge: no valid library path found") + utilities.report("merge: no valid library path found") end return concat(result, "\n\n") end @@ -3480,8 +3493,25 @@ function merger.selfclean(name) self_save(name,self_swap(self_load(name),self_nothing())) end -function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true - utils.report("lua: compiling %s into %s",luafile,lucfile) + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.lua = utilities.merger or { } +utilities.report = utilities.report or print + +function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) os.remove(lucfile) local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) if strip ~= false then @@ -3489,7 +3519,7 @@ function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=f end local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utils.report("lua: removing %s",luafile) + utilities.report("lua: removing %s",luafile) os.remove(luafile) end return done @@ -3501,7 +3531,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-aux'] = { +if not modules then modules = { } end modules ['util-prs'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3509,15 +3539,16 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } --- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end - -aux = aux or { } +utilities = utilities or {} +utilities.parsers = utilities.parsers or { } +local parsers = utilities.parsers +parsers.patterns = parsers.patterns or { } +local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg +local lpegmatch = lpeg.match local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type -local lpegmatch = lpeg.match - -local P, R, V = lpeg.P, lpeg.R, lpeg.V +local sortedhash = table.sortedhash local escape, left, right = P("\\"), P('{'), P('}') @@ -3526,23 +3557,23 @@ lpeg.patterns.balanced = P { [2] = left * V(1) * right } -local space = lpeg.P(' ') -local equal = lpeg.P("=") -local comma = lpeg.P(",") -local lbrace = lpeg.P("{") -local rbrace = lpeg.P("}") +local space = P(' ') +local equal = P("=") +local comma = P(",") +local lbrace = P("{") +local rbrace = P("}") local nobrace = 1 - (lbrace+rbrace) -local nested = lpeg.P { lbrace * (nobrace + lpeg.V(1))^0 * rbrace } +local nested = P { lbrace * (nobrace + V(1))^0 * rbrace } local spaces = space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) -local key = lpeg.C((1-equal-comma)^1) -local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C("")) +local key = C((1-equal-comma)^1) +local pattern_a = (space+comma)^0 * (key * equal * value + key * C("")) local pattern_c = (space+comma)^0 * (key * equal * value) -local key = lpeg.C((1-space-equal-comma)^1) -local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + lpeg.C(""))) +local key = C((1-space-equal-comma)^1) +local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C(""))) -- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored @@ -3556,11 +3587,11 @@ local pattern_a_s = (pattern_a/set)^1 local pattern_b_s = (pattern_b/set)^1 local pattern_c_s = (pattern_c/set)^1 -aux.settings_to_hash_pattern_a = pattern_a_s -aux.settings_to_hash_pattern_b = pattern_b_s -aux.settings_to_hash_pattern_c = pattern_c_s +parsers.patterns.settings_to_hash_a = pattern_a_s +parsers.patterns.settings_to_hash_b = pattern_b_s +parsers.patterns.settings_to_hash_c = pattern_c_s -function aux.make_settings_to_hash_pattern(set,how) +function parsers.make_settings_to_hash_pattern(set,how) if how == "strict" then return (pattern_c/set)^1 elseif how == "tolerant" then @@ -3570,7 +3601,7 @@ function aux.make_settings_to_hash_pattern(set,how) end end -function aux.settings_to_hash(str,existing) +function parsers.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_a_s,str) @@ -3580,7 +3611,7 @@ function aux.settings_to_hash(str,existing) end end -function aux.settings_to_hash_tolerant(str,existing) +function parsers.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_b_s,str) @@ -3590,7 +3621,7 @@ function aux.settings_to_hash_tolerant(str,existing) end end -function aux.settings_to_hash_strict(str,existing) +function parsers.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_c_s,str) @@ -3601,16 +3632,16 @@ function aux.settings_to_hash_strict(str,existing) end local separator = comma * space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(separator*value)^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) +local pattern = Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored -aux.settings_to_array_pattern = pattern +parsers.patterns.settings_to_array = pattern -- we could use a weak table as cache -function aux.settings_to_array(str) +function parsers.settings_to_array(str) if not str or str == "" then return { } else @@ -3622,14 +3653,14 @@ local function set(t,v) t[#t+1] = v end -local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(separator*value)^0 * lpeg.Carg(1) +local value = P(Carg(1)*value) / set +local pattern = value*(separator*value)^0 * Carg(1) -function aux.add_settings_to_array(t,str) +function parsers.add_settings_to_array(t,str) return lpegmatch(pattern,str,nil,t) end -function aux.hash_to_string(h,separator,yes,no,strict,omit) +function parsers.hash_to_string(h,separator,yes,no,strict,omit) if h then local t, s = { }, table.sortedkeys(h) omit = omit and table.tohash(omit) @@ -3658,7 +3689,7 @@ function aux.hash_to_string(h,separator,yes,no,strict,omit) end end -function aux.array_to_string(a,separator) +function parsers.array_to_string(a,separator) if a then return concat(a,separator or ",") else @@ -3666,7 +3697,7 @@ function aux.array_to_string(a,separator) end end -function aux.settings_to_set(str,t) -- tohash? +function parsers.settings_to_set(str,t) -- tohash? -- todo: lpeg -- duplicate anyway t = t or { } for s in gmatch(str,"%s*([^, ]+)") do -- space added t[s] = true @@ -3674,9 +3705,9 @@ function aux.settings_to_set(str,t) -- tohash? return t end -function aux.simple_hash_to_string(h, separator) +function parsers.simple_hash_to_string(h, separator) local t = { } - for k, v in table.sortedhash(h) do + for k, v in sortedhash(h) do if v then t[#t+1] = k end @@ -3684,43 +3715,44 @@ function aux.simple_hash_to_string(h, separator) return concat(t,separator or ",") end -local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace -local pattern = lpeg.Ct((space + value)^0) +local value = lbrace * C((nobrace + nested)^0) * rbrace +local pattern = Ct((space + value)^0) -function aux.arguments_to_table(str) +function parsers.arguments_to_table(str) return lpegmatch(pattern,str) end --- temporary here +-- temporary here (unoptimized) -function aux.getparameters(self,class,parentclass,settings) +function parsers.getparameters(self,class,parentclass,settings) local sc = self[class] if not sc then sc = table.clone(self[parent]) self[class] = sc end - aux.settings_to_hash(settings,sc) + parsers.settings_to_hash(settings,sc) end --- temporary here -local digit = lpeg.R("09") -local period = lpeg.P(".") -local zero = lpeg.P("0") -local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") -local number = digit^1 * (case_1 + case_2) -local stripper = lpeg.Cs((number + 1)^0) +end -- of closure +do -- create closure to overcome 200 locals limit -lpeg.patterns.strip_zeros = stripper +if not modules then modules = { } end modules ['util-tab'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} -function aux.strip_zeros(str) - return lpegmatch(stripper,str) -end +utilities = utilities or {} +utilities.tables = utilities.tables or { } +local tables = utilities.tables + +local concat, format, gmatch = table.concat, string.format, string.gmatch -function aux.definetable(target) -- defines undefined tables +function tables.definetable(target) -- defines undefined tables local composed, t = nil, { } for name in gmatch(target,"([^%.]+)") do if composed then @@ -3733,7 +3765,7 @@ function aux.definetable(target) -- defines undefined tables return concat(t,"\n") end -function aux.accesstable(target) +function tables.accesstable(target) local t = _G for name in gmatch(target,"([^%.]+)") do t = t[name] @@ -3742,10 +3774,48 @@ function aux.accesstable(target) end --- as we use this a lot ... +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-fmt'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or { } +utilities.formatters = utilities.formatters or { } +local formatters = utilities.formatters + +local concat, format = table.concat, string.format +local tostring, type = tostring, type +local strip = string.strip + +local P, R, Cs = lpeg.P, lpeg.R, lpeg.Cs +local lpegmatch = lpeg.match +-- temporary here -function aux.formatcolumns(result,between) +local digit = R("09") +local period = P(".") +local zero = P("0") +local trailingzeros = zero^0 * -digit -- suggested by Roberto R +local case_1 = period * trailingzeros / "" +local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number = digit^1 * (case_1 + case_2) +local stripper = Cs((number + 1)^0) + + +lpeg.patterns.strip_zeros = stripper + +function formatters.strip_zeros(str) + return lpegmatch(stripper,str) +end + +function formatters.formatcolumns(result,between) if result and #result > 0 then between = between or " " local widths, numbers = { }, { } @@ -3790,10 +3860,10 @@ function aux.formatcolumns(result,between) end end end - local template = string.strip(concat(widths)) + local template = strip(concat(widths)) for i=1,#result do local str = format(template,unpack(result[i])) - result[i] = string.strip(str) + result[i] = strip(str) end end return result @@ -3804,6 +3874,115 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util.deb'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the <anonymous> tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local format, find = string.format, string.find +local is_boolean = string.is_boolean + +utilities = utilities or { } +utilities.debugger = utilities.debugger or { } +local debugger = utilities.debugger + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end + +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '<anonymous>' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end + +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +end + + + + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['trac-inf'] = { version = 1.001, comment = "companion to trac-inf.mkiv", @@ -3820,14 +3999,13 @@ if not modules then modules = { } end modules ['trac-inf'] = { local format = string.format local clock = os.gettimeofday or os.clock -- should go in environment -local statusinfo, n, registered = { }, 0, { } - -statistics = statistics or { } +statistics = statistics or { } +local statistics = statistics statistics.enable = true statistics.threshold = 0.05 -local timers = { } +local statusinfo, n, registered, timers = { }, 0, { }, { } local function hastiming(instance) return instance and timers[instance] @@ -3995,7 +4173,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['trac-set'] = { +if not modules then modules = { } end modules ['trac-set'] = { -- might become util-set.lua version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4007,8 +4185,12 @@ local type, next, tostring = type, next, tostring local concat = table.concat local format, find, lower, gsub, simpleesc = string.format, string.find, string.lower, string.gsub, string.simpleesc local is_boolean = string.is_boolean +local settings_to_hash = utilities.parsers.settings_to_hash -setters = { } +utilities = utilities or { } +local utilities = utilities +utilities.setters = utilities.setters or { } +local setters = utilities.setters local data = { } -- maybe just local @@ -4064,7 +4246,7 @@ end local function set(t,what,newvalue) local data, done = t.data, t.done if type(what) == "string" then - what = aux.settings_to_hash(what) -- inefficient but ok + what = settings_to_hash(what) -- inefficient but ok end for w, value in next, what do if value == "" then @@ -4191,18 +4373,20 @@ end -- we could have used a bit of oo and the trackers:enable syntax but -- there is already a lot of code around using the singular tracker --- we could make this into a module +-- we could make this into a module but we also want the rest avaliable + +local enable, disable, register, list, show = setters.enable, setters.disable, setters.register, setters.list, setters.show function setters.new(name) - local t + local t -- we need to access it in t t = { data = { }, -- indexed, but also default and value fields name = name, - enable = function(...) setters.enable (t,...) end, - disable = function(...) setters.disable (t,...) end, - register = function(...) setters.register(t,...) end, - list = function(...) setters.list (t,...) end, - show = function(...) setters.show (t,...) end, + enable = function(...) enable (t,...) end, + disable = function(...) disable (t,...) end, + register = function(...) register(t,...) end, + list = function(...) list (t,...) end, + show = function(...) show (t,...) end, } data[name] = t return t @@ -4212,13 +4396,18 @@ trackers = setters.new("trackers") directives = setters.new("directives") experiments = setters.new("experiments") +local t_enable, t_disable = trackers .enable, trackers .disable +local d_enable, d_disable = directives .enable, directives .disable +local e_enable, e_disable = experiments.enable, experiments.disable + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end + if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) + d_enable(environment.engineflags.directives) end -- nice trick: we overload two of the directives related functions with variants that @@ -4232,30 +4421,24 @@ end local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) -local enable = directives.enable -local disable = directives.disable - function directives.enable(...) report("directives","enabling: %s",concat({...}," ")) - enable(...) + d_enable(...) end function directives.disable(...) report("directives","disabling: %s",concat({...}," ")) - disable(...) + d_disable(...) end -local enable = experiments.enable -local disable = experiments.disable - function experiments.enable(...) report("experiments","enabling: %s",concat({...}," ")) - enable(...) + e_enable(...) end function experiments.disable(...) report("experiments","disabling: %s",concat({...}," ")) - disable(...) + e_disable(...) end -- a useful example @@ -4264,136 +4447,20 @@ directives.register("system.nostatistics", function(v) statistics.enable = not v end) +directives.register("system.nolibraries", function(v) + libraries = nil -- we discard this tracing for security +end) + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) -end - - -end -- of closure - -do -- create closure to overcome 200 locals limit - -if not modules then modules = { } end modules ['trac-tra'] = { - version = 1.001, - comment = "companion to trac-tra.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- the <anonymous> tag is kind of generic and used for functions that are not --- bound to a variable, like node.new, node.copy etc (contrary to for instance --- node.has_attribute which is bound to a has_attribute local variable in mkiv) - -local debug = require "debug" - -local getinfo = debug.getinfo -local type, next = type, next -local format, find = string.format, string.find -local is_boolean = string.is_boolean - -debugger = debugger or { } - -local counters = { } -local names = { } - --- one - -local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end - if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' - else - -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) - end - else - return "unknown" - end -end - -function debugger.showstats(printer,threshold) - printer = printer or texio.write or print - threshold = threshold or 0 - local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end - end - grandtotal = grandtotal + count - functions = functions + 1 - end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) -end - --- two - - --- rest - -function debugger.savestats(filename,threshold) - local f = io.open(filename,'w') - if f then - debugger.showstats(function(str) f:write(str) end,threshold) - f:close() - end -end - -function debugger.enable() - debug.sethook(hook,"c") -end - -function debugger.disable() - debug.sethook() -end - -local function trace_calls(n) - debugger.enable() - luatex.register_stop_actions(function() - debugger.disable() - debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) - end) - trace_calls = function() end -end - -if directives then - directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling + d_enable(environment.engineflags.directives) end - - - - end -- of closure do -- create closure to overcome 200 locals limit @@ -4422,7 +4489,8 @@ provide an <l n='xml'/> structured file. Actually, any logging that is hooked into callbacks will be \XML\ by default.</p> --ldx]]-- -logs = logs or { } +logs = logs or { } +local logs = logs --[[ldx-- <p>This looks pretty ugly but we need to speed things up a bit.</p> @@ -4665,8 +4733,8 @@ function noplog.simple(fmt,...) -- todo: fmt,s end end -if utils then - utils.report = function(...) logs.simple(...) end +if utilities then + utilities.report = function(...) logs.simple(...) end end function logs.setprogram(newname,newbanner) @@ -4736,6 +4804,50 @@ function logs.fatal(where,...) end +function logs.obsolete(old,new) + local o = loadstring("return " .. new)() + if type(o) == "function" then + return function(...) + logs.report("system","function %s is obsolete, use %s",old,new) + loadstring(old .. "=" .. new .. " return ".. old)()(...) + end + elseif type(o) == "table" then + local t, m = { }, { } + m.__index = function(t,k) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + return o[k] + end + m.__newindex = function(t,k,v) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + o[k] = v + end + if libraries then + libraries.obsolete[old] = t -- true + end + setmetatable(t,m) + return t + end +end + +if tex.error then + + function logs.texerrormessage(...) -- for the moment we put this function here + tex.error(format(...), { }) + end + +else + + function logs.texerrormessage(...) -- for the moment we put this function here + local v = format(...) + tex.sprint(tex.ctxcatcodes,"\\errmessage{") + tex.sprint(tex.vrbcatcodes,v) + tex.print(tex.ctxcatcodes,"}") + end + +end + end -- of closure @@ -4762,7 +4874,8 @@ local trace_namespaces = false trackers.register("system.namespaces", function( local report_system = logs.new("system") -namespaces = { } +namespaces = namespaces or { } +local namespaces = namespaces local registered = { } @@ -4932,6 +5045,7 @@ local report_resolvers = logs.new("resolvers") local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find local unquote, quote = string.unquote, string.quote +local concat = table.concat -- precautions @@ -4956,6 +5070,8 @@ end -- environment environment = environment or { } +local environment = environment + environment.arguments = { } environment.files = { } environment.sortedflags = nil @@ -5078,7 +5194,7 @@ function environment.reconstruct_commandline(arg,noquote) result[#result+1] = a end end - return table.join(result," ") + return concat(result," ") else return "" end @@ -5248,6 +5364,7 @@ optimize the code.</p> --ldx]]-- xml = xml or { } +local xml = xml local concat, remove, insert = table.concat, table.remove, table.insert @@ -6453,6 +6570,8 @@ of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We will explain more about its usage in other documents.</p> --ldx]]-- +local xml = xml + local lpathcalls = 0 function xml.lpathcalls () return lpathcalls end local lpathcached = 0 function xml.lpathcached() return lpathcached end @@ -7647,6 +7766,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton local format, gsub, match = string.format, string.gsub, string.match local lpegmatch = lpeg.match +local xml = xml + --[[ldx-- <p>The following helper functions best belong to the <t>lxml-ini</t> module. Some are here because we need then in the <t>mk</t> @@ -7748,6 +7869,8 @@ local trace_manipulations = false trackers.register("lxml.manipulations", funct local report_xml = logs.new("xml") +local xml = xml + local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert @@ -8262,6 +8385,8 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } +local xml = xml + local finalizers = xml.finalizers.xml local xmlfilter = xml.filter -- we could inline this one for speed local xmltostring = xml.tostring @@ -8588,7 +8713,8 @@ local ostype, osname, ossetenv, osgetenv = os.type, os.name, os.setenv, os.geten -- we now split it over multiple files. As this file is now the -- starting point we introduce resolvers here. -resolvers = resolvers or { } +resolvers = resolvers or { } +local resolvers = resolvers -- We don't want the kpse library to kick in. Also, we want to be able to -- execute programs. Control over execution is implemented later. @@ -8812,6 +8938,8 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- As this bit of code is somewhat special it gets its own module. After -- all, when working on the main resolver code, I don't want to scroll -- past this every time. @@ -9119,6 +9247,8 @@ if not modules then modules = { } end modules ['data-env'] = { license = "see context related readme files", } +local resolvers = resolvers + local formats = { } resolvers.formats = formats local suffixes = { } resolvers.suffixes = suffixes local dangerous = { } resolvers.dangerous = dangerous @@ -9309,11 +9439,13 @@ local mkdirs, isdir = dir.mkdirs, lfs.isdir local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end) -local report_cache = logs.new("cache") - +local report_cache = logs.new("cache") local report_resolvers = logs.new("resolvers") -caches = caches or { } +local resolvers = resolvers + +caches = caches or { } +local caches = caches caches.base = caches.base or "luatex-cache" caches.more = caches.more or "context" @@ -9558,7 +9690,7 @@ function caches.savedata(filepath,filename,data,raw) end local cleanup = resolvers.boolean_variable("PURGECACHE", false) local strip = resolvers.boolean_variable("LUACSTRIP", true) - utils.lua.compile(tmaname, tmcname, cleanup, strip) + utilities.lua.compile(tmaname, tmcname, cleanup, strip) end -- moved from data-res: @@ -9620,7 +9752,7 @@ function caches.savecontent(cachename,dataname,content) if trace_locating then report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname) end - if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip + if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip if trace_locating then report_resolvers("'%s' compiled to '%s'",dataname,lucname) end @@ -9657,6 +9789,8 @@ local trace_locating = false trackers.register("resolvers.locating", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + resolvers.locators = { notfound = { nil } } -- locate databases resolvers.hashers = { notfound = { nil } } -- load databases resolvers.generators = { notfound = { nil } } -- generate databases @@ -9713,6 +9847,7 @@ if not modules then modules = { } end modules ['data-res'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local os = os local lpegP, lpegS, lpegR, lpegC, lpegCc, lpegCs, lpegCt = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns @@ -9726,10 +9861,14 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local expanded_path_from_list = resolvers.expanded_path_from_list local checked_variable = resolvers.checked_variable local split_configuration_path = resolvers.split_configuration_path +local initializesetter = utilities.setters.initialize + local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.setenv, os.getenv resolvers.cacheversion = '1.0.1' @@ -9949,7 +10088,7 @@ local function load_configuration_files() t[k] = v elseif kind == "table" then -- this operates on the table directly - setters.initialize(filename,k,v) + initializesetter(filename,k,v) -- this doesn't (maybe metatables some day) for kk, vv in next, v do -- vv = variable if vv ~= unset_variable then @@ -11122,6 +11261,8 @@ if not modules then modules = { } end modules ['data-pre'] = { local upper, lower, gsub = string.upper, string.lower, string.gsub +local resolvers = resolvers + local prefixes = { } local getenv = resolvers.getenv @@ -11235,6 +11376,8 @@ if not modules then modules = { } end modules ['data-inp'] = { license = "see context related readme files" } +local resolvers = resolvers + resolvers.finders = resolvers.finders or { } resolvers.openers = resolvers.openers or { } resolvers.loaders = resolvers.loaders or { } @@ -11256,7 +11399,7 @@ if not modules then modules = { } end modules ['data-out'] = { license = "see context related readme files" } -outputs = outputs or { } +-- not used yet @@ -11291,8 +11434,8 @@ table structures without bothering about the disk cache.</p> <p>Examples of usage can be found in the font related code.</p> --ldx]]-- -containers = containers or { } - +containers = containers or { } +local containers = containers containers.usecache = true local report_cache = logs.new("cache") @@ -11418,6 +11561,8 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- we will make a better format, maybe something xml or just text or lua resolvers.automounted = resolvers.automounted or { } @@ -11526,15 +11671,20 @@ local report_resolvers = logs.new("resolvers") -- zip:///texmf.zip?tree=/tex/texmf-local -- zip:///texmf-mine.zip?tree=/tex/texmf-projects -zip = zip or { } -zip.archives = zip.archives or { } -zip.registeredfiles = zip.registeredfiles or { } +local resolvers = resolvers + +zip = zip or { } +local zip = zip + +zip.archives = zip.archives or { } +local archives = zip.archives + +zip.registeredfiles = zip.registeredfiles or { } +local registeredfiles = zip.registeredfiles local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local locators, hashers, concatinators = resolvers.locators, resolvers.hashers, resolvers.concatinators -local archives = zip.archives - local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str @@ -11698,7 +11848,7 @@ function resolvers.usezipfile(zipname) zipname = validzip(zipname) local specification = resolvers.splitmethod(zipname) local zipfile = specification.path - if zipfile and not zip.registeredfiles[zipname] then + if zipfile and not registeredfiles[zipname] then local tree = url.query(specification.query).tree or "" local z = zip.openarchive(zipfile) if z then @@ -11709,7 +11859,7 @@ function resolvers.usezipfile(zipname) statistics.starttiming(instance) resolvers.prepend_hash('zip',zipname,zipfile) resolvers.extend_texmf_var(zipname) -- resets hashes too - zip.registeredfiles[zipname] = z + registeredfiles[zipname] = z instance.files[zipname] = resolvers.register_zip_file(z,tree or "") statistics.stoptiming(instance) elseif trace_locating then @@ -11769,6 +11919,8 @@ local unpack = unpack or table.unpack local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local done, found, notfound = { }, { }, resolvers.finders.notfound function resolvers.finders.tree(specification,filetype) @@ -11851,11 +12003,15 @@ if not modules then modules = { } end modules ['data-crl'] = { -- this one is replaced by data-sch.lua -- -curl = curl or { } - local gsub = string.gsub + +local resolvers = resolvers + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +curl = curl or { } +local curl = curl + local cached = { } function curl.fetch(protocol, name) -- todo: use socket library @@ -11925,6 +12081,8 @@ local report_resolvers = logs.new("resolvers") local gsub, insert = string.gsub, table.insert local unpack = unpack or table.unpack +local resolvers, package = resolvers, package + local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' local clibformats = { 'lib' } @@ -12079,6 +12237,8 @@ local type, next = type, next local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) +local resolvers = resolvers + local report_resolvers = logs.new("resolvers") function resolvers.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix @@ -12140,6 +12300,8 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local resolvers = resolvers + -- = << -- ? ?? -- < += @@ -12209,6 +12371,8 @@ local find, concat, upper, format = string.find, table.concat, string.upper, str resolvers.listers = resolvers.listers or { } +local resolvers = resolvers + local function tabstr(str) if type(str) == 'table' then return concat(str," | ") @@ -12258,9 +12422,15 @@ if not modules then modules = { } end modules ['luat-sta'] = { local gmatch, match = string.gmatch, string.match local type = type -states = states or { } -states.data = states.data or { } -states.hash = states.hash or { } +states = states or { } +local states = states + +states.data = states.data or { } +local data = states.data + +states.hash = states.hash or { } +local hash = states.hash + states.tag = states.tag or "" states.filename = states.filename or "" @@ -12270,7 +12440,7 @@ function states.save(filename,tag) io.savedata(filename, "-- generator : luat-sta.lua\n" .. "-- state tag : " .. tag .. "\n\n" .. - table.serialize(states.data[tag or states.tag] or {},true) + table.serialize(data[tag or states.tag] or {},true) ) end @@ -12278,11 +12448,11 @@ function states.load(filename,tag) states.filename = filename states.tag = tag or "whatever" states.filename = file.addsuffix(states.filename,'lus') - states.data[states.tag], states.hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } + data[states.tag], hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } end -function states.set_by_tag(tag,key,value,default,persistent) - local d, h = states.data[tag], states.hash[tag] +local function set_by_tag(tag,key,value,default,persistent) + local d, h = data[tag], hash[tag] if d then if type(d) == "table" then local dkey, hkey = key, key @@ -12312,17 +12482,17 @@ function states.set_by_tag(tag,key,value,default,persistent) d[dkey], h[hkey] = value, value elseif type(d) == "string" then -- weird - states.data[tag], states.hash[tag] = value, value + data[tag], hash[tag] = value, value end end end -function states.get_by_tag(tag,key,default) - local h = states.hash[tag] +local function get_by_tag(tag,key,default) + local h = hash[tag] if h and h[key] then return h[key] else - local d = states.data[tag] + local d = data[tag] if d then for k in gmatch(key,"[^%.]+") do local dk = d[k] @@ -12337,12 +12507,15 @@ function states.get_by_tag(tag,key,default) end end +states.set_by_tag = set_by_tag +states.get_by_tag = get_by_tag + function states.set(key,value,default,persistent) - states.set_by_tag(states.tag,key,value,default,persistent) + set_by_tag(states.tag,key,value,default,persistent) end function states.get(key,default) - return states.get_by_tag(states.tag,key,default) + return get_by_tag(states.tag,key,default) end @@ -12422,10 +12595,10 @@ function environment.make_format(name) local lucstubname = file.addsuffix(texbasename,"luc") -- pack libraries in stub logs.simple("creating initialization file: %s",luastubname) - utils.merger.selfcreate(usedlualibs,specificationpath,luastubname) + utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname) -- compile stub file (does not save that much as we don't use this stub at startup any more) local strip = resolvers.boolean_variable("LUACSTRIP", true) - if utils.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then + if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then logs.simple("using compiled initialization file: %s",lucstubname) usedluastub = lucstubname else @@ -12507,12 +12680,16 @@ own.libs = { -- order can be made better 'l-boolean.lua', 'l-unicode.lua', 'l-math.lua', - 'l-utils.lua', - 'l-aux.lua', + + 'util-mrg.lua', + 'util-lua.lua', + 'util-prs.lua', + 'util-tab.lua', + 'util-fmt.lua', + 'util-deb.lua', 'trac-inf.lua', 'trac-set.lua', - 'trac-tra.lua', 'trac-log.lua', 'trac-pro.lua', 'luat-env.lua', -- can come before inf (as in mkiv) @@ -12524,7 +12701,6 @@ own.libs = { -- order can be made better 'lxml-aux.lua', 'lxml-xml.lua', - 'data-ini.lua', 'data-exp.lua', 'data-env.lua', @@ -12589,6 +12765,7 @@ local function locate_libs() local filename = pth .. "/" .. lib local found = lfs.isfile(filename) if found then + package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require return pth end end @@ -13326,7 +13503,7 @@ if environment.argument("selfmerge") then runners.loadbase() local found = locate_libs() if found then - utils.merger.selfmerge(own.name,own.libs,{ found }) + utilities.merger.selfmerge(own.name,own.libs,{ found }) end elseif environment.argument("selfclean") then @@ -13334,7 +13511,7 @@ elseif environment.argument("selfclean") then -- remove embedded libraries runners.loadbase() - utils.merger.selfclean(own.name) + utilities.merger.selfclean(own.name) elseif environment.argument("selfupdate") then @@ -13599,6 +13776,7 @@ elseif false then else + runners.loadbase() runners.execute_ctx_script("mtx-base",filename) end diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 68ee3d2c1..ef6ccbfb6 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -52,6 +52,7 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } +local string = string local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower local lpegmatch = lpeg.match @@ -199,11 +200,6 @@ end string.padd = string.rpadd -function is_number(str) -- tonumber - return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1 -end - - function string:split_settings() -- no {} handling, see l-aux for lpeg variant if find(self,"=") then local t = { } @@ -547,12 +543,10 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -table.join = table.concat - +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match local getmetatable, setmetatable = getmetatable, setmetatable -local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs -- Starting with version 5.2 Lua no longer provide ipairs, which makes -- sense. As we already used the for loop and # in most places the @@ -1452,7 +1446,9 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte, find, gsub = string.byte, string.find, string.gsub +local io = io +local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format +local concat = table.concat if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1463,9 +1459,7 @@ end function io.loaddata(filename,textmode) local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- collectgarbage("step") -- sometimes makes a big difference in mem consumption local data = f:read('*all') - -- garbagecollector.check(data) f:close() return data else @@ -1477,7 +1471,7 @@ function io.savedata(filename,data,joiner) local f = io.open(filename,"wb") if f then if type(data) == "table" then - f:write(table.join(data,joiner or "")) + f:write(concat(data,joiner or "")) elseif type(data) == "function" then data(f) else @@ -1603,12 +1597,12 @@ function io.ask(question,default,options) while true do io.write(question) if options then - io.write(string.format(" [%s]",table.concat(options,"|"))) + io.write(format(" [%s]",concat(options,"|"))) end if default then - io.write(string.format(" [%s]",default)) + io.write(format(" [%s]",default)) end - io.write(string.format(" ")) + io.write(format(" ")) local answer = io.read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then @@ -1682,7 +1676,8 @@ local tostring = tostring local format, floor, insert, match = string.format, math.floor, table.insert, string.match local lpegmatch = lpeg.match -number = number or { } +number = number or { } +local number = number -- a,b,c,d,e,f = number.toset(100101) @@ -1759,6 +1754,8 @@ if not modules then modules = { } end modules ['l-set'] = { license = "see context related readme files" } +-- This will become obsolete when we have the bitset library embedded. + set = set or { } local nums = { } @@ -1840,10 +1837,10 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute +local os = os local find, format, gsub, upper = string.find, string.format, string.gsub, string.upper local random, ceil = math.random, math.ceil local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -- The following code permits traversing the environment table, at least -- in luatex. Internally all environment names are uppercase. @@ -2193,12 +2190,15 @@ if not modules then modules = { } end modules ['l-file'] = { -- needs a cleanup file = file or { } +local file = file local insert, concat = table.insert, table.concat local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char local lpegmatch = lpeg.match local getcurrentdir = lfs.currentdir +local P, R, S, C, Cs, Cp, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc + local function dirname(name,default) return match(name,"^(.+)[/\\].-$") or (default or "") end @@ -2416,11 +2416,11 @@ end -- also rewrite previous -local letter = lpeg.R("az","AZ") + lpeg.S("_-+") -local separator = lpeg.P("://") +local letter = R("az","AZ") + S("_-+") +local separator = P("://") -local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/") -local rootbased = lpeg.P("/") + letter*lpeg.P(":") +local qualified = P(".")^0 * P("/") + letter*P(":") + letter^1*separator + letter^1 * P("/") +local rootbased = P("/") + letter*P(":") -- ./name ../name /name c: :// name/name @@ -2432,14 +2432,16 @@ function file.is_rootbased_path(filename) return lpegmatch(rootbased,filename) ~= nil end -local slash = lpeg.S("\\/") -local period = lpeg.P(".") -local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":") -local path = lpeg.C(((1-slash)^0 * slash)^0) -local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1)) -local base = lpeg.C((1-suffix)^0) +-- actually these are schemes + +local slash = S("\\/") +local period = P(".") +local drive = C(R("az","AZ")) * P(":") +local path = C(((1-slash)^0 * slash)^0) +local suffix = period * C(P(1-period)^0 * P(-1)) +local base = C((1-suffix)^0) -local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) function file.splitname(str) -- returns drive, path, base, suffix return lpegmatch(pattern,str) @@ -2467,6 +2469,7 @@ if not modules then modules = { } end modules ['l-md5'] = { -- This also provides file checksums and checkers. +local md5, file = md5, file local gsub, format, byte = string.gsub, string.format, string.byte local function convert(str,fmt) @@ -2547,7 +2550,8 @@ local lpegmatch, lpegP, lpegC, lpegR, lpegS, lpegCs, lpegCc = lpeg.match, lpeg.P -- / \ / \ -- urn:example:animal:ferret:nose -url = url or { } +url = url or { } +local url = url local function tochar(s) return char(tonumber(s,16)) @@ -2687,20 +2691,30 @@ if not modules then modules = { } end modules ['l-dir'] = { local type = type local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local concat = table.concat local lpegmatch = lpeg.match +local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V + dir = dir or { } +local dir = dir +local lfs = lfs + +local attributes = lfs.attributes +local walkdir = lfs.dir +local isdir = lfs.isdir +local isfile = lfs.isfile +local mkdir = lfs.mkdir +local chdir = lfs.chdir +local currentdir = lfs.currentdir -- handy function dir.current() - return (gsub(lfs.currentdir(),"\\","/")) + return (gsub(currentdir(),"\\","/")) end --- optimizing for no string.find (*) does not save time - -local attributes = lfs.attributes -local walkdir = lfs.dir +-- optimizing for no find (*) does not save time local function glob_pattern(path,patt,recurse,action) local ok, scanner @@ -2756,8 +2770,6 @@ end dir.collect_pattern = collect_pattern -local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V - local pattern = Ct { [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3), [2] = C(((1-S("*?/"))^0 * P("/"))^0), @@ -2780,7 +2792,7 @@ local function glob(str,t) for s=1,#str do glob(str[s],t) end - elseif lfs.isfile(str) then + elseif isfile(str) then t(str) else local split = lpegmatch(pattern,str) @@ -2799,7 +2811,7 @@ local function glob(str,t) glob(str[s],t) end return t - elseif lfs.isfile(str) then + elseif isfile(str) then local t = t or { } t[#t+1] = str return t @@ -2863,13 +2875,13 @@ dir.globfiles = globfiles -- print(dir.ls("*.tex")) function dir.ls(pattern) - return table.concat(glob(pattern),"\n") + return concat(glob(pattern),"\n") end local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then -- os.type == "windows" +if find(os.getenv("PATH"),";") then -- os.type == "windows" function dir.mkdirs(...) local str, pth, t = "", "", { ... } @@ -2918,11 +2930,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" else pth = pth .. "/" .. s end - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end @@ -2937,11 +2949,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" if not first then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then - local d = lfs.currentdir() - if lfs.chdir(first) then + local d = currentdir() + if chdir(first) then first = dir.current() end - lfs.chdir(d) + chdir(d) end end if not first then @@ -2982,26 +2994,26 @@ else else pth = pth .. "/" .. s end - if make_indeed and not first and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not first and not isdir(pth) then + mkdir(pth) end end else pth = "." for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end function dir.expand_name(str) -- will be merged with cleanpath and collapsepath if not find(str,"^/") then - str = lfs.currentdir() .. "/" .. str + str = currentdir() .. "/" .. str end str = gsub(str,"//","/") str = gsub(str,"/%./","/") @@ -3025,10 +3037,11 @@ if not modules then modules = { } end modules ['l-boolean'] = { license = "see context related readme files" } -boolean = boolean or { } - local type, tonumber = type, tonumber +boolean = boolean or { } +local boolean = boolean + function boolean.tonumber(b) if b then return 1 else return 0 end end @@ -3109,6 +3122,8 @@ if not unicode then end +local unicode = unicode + utf = utf or unicode.utf8 local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub @@ -3280,7 +3295,7 @@ end function unicode.utfcodes(str) local t = { } - for k,v in string.utfvalues(str) do + for k,v in utfvalues(str) do t[#t+1] = format("0x%04X",k) end return concat(t,separator or " ") @@ -3339,7 +3354,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-utils'] = { +if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3353,13 +3368,11 @@ local gsub, format = string.gsub, string.format local concat = table.concat local type, next = type, next -if not utils then utils = { } end -if not utils.merger then utils.merger = { } end -if not utils.lua then utils.lua = { } end - -utils.report = utils.report or print +utilities = utilities or {} +utilities.merger = utilities.merger or { } +utilities.report = utilities.report or print -local merger = utils.merger +local merger = utilities.merger merger.strip_comment = true @@ -3396,9 +3409,9 @@ end local function self_load(name) local data = io.loaddata(name) or "" if data == "" then - utils.report("merge: unknown file %s",name) + utilities.report("merge: unknown file %s",name) else - utils.report("merge: inserting %s",name) + utilities.report("merge: inserting %s",name) end return data or "" end @@ -3409,10 +3422,10 @@ local function self_save(name, data) -- saves some 20K local n = #data data = gsub(data,"%-%-~[^\n\r]*[\r\n]","") - utils.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) + utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) end io.savedata(name,data) - utils.report("merge: saving %s",name) + utilities.report("merge: saving %s",name) end end @@ -3429,7 +3442,7 @@ local function self_libs(libs,list) local lib = libs[i] for j=1,#list do local pth = gsub(list[j],"\\","/") -- file.clean_path - utils.report("merge: checking library path %s",pth) + utilities.report("merge: checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then foundpath = pth @@ -3438,30 +3451,30 @@ local function self_libs(libs,list) if foundpath then break end end if foundpath then - utils.report("merge: using library path %s",foundpath) + utilities.report("merge: using library path %s",foundpath) local right, wrong = { }, { } for i=1,#libs do local lib = libs[i] local fullname = foundpath .. "/" .. lib if lfs.isfile(fullname) then - utils.report("merge: using library %s",fullname) + utilities.report("merge: using library %s",fullname) right[#right+1] = lib result[#result+1] = m_begin_closure result[#result+1] = io.loaddata(fullname,true) result[#result+1] = m_end_closure else - utils.report("merge: skipping library %s",fullname) + utilities.report("merge: skipping library %s",fullname) wrong[#wrong+1] = lib end end if #right > 0 then - utils.report("merge: used libraries: %s",concat(right," ")) + utilities.report("merge: used libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("merge: skipped libraries: %s",concat(wrong," ")) + utilities.report("merge: skipped libraries: %s",concat(wrong," ")) end else - utils.report("merge: no valid library path found") + utilities.report("merge: no valid library path found") end return concat(result, "\n\n") end @@ -3480,8 +3493,25 @@ function merger.selfclean(name) self_save(name,self_swap(self_load(name),self_nothing())) end -function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true - utils.report("lua: compiling %s into %s",luafile,lucfile) + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.lua = utilities.merger or { } +utilities.report = utilities.report or print + +function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) os.remove(lucfile) local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) if strip ~= false then @@ -3489,7 +3519,7 @@ function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=f end local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utils.report("lua: removing %s",luafile) + utilities.report("lua: removing %s",luafile) os.remove(luafile) end return done @@ -3501,7 +3531,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-aux'] = { +if not modules then modules = { } end modules ['util-prs'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -3509,15 +3539,16 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } --- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end - -aux = aux or { } +utilities = utilities or {} +utilities.parsers = utilities.parsers or { } +local parsers = utilities.parsers +parsers.patterns = parsers.patterns or { } +local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg +local lpegmatch = lpeg.match local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type -local lpegmatch = lpeg.match - -local P, R, V = lpeg.P, lpeg.R, lpeg.V +local sortedhash = table.sortedhash local escape, left, right = P("\\"), P('{'), P('}') @@ -3526,23 +3557,23 @@ lpeg.patterns.balanced = P { [2] = left * V(1) * right } -local space = lpeg.P(' ') -local equal = lpeg.P("=") -local comma = lpeg.P(",") -local lbrace = lpeg.P("{") -local rbrace = lpeg.P("}") +local space = P(' ') +local equal = P("=") +local comma = P(",") +local lbrace = P("{") +local rbrace = P("}") local nobrace = 1 - (lbrace+rbrace) -local nested = lpeg.P { lbrace * (nobrace + lpeg.V(1))^0 * rbrace } +local nested = P { lbrace * (nobrace + V(1))^0 * rbrace } local spaces = space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) -local key = lpeg.C((1-equal-comma)^1) -local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C("")) +local key = C((1-equal-comma)^1) +local pattern_a = (space+comma)^0 * (key * equal * value + key * C("")) local pattern_c = (space+comma)^0 * (key * equal * value) -local key = lpeg.C((1-space-equal-comma)^1) -local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + lpeg.C(""))) +local key = C((1-space-equal-comma)^1) +local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C(""))) -- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored @@ -3556,11 +3587,11 @@ local pattern_a_s = (pattern_a/set)^1 local pattern_b_s = (pattern_b/set)^1 local pattern_c_s = (pattern_c/set)^1 -aux.settings_to_hash_pattern_a = pattern_a_s -aux.settings_to_hash_pattern_b = pattern_b_s -aux.settings_to_hash_pattern_c = pattern_c_s +parsers.patterns.settings_to_hash_a = pattern_a_s +parsers.patterns.settings_to_hash_b = pattern_b_s +parsers.patterns.settings_to_hash_c = pattern_c_s -function aux.make_settings_to_hash_pattern(set,how) +function parsers.make_settings_to_hash_pattern(set,how) if how == "strict" then return (pattern_c/set)^1 elseif how == "tolerant" then @@ -3570,7 +3601,7 @@ function aux.make_settings_to_hash_pattern(set,how) end end -function aux.settings_to_hash(str,existing) +function parsers.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_a_s,str) @@ -3580,7 +3611,7 @@ function aux.settings_to_hash(str,existing) end end -function aux.settings_to_hash_tolerant(str,existing) +function parsers.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_b_s,str) @@ -3590,7 +3621,7 @@ function aux.settings_to_hash_tolerant(str,existing) end end -function aux.settings_to_hash_strict(str,existing) +function parsers.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } lpegmatch(pattern_c_s,str) @@ -3601,16 +3632,16 @@ function aux.settings_to_hash_strict(str,existing) end local separator = comma * space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(separator*value)^0) +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) +local pattern = Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored -aux.settings_to_array_pattern = pattern +parsers.patterns.settings_to_array = pattern -- we could use a weak table as cache -function aux.settings_to_array(str) +function parsers.settings_to_array(str) if not str or str == "" then return { } else @@ -3622,14 +3653,14 @@ local function set(t,v) t[#t+1] = v end -local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(separator*value)^0 * lpeg.Carg(1) +local value = P(Carg(1)*value) / set +local pattern = value*(separator*value)^0 * Carg(1) -function aux.add_settings_to_array(t,str) +function parsers.add_settings_to_array(t,str) return lpegmatch(pattern,str,nil,t) end -function aux.hash_to_string(h,separator,yes,no,strict,omit) +function parsers.hash_to_string(h,separator,yes,no,strict,omit) if h then local t, s = { }, table.sortedkeys(h) omit = omit and table.tohash(omit) @@ -3658,7 +3689,7 @@ function aux.hash_to_string(h,separator,yes,no,strict,omit) end end -function aux.array_to_string(a,separator) +function parsers.array_to_string(a,separator) if a then return concat(a,separator or ",") else @@ -3666,7 +3697,7 @@ function aux.array_to_string(a,separator) end end -function aux.settings_to_set(str,t) -- tohash? +function parsers.settings_to_set(str,t) -- tohash? -- todo: lpeg -- duplicate anyway t = t or { } for s in gmatch(str,"%s*([^, ]+)") do -- space added t[s] = true @@ -3674,9 +3705,9 @@ function aux.settings_to_set(str,t) -- tohash? return t end -function aux.simple_hash_to_string(h, separator) +function parsers.simple_hash_to_string(h, separator) local t = { } - for k, v in table.sortedhash(h) do + for k, v in sortedhash(h) do if v then t[#t+1] = k end @@ -3684,43 +3715,44 @@ function aux.simple_hash_to_string(h, separator) return concat(t,separator or ",") end -local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace -local pattern = lpeg.Ct((space + value)^0) +local value = lbrace * C((nobrace + nested)^0) * rbrace +local pattern = Ct((space + value)^0) -function aux.arguments_to_table(str) +function parsers.arguments_to_table(str) return lpegmatch(pattern,str) end --- temporary here +-- temporary here (unoptimized) -function aux.getparameters(self,class,parentclass,settings) +function parsers.getparameters(self,class,parentclass,settings) local sc = self[class] if not sc then sc = table.clone(self[parent]) self[class] = sc end - aux.settings_to_hash(settings,sc) + parsers.settings_to_hash(settings,sc) end --- temporary here -local digit = lpeg.R("09") -local period = lpeg.P(".") -local zero = lpeg.P("0") -local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") -local number = digit^1 * (case_1 + case_2) -local stripper = lpeg.Cs((number + 1)^0) +end -- of closure +do -- create closure to overcome 200 locals limit -lpeg.patterns.strip_zeros = stripper +if not modules then modules = { } end modules ['util-tab'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} -function aux.strip_zeros(str) - return lpegmatch(stripper,str) -end +utilities = utilities or {} +utilities.tables = utilities.tables or { } +local tables = utilities.tables + +local concat, format, gmatch = table.concat, string.format, string.gmatch -function aux.definetable(target) -- defines undefined tables +function tables.definetable(target) -- defines undefined tables local composed, t = nil, { } for name in gmatch(target,"([^%.]+)") do if composed then @@ -3733,7 +3765,7 @@ function aux.definetable(target) -- defines undefined tables return concat(t,"\n") end -function aux.accesstable(target) +function tables.accesstable(target) local t = _G for name in gmatch(target,"([^%.]+)") do t = t[name] @@ -3742,10 +3774,48 @@ function aux.accesstable(target) end --- as we use this a lot ... +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['util-fmt'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or { } +utilities.formatters = utilities.formatters or { } +local formatters = utilities.formatters + +local concat, format = table.concat, string.format +local tostring, type = tostring, type +local strip = string.strip + +local P, R, Cs = lpeg.P, lpeg.R, lpeg.Cs +local lpegmatch = lpeg.match +-- temporary here -function aux.formatcolumns(result,between) +local digit = R("09") +local period = P(".") +local zero = P("0") +local trailingzeros = zero^0 * -digit -- suggested by Roberto R +local case_1 = period * trailingzeros / "" +local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number = digit^1 * (case_1 + case_2) +local stripper = Cs((number + 1)^0) + + +lpeg.patterns.strip_zeros = stripper + +function formatters.strip_zeros(str) + return lpegmatch(stripper,str) +end + +function formatters.formatcolumns(result,between) if result and #result > 0 then between = between or " " local widths, numbers = { }, { } @@ -3790,10 +3860,10 @@ function aux.formatcolumns(result,between) end end end - local template = string.strip(concat(widths)) + local template = strip(concat(widths)) for i=1,#result do local str = format(template,unpack(result[i])) - result[i] = string.strip(str) + result[i] = strip(str) end end return result @@ -3804,6 +3874,115 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util.deb'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- the <anonymous> tag is kind of generic and used for functions that are not +-- bound to a variable, like node.new, node.copy etc (contrary to for instance +-- node.has_attribute which is bound to a has_attribute local variable in mkiv) + +local debug = require "debug" + +local getinfo = debug.getinfo +local type, next = type, next +local format, find = string.format, string.find +local is_boolean = string.is_boolean + +utilities = utilities or { } +utilities.debugger = utilities.debugger or { } +local debugger = utilities.debugger + +local counters = { } +local names = { } + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end + +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '<anonymous>' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end + +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +end + + + + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['trac-inf'] = { version = 1.001, comment = "companion to trac-inf.mkiv", @@ -3820,14 +3999,13 @@ if not modules then modules = { } end modules ['trac-inf'] = { local format = string.format local clock = os.gettimeofday or os.clock -- should go in environment -local statusinfo, n, registered = { }, 0, { } - -statistics = statistics or { } +statistics = statistics or { } +local statistics = statistics statistics.enable = true statistics.threshold = 0.05 -local timers = { } +local statusinfo, n, registered, timers = { }, 0, { }, { } local function hastiming(instance) return instance and timers[instance] @@ -3995,7 +4173,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['trac-set'] = { +if not modules then modules = { } end modules ['trac-set'] = { -- might become util-set.lua version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4007,8 +4185,12 @@ local type, next, tostring = type, next, tostring local concat = table.concat local format, find, lower, gsub, simpleesc = string.format, string.find, string.lower, string.gsub, string.simpleesc local is_boolean = string.is_boolean +local settings_to_hash = utilities.parsers.settings_to_hash -setters = { } +utilities = utilities or { } +local utilities = utilities +utilities.setters = utilities.setters or { } +local setters = utilities.setters local data = { } -- maybe just local @@ -4064,7 +4246,7 @@ end local function set(t,what,newvalue) local data, done = t.data, t.done if type(what) == "string" then - what = aux.settings_to_hash(what) -- inefficient but ok + what = settings_to_hash(what) -- inefficient but ok end for w, value in next, what do if value == "" then @@ -4191,18 +4373,20 @@ end -- we could have used a bit of oo and the trackers:enable syntax but -- there is already a lot of code around using the singular tracker --- we could make this into a module +-- we could make this into a module but we also want the rest avaliable + +local enable, disable, register, list, show = setters.enable, setters.disable, setters.register, setters.list, setters.show function setters.new(name) - local t + local t -- we need to access it in t t = { data = { }, -- indexed, but also default and value fields name = name, - enable = function(...) setters.enable (t,...) end, - disable = function(...) setters.disable (t,...) end, - register = function(...) setters.register(t,...) end, - list = function(...) setters.list (t,...) end, - show = function(...) setters.show (t,...) end, + enable = function(...) enable (t,...) end, + disable = function(...) disable (t,...) end, + register = function(...) register(t,...) end, + list = function(...) list (t,...) end, + show = function(...) show (t,...) end, } data[name] = t return t @@ -4212,13 +4396,18 @@ trackers = setters.new("trackers") directives = setters.new("directives") experiments = setters.new("experiments") +local t_enable, t_disable = trackers .enable, trackers .disable +local d_enable, d_disable = directives .enable, directives .disable +local e_enable, e_disable = experiments.enable, experiments.disable + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end + if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) + d_enable(environment.engineflags.directives) end -- nice trick: we overload two of the directives related functions with variants that @@ -4232,30 +4421,24 @@ end local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) -local enable = directives.enable -local disable = directives.disable - function directives.enable(...) report("directives","enabling: %s",concat({...}," ")) - enable(...) + d_enable(...) end function directives.disable(...) report("directives","disabling: %s",concat({...}," ")) - disable(...) + d_disable(...) end -local enable = experiments.enable -local disable = experiments.disable - function experiments.enable(...) report("experiments","enabling: %s",concat({...}," ")) - enable(...) + e_enable(...) end function experiments.disable(...) report("experiments","disabling: %s",concat({...}," ")) - disable(...) + e_disable(...) end -- a useful example @@ -4264,136 +4447,20 @@ directives.register("system.nostatistics", function(v) statistics.enable = not v end) +directives.register("system.nolibraries", function(v) + libraries = nil -- we discard this tracing for security +end) + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) -end - - -end -- of closure - -do -- create closure to overcome 200 locals limit - -if not modules then modules = { } end modules ['trac-tra'] = { - version = 1.001, - comment = "companion to trac-tra.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- the <anonymous> tag is kind of generic and used for functions that are not --- bound to a variable, like node.new, node.copy etc (contrary to for instance --- node.has_attribute which is bound to a has_attribute local variable in mkiv) - -local debug = require "debug" - -local getinfo = debug.getinfo -local type, next = type, next -local format, find = string.format, string.find -local is_boolean = string.is_boolean - -debugger = debugger or { } - -local counters = { } -local names = { } - --- one - -local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end - if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' - else - -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) - end - else - return "unknown" - end -end - -function debugger.showstats(printer,threshold) - printer = printer or texio.write or print - threshold = threshold or 0 - local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end - end - grandtotal = grandtotal + count - functions = functions + 1 - end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) -end - --- two - - --- rest - -function debugger.savestats(filename,threshold) - local f = io.open(filename,'w') - if f then - debugger.showstats(function(str) f:write(str) end,threshold) - f:close() - end -end - -function debugger.enable() - debug.sethook(hook,"c") -end - -function debugger.disable() - debug.sethook() -end - -local function trace_calls(n) - debugger.enable() - luatex.register_stop_actions(function() - debugger.disable() - debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) - end) - trace_calls = function() end -end - -if directives then - directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling + d_enable(environment.engineflags.directives) end - - - - end -- of closure do -- create closure to overcome 200 locals limit @@ -4422,7 +4489,8 @@ provide an <l n='xml'/> structured file. Actually, any logging that is hooked into callbacks will be \XML\ by default.</p> --ldx]]-- -logs = logs or { } +logs = logs or { } +local logs = logs --[[ldx-- <p>This looks pretty ugly but we need to speed things up a bit.</p> @@ -4665,8 +4733,8 @@ function noplog.simple(fmt,...) -- todo: fmt,s end end -if utils then - utils.report = function(...) logs.simple(...) end +if utilities then + utilities.report = function(...) logs.simple(...) end end function logs.setprogram(newname,newbanner) @@ -4736,6 +4804,50 @@ function logs.fatal(where,...) end +function logs.obsolete(old,new) + local o = loadstring("return " .. new)() + if type(o) == "function" then + return function(...) + logs.report("system","function %s is obsolete, use %s",old,new) + loadstring(old .. "=" .. new .. " return ".. old)()(...) + end + elseif type(o) == "table" then + local t, m = { }, { } + m.__index = function(t,k) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + return o[k] + end + m.__newindex = function(t,k,v) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + o[k] = v + end + if libraries then + libraries.obsolete[old] = t -- true + end + setmetatable(t,m) + return t + end +end + +if tex.error then + + function logs.texerrormessage(...) -- for the moment we put this function here + tex.error(format(...), { }) + end + +else + + function logs.texerrormessage(...) -- for the moment we put this function here + local v = format(...) + tex.sprint(tex.ctxcatcodes,"\\errmessage{") + tex.sprint(tex.vrbcatcodes,v) + tex.print(tex.ctxcatcodes,"}") + end + +end + end -- of closure @@ -4762,7 +4874,8 @@ local trace_namespaces = false trackers.register("system.namespaces", function( local report_system = logs.new("system") -namespaces = { } +namespaces = namespaces or { } +local namespaces = namespaces local registered = { } @@ -4932,6 +5045,7 @@ local report_resolvers = logs.new("resolvers") local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find local unquote, quote = string.unquote, string.quote +local concat = table.concat -- precautions @@ -4956,6 +5070,8 @@ end -- environment environment = environment or { } +local environment = environment + environment.arguments = { } environment.files = { } environment.sortedflags = nil @@ -5078,7 +5194,7 @@ function environment.reconstruct_commandline(arg,noquote) result[#result+1] = a end end - return table.join(result," ") + return concat(result," ") else return "" end @@ -5248,6 +5364,7 @@ optimize the code.</p> --ldx]]-- xml = xml or { } +local xml = xml local concat, remove, insert = table.concat, table.remove, table.insert @@ -6453,6 +6570,8 @@ of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We will explain more about its usage in other documents.</p> --ldx]]-- +local xml = xml + local lpathcalls = 0 function xml.lpathcalls () return lpathcalls end local lpathcached = 0 function xml.lpathcached() return lpathcached end @@ -7647,6 +7766,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton local format, gsub, match = string.format, string.gsub, string.match local lpegmatch = lpeg.match +local xml = xml + --[[ldx-- <p>The following helper functions best belong to the <t>lxml-ini</t> module. Some are here because we need then in the <t>mk</t> @@ -7748,6 +7869,8 @@ local trace_manipulations = false trackers.register("lxml.manipulations", funct local report_xml = logs.new("xml") +local xml = xml + local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert @@ -8262,6 +8385,8 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } +local xml = xml + local finalizers = xml.finalizers.xml local xmlfilter = xml.filter -- we could inline this one for speed local xmltostring = xml.tostring @@ -8588,7 +8713,8 @@ local ostype, osname, ossetenv, osgetenv = os.type, os.name, os.setenv, os.geten -- we now split it over multiple files. As this file is now the -- starting point we introduce resolvers here. -resolvers = resolvers or { } +resolvers = resolvers or { } +local resolvers = resolvers -- We don't want the kpse library to kick in. Also, we want to be able to -- execute programs. Control over execution is implemented later. @@ -8812,6 +8938,8 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- As this bit of code is somewhat special it gets its own module. After -- all, when working on the main resolver code, I don't want to scroll -- past this every time. @@ -9119,6 +9247,8 @@ if not modules then modules = { } end modules ['data-env'] = { license = "see context related readme files", } +local resolvers = resolvers + local formats = { } resolvers.formats = formats local suffixes = { } resolvers.suffixes = suffixes local dangerous = { } resolvers.dangerous = dangerous @@ -9309,11 +9439,13 @@ local mkdirs, isdir = dir.mkdirs, lfs.isdir local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end) -local report_cache = logs.new("cache") - +local report_cache = logs.new("cache") local report_resolvers = logs.new("resolvers") -caches = caches or { } +local resolvers = resolvers + +caches = caches or { } +local caches = caches caches.base = caches.base or "luatex-cache" caches.more = caches.more or "context" @@ -9558,7 +9690,7 @@ function caches.savedata(filepath,filename,data,raw) end local cleanup = resolvers.boolean_variable("PURGECACHE", false) local strip = resolvers.boolean_variable("LUACSTRIP", true) - utils.lua.compile(tmaname, tmcname, cleanup, strip) + utilities.lua.compile(tmaname, tmcname, cleanup, strip) end -- moved from data-res: @@ -9620,7 +9752,7 @@ function caches.savecontent(cachename,dataname,content) if trace_locating then report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname) end - if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip + if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip if trace_locating then report_resolvers("'%s' compiled to '%s'",dataname,lucname) end @@ -9657,6 +9789,8 @@ local trace_locating = false trackers.register("resolvers.locating", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + resolvers.locators = { notfound = { nil } } -- locate databases resolvers.hashers = { notfound = { nil } } -- load databases resolvers.generators = { notfound = { nil } } -- generate databases @@ -9713,6 +9847,7 @@ if not modules then modules = { } end modules ['data-res'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local os = os local lpegP, lpegS, lpegR, lpegC, lpegCc, lpegCs, lpegCt = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns @@ -9726,10 +9861,14 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local expanded_path_from_list = resolvers.expanded_path_from_list local checked_variable = resolvers.checked_variable local split_configuration_path = resolvers.split_configuration_path +local initializesetter = utilities.setters.initialize + local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.setenv, os.getenv resolvers.cacheversion = '1.0.1' @@ -9949,7 +10088,7 @@ local function load_configuration_files() t[k] = v elseif kind == "table" then -- this operates on the table directly - setters.initialize(filename,k,v) + initializesetter(filename,k,v) -- this doesn't (maybe metatables some day) for kk, vv in next, v do -- vv = variable if vv ~= unset_variable then @@ -11122,6 +11261,8 @@ if not modules then modules = { } end modules ['data-pre'] = { local upper, lower, gsub = string.upper, string.lower, string.gsub +local resolvers = resolvers + local prefixes = { } local getenv = resolvers.getenv @@ -11235,6 +11376,8 @@ if not modules then modules = { } end modules ['data-inp'] = { license = "see context related readme files" } +local resolvers = resolvers + resolvers.finders = resolvers.finders or { } resolvers.openers = resolvers.openers or { } resolvers.loaders = resolvers.loaders or { } @@ -11256,7 +11399,7 @@ if not modules then modules = { } end modules ['data-out'] = { license = "see context related readme files" } -outputs = outputs or { } +-- not used yet @@ -11291,8 +11434,8 @@ table structures without bothering about the disk cache.</p> <p>Examples of usage can be found in the font related code.</p> --ldx]]-- -containers = containers or { } - +containers = containers or { } +local containers = containers containers.usecache = true local report_cache = logs.new("cache") @@ -11418,6 +11561,8 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- we will make a better format, maybe something xml or just text or lua resolvers.automounted = resolvers.automounted or { } @@ -11526,15 +11671,20 @@ local report_resolvers = logs.new("resolvers") -- zip:///texmf.zip?tree=/tex/texmf-local -- zip:///texmf-mine.zip?tree=/tex/texmf-projects -zip = zip or { } -zip.archives = zip.archives or { } -zip.registeredfiles = zip.registeredfiles or { } +local resolvers = resolvers + +zip = zip or { } +local zip = zip + +zip.archives = zip.archives or { } +local archives = zip.archives + +zip.registeredfiles = zip.registeredfiles or { } +local registeredfiles = zip.registeredfiles local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local locators, hashers, concatinators = resolvers.locators, resolvers.hashers, resolvers.concatinators -local archives = zip.archives - local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str @@ -11698,7 +11848,7 @@ function resolvers.usezipfile(zipname) zipname = validzip(zipname) local specification = resolvers.splitmethod(zipname) local zipfile = specification.path - if zipfile and not zip.registeredfiles[zipname] then + if zipfile and not registeredfiles[zipname] then local tree = url.query(specification.query).tree or "" local z = zip.openarchive(zipfile) if z then @@ -11709,7 +11859,7 @@ function resolvers.usezipfile(zipname) statistics.starttiming(instance) resolvers.prepend_hash('zip',zipname,zipfile) resolvers.extend_texmf_var(zipname) -- resets hashes too - zip.registeredfiles[zipname] = z + registeredfiles[zipname] = z instance.files[zipname] = resolvers.register_zip_file(z,tree or "") statistics.stoptiming(instance) elseif trace_locating then @@ -11769,6 +11919,8 @@ local unpack = unpack or table.unpack local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local done, found, notfound = { }, { }, resolvers.finders.notfound function resolvers.finders.tree(specification,filetype) @@ -11851,11 +12003,15 @@ if not modules then modules = { } end modules ['data-crl'] = { -- this one is replaced by data-sch.lua -- -curl = curl or { } - local gsub = string.gsub + +local resolvers = resolvers + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +curl = curl or { } +local curl = curl + local cached = { } function curl.fetch(protocol, name) -- todo: use socket library @@ -11925,6 +12081,8 @@ local report_resolvers = logs.new("resolvers") local gsub, insert = string.gsub, table.insert local unpack = unpack or table.unpack +local resolvers, package = resolvers, package + local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' local clibformats = { 'lib' } @@ -12079,6 +12237,8 @@ local type, next = type, next local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) +local resolvers = resolvers + local report_resolvers = logs.new("resolvers") function resolvers.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix @@ -12140,6 +12300,8 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local resolvers = resolvers + -- = << -- ? ?? -- < += @@ -12209,6 +12371,8 @@ local find, concat, upper, format = string.find, table.concat, string.upper, str resolvers.listers = resolvers.listers or { } +local resolvers = resolvers + local function tabstr(str) if type(str) == 'table' then return concat(str," | ") @@ -12258,9 +12422,15 @@ if not modules then modules = { } end modules ['luat-sta'] = { local gmatch, match = string.gmatch, string.match local type = type -states = states or { } -states.data = states.data or { } -states.hash = states.hash or { } +states = states or { } +local states = states + +states.data = states.data or { } +local data = states.data + +states.hash = states.hash or { } +local hash = states.hash + states.tag = states.tag or "" states.filename = states.filename or "" @@ -12270,7 +12440,7 @@ function states.save(filename,tag) io.savedata(filename, "-- generator : luat-sta.lua\n" .. "-- state tag : " .. tag .. "\n\n" .. - table.serialize(states.data[tag or states.tag] or {},true) + table.serialize(data[tag or states.tag] or {},true) ) end @@ -12278,11 +12448,11 @@ function states.load(filename,tag) states.filename = filename states.tag = tag or "whatever" states.filename = file.addsuffix(states.filename,'lus') - states.data[states.tag], states.hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } + data[states.tag], hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } end -function states.set_by_tag(tag,key,value,default,persistent) - local d, h = states.data[tag], states.hash[tag] +local function set_by_tag(tag,key,value,default,persistent) + local d, h = data[tag], hash[tag] if d then if type(d) == "table" then local dkey, hkey = key, key @@ -12312,17 +12482,17 @@ function states.set_by_tag(tag,key,value,default,persistent) d[dkey], h[hkey] = value, value elseif type(d) == "string" then -- weird - states.data[tag], states.hash[tag] = value, value + data[tag], hash[tag] = value, value end end end -function states.get_by_tag(tag,key,default) - local h = states.hash[tag] +local function get_by_tag(tag,key,default) + local h = hash[tag] if h and h[key] then return h[key] else - local d = states.data[tag] + local d = data[tag] if d then for k in gmatch(key,"[^%.]+") do local dk = d[k] @@ -12337,12 +12507,15 @@ function states.get_by_tag(tag,key,default) end end +states.set_by_tag = set_by_tag +states.get_by_tag = get_by_tag + function states.set(key,value,default,persistent) - states.set_by_tag(states.tag,key,value,default,persistent) + set_by_tag(states.tag,key,value,default,persistent) end function states.get(key,default) - return states.get_by_tag(states.tag,key,default) + return get_by_tag(states.tag,key,default) end @@ -12422,10 +12595,10 @@ function environment.make_format(name) local lucstubname = file.addsuffix(texbasename,"luc") -- pack libraries in stub logs.simple("creating initialization file: %s",luastubname) - utils.merger.selfcreate(usedlualibs,specificationpath,luastubname) + utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname) -- compile stub file (does not save that much as we don't use this stub at startup any more) local strip = resolvers.boolean_variable("LUACSTRIP", true) - if utils.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then + if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then logs.simple("using compiled initialization file: %s",lucstubname) usedluastub = lucstubname else @@ -12507,12 +12680,16 @@ own.libs = { -- order can be made better 'l-boolean.lua', 'l-unicode.lua', 'l-math.lua', - 'l-utils.lua', - 'l-aux.lua', + + 'util-mrg.lua', + 'util-lua.lua', + 'util-prs.lua', + 'util-tab.lua', + 'util-fmt.lua', + 'util-deb.lua', 'trac-inf.lua', 'trac-set.lua', - 'trac-tra.lua', 'trac-log.lua', 'trac-pro.lua', 'luat-env.lua', -- can come before inf (as in mkiv) @@ -12524,7 +12701,6 @@ own.libs = { -- order can be made better 'lxml-aux.lua', 'lxml-xml.lua', - 'data-ini.lua', 'data-exp.lua', 'data-env.lua', @@ -12589,6 +12765,7 @@ local function locate_libs() local filename = pth .. "/" .. lib local found = lfs.isfile(filename) if found then + package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require return pth end end @@ -13326,7 +13503,7 @@ if environment.argument("selfmerge") then runners.loadbase() local found = locate_libs() if found then - utils.merger.selfmerge(own.name,own.libs,{ found }) + utilities.merger.selfmerge(own.name,own.libs,{ found }) end elseif environment.argument("selfclean") then @@ -13334,7 +13511,7 @@ elseif environment.argument("selfclean") then -- remove embedded libraries runners.loadbase() - utils.merger.selfclean(own.name) + utilities.merger.selfclean(own.name) elseif environment.argument("selfupdate") then @@ -13599,6 +13776,7 @@ elseif false then else + runners.loadbase() runners.execute_ctx_script("mtx-base",filename) end diff --git a/tex/context/base/anch-pgr.mkii b/tex/context/base/anch-pgr.mkii index 194f19755..cc7ae77f4 100644 --- a/tex/context/base/anch-pgr.mkii +++ b/tex/context/base/anch-pgr.mkii @@ -66,10 +66,14 @@ \def\registerpageposition#1% this one is flushed first ! {\ifpositioning\ifcase\realpageno\or - \ifdim\printpaperheight=\paperheight\else - \ifdim\printpaperwidth=\paperwidth\else + \ifdim\printpaperheight=\paperheight + \ifdim\printpaperwidth=\paperwidth + % not needed, + \else \setbox#1\hbox{\hpos\pageanchor{\box#1}}% \fi + \else + \setbox#1\ruledhbox{\hpos\pageanchor{\box#1}}% \fi \fi\fi} diff --git a/tex/context/base/anch-pgr.mkiv b/tex/context/base/anch-pgr.mkiv index 248b9ca5e..8c6065305 100644 --- a/tex/context/base/anch-pgr.mkiv +++ b/tex/context/base/anch-pgr.mkiv @@ -69,10 +69,14 @@ \def\registerpageposition#1% this one is flushed first ! {\ifpositioning\ifcase\realpageno\or - \ifdim\printpaperheight=\paperheight\else - \ifdim\printpaperwidth=\paperwidth\else + \ifdim\printpaperheight=\paperheight + \ifdim\printpaperwidth=\paperwidth + % not needed, + \else \setbox#1\hbox{\hpos\pageanchor{\box#1}}% \fi + \else + \setbox#1\ruledhbox{\hpos\pageanchor{\box#1}}% \fi \fi\fi} diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua index 8066af4ce..b83550922 100644 --- a/tex/context/base/anch-pos.lua +++ b/tex/context/base/anch-pos.lua @@ -16,32 +16,33 @@ local concat, format = table.concat, string.format local texprint, ctxcatcodes = tex.print, tex.ctxcatcodes local lpegmatch = lpeg.match -jobpositions = jobpositions or { } -jobpositions.collected = jobpositions.collected or { } -jobpositions.tobesaved = jobpositions.tobesaved or { } +local jobpositions = { + collected = { }, + tobesaved = { }, +} --- these are global since they are used often at the tex end +job.positions = jobpositions --- \the\dimexpr #2\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax --- \the\dimexpr #3\ifnum\positionanchormode=\plusone-\MPy\pageanchor\fi\relax +local tobesaved, collected = jobpositions.tobesaved, jobpositions.collected -ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global +_plib_, _ptbs_, _pcol_ = jobpositions, tobesaved, collected -- global local dx, dy = "0pt", "0pt" local function initializer() - ptbs, pcol = jobpositions.tobesaved, jobpositions.collected - local p = pcol["page:0"] -- page:1 + tobesaved, collected = jobpositions.tobesaved, jobpositions.collected -- local + _ptbs_, _pcol_ = tobesaved, collected -- global + local p = collected["page:0"] -- page:1 if p then -- to be checked ! --~ dx, dy = p[2] or "0pt", p[3] or "0pt" end end -job.register('jobpositions.collected', jobpositions.tobesaved, initializer) +job.register('job.positions.collected', jobpositions.tobesaved, initializer) function jobpositions.copy(target,source) - jobpositions.collected[target] = jobpositions.collected[source] or ptbs[source] + jobpositions.collected[target] = jobpositions.collected[source] or tobesaved[source] end function jobpositions.replace(name,...) @@ -49,19 +50,19 @@ function jobpositions.replace(name,...) end function jobpositions.doifelse(name) - commands.testcase(jobpositions.collected[name] or ptbs[name]) + commands.testcase(jobpositions.collected[name] or tobesaved[name]) end -function jobpositions.MPp(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[1]) or '0' ) end -function jobpositions.MPx(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[2]) or '0pt') end -function jobpositions.MPy(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[3]) or '0pt') end -function jobpositions.MPw(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[4]) or '0pt') end -function jobpositions.MPh(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[5]) or '0pt') end -function jobpositions.MPd(id) local jpi = pcol[id] or ptbs[id] texprint(ctxcatcodes,(jpi and jpi[6]) or '0pt') end +function jobpositions.MPp(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[1]) or '0' ) end +function jobpositions.MPx(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[2]) or '0pt') end +function jobpositions.MPy(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[3]) or '0pt') end +function jobpositions.MPw(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[4]) or '0pt') end +function jobpositions.MPh(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[5]) or '0pt') end +function jobpositions.MPd(id) local jpi = collected[id] or tobesaved[id] texprint(ctxcatcodes,(jpi and jpi[6]) or '0pt') end function jobpositions.MPx(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] local x = jpi and jpi[2] if x then texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',x,dx)) -- no space after dimexpr ! @@ -71,7 +72,7 @@ function jobpositions.MPx(id) end function jobpositions.MPy(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] local y = jpi and jpi[3] if y then texprint(ctxcatcodes,format('\\the\\dimexpr%s-%s\\relax',y,dy)) -- no space after dimexpr ! @@ -85,7 +86,7 @@ end -- can be writes and no format needed any more function jobpositions.MPxy(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,format('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy)) --~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',dy,')') @@ -95,7 +96,7 @@ function jobpositions.MPxy(id) end function jobpositions.MPll(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,format('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy)) --~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')') @@ -105,7 +106,7 @@ function jobpositions.MPll(id) end function jobpositions.MPlr(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,format('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy)) --~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'-',jpi[6],'-',dy,')') @@ -115,7 +116,7 @@ function jobpositions.MPlr(id) end function jobpositions.MPur(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,format('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy)) --~ texprint(ctxcatcodes,'(',jpi[2],'+',jpi[4],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')') @@ -125,7 +126,7 @@ function jobpositions.MPur(id) end function jobpositions.MPul(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,format('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy)) --~ texprint(ctxcatcodes,'(',jpi[2],'-',dx,',',jpi[3],'+',jpi[5],'-',dy,')') @@ -135,7 +136,7 @@ function jobpositions.MPul(id) end function jobpositions.MPpos(id) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if jpi then texprint(ctxcatcodes,concat(jpi,',',1,6)) else @@ -146,7 +147,7 @@ end local splitter = lpeg.Ct(lpeg.splitat(",")) function jobpositions.MPplus(id,n,default) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] if not jpi then texprint(ctxcatcodes,default) else @@ -160,7 +161,7 @@ function jobpositions.MPplus(id,n,default) end function jobpositions.MPrest(id,default) - local jpi = pcol[id] or ptbs[id] + local jpi = collected[id] or tobesaved[id] -- texprint(ctxcatcodes,(jpi and jpi[7] and concat(jpi,",",7,#jpi)) or default) texprint(ctxcatcodes,(jpi and jpi[7]) or default) end diff --git a/tex/context/base/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv index e454747da..ba668f6ac 100644 --- a/tex/context/base/anch-pos.mkiv +++ b/tex/context/base/anch-pos.mkiv @@ -35,7 +35,9 @@ % at some point (when we no longer share code) we will move to numbers % do that we have less garbage collection and hashing % -% the global table ptbs is equivalent to jobpositions.tobesaved +% the global table _plib_ is equivalent to job.positions +% the global table _ptbs_ is equivalent to job.positions.tobesaved +% the global table _pcol_ is equivalent to job.positions.collected % % btw, using a function is more efficient than passing longer code % snippets to ctxlua @@ -108,12 +110,12 @@ % are the next 6 still used? -\def\dolazysaveposition #1#2#3#4{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4"}}}} -\def\dolazysavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}} -\def\dolazysavepositionplus#1#2#3#4#5#6#7#8{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}} -\def\dosaveposition #1#2#3#4{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4"}}}} -\def\dosavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}} -\def\dosavepositionplus #1#2#3#4#5#6#7#8{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}} +\def\dolazysaveposition #1#2#3#4{\normalexpanded{\ctxlatelua{_ptbs_['#1']={#2,"#3","#4"}}}} +\def\dolazysavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlatelua{_ptbs_['#1']={#2,"#3","#4","#5","#6","#7"}}}} +\def\dolazysavepositionplus#1#2#3#4#5#6#7#8{\normalexpanded{\ctxlatelua{_ptbs_['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}} +\def\dosaveposition #1#2#3#4{\normalexpanded{\ctxlua {_ptbs_['#1']={#2,"#3","#4"}}}} +\def\dosavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlua {_ptbs_['#1']={#2,"#3","#4","#5","#6","#7"}}}} +\def\dosavepositionplus #1#2#3#4#5#6#7#8{\normalexpanded{\ctxlua {_ptbs_['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}} \def\lastsavedpositionx {\the\dimexpr\pdflastxpos\scaledpoint\relax} \def\lastsavedpositiony {\the\dimexpr\pdflastypos\scaledpoint\relax} @@ -121,17 +123,17 @@ \def\dosetposition#1% {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% + \normalexpanded{\ctxlatelua{_ptbs_['#1']={% \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony"}}}} \def\dosetpositionwhd#1#2#3#4% {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% + \normalexpanded{\ctxlatelua{_ptbs_['#1']={% \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4"}}}} \def\dosetpositionplus#1#2#3#4#5% {\savecurrentposition - \normalexpanded{\ctxlatelua{ptbs['#1']={% + \normalexpanded{\ctxlatelua{_ptbs_['#1']={% \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4","#5"}}}} \let\dosetpositionpapersize\gobbletwoarguments @@ -160,7 +162,7 @@ %D Sometimes we want to trick the position handler a bit: -\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{jobpositions.replace('#1',\number#2,"\the\dimexpr#3\relax","\the\dimexpr#4\relax","\the\dimexpr#5\relax","\the\dimexpr#6\relax","\the\dimexpr#7\relax")}} +\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{_plib_.replace('#1',\number#2,"\the\dimexpr#3\relax","\the\dimexpr#4\relax","\the\dimexpr#5\relax","\the\dimexpr#6\relax","\the\dimexpr#7\relax")}} %D For postprocessing purposes, we save the number of %D positions. @@ -205,18 +207,18 @@ % \the\dimexpr\noexpand\lastsavedpositionx\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax % \the\dimexpr\noexpand\lastsavedpositiony\ifnum\positionanchormode=\plusone-\MPx\pageanchor\fi\relax -\def\MPp #1{\ctxlua{jobpositions.MPp("#1")}} -\def\MPx #1{\ctxlua{jobpositions.MPx("#1")}} -\def\MPy #1{\ctxlua{jobpositions.MPy("#1")}} -\def\MPw #1{\ctxlua{jobpositions.MPw("#1")}} -\def\MPh #1{\ctxlua{jobpositions.MPh("#1")}} -\def\MPd #1{\ctxlua{jobpositions.MPd("#1")}} -\def\MPxy #1{\ctxlua{jobpositions.MPxy("#1")}} -\def\MPll #1{\ctxlua{jobpositions.MPll("#1")}} -\def\MPlr #1{\ctxlua{jobpositions.MPlr("#1")}} -\def\MPur #1{\ctxlua{jobpositions.MPur("#1")}} -\def\MPul #1{\ctxlua{jobpositions.MPul("#1")}} -\def\MPpos#1{\ctxlua{jobpositions.MPpos("#1")}} +\def\MPp #1{\ctxlua{_plib_.MPp("#1")}} +\def\MPx #1{\ctxlua{_plib_.MPx("#1")}} +\def\MPy #1{\ctxlua{_plib_.MPy("#1")}} +\def\MPw #1{\ctxlua{_plib_.MPw("#1")}} +\def\MPh #1{\ctxlua{_plib_.MPh("#1")}} +\def\MPd #1{\ctxlua{_plib_.MPd("#1")}} +\def\MPxy #1{\ctxlua{_plib_.MPxy("#1")}} +\def\MPll #1{\ctxlua{_plib_.MPll("#1")}} +\def\MPlr #1{\ctxlua{_plib_.MPlr("#1")}} +\def\MPur #1{\ctxlua{_plib_.MPur("#1")}} +\def\MPul #1{\ctxlua{_plib_.MPul("#1")}} +\def\MPpos#1{\ctxlua{_plib_.MPpos("#1")}} %D \macros %D {MPplus, MPrest, MPv, MPvv} @@ -238,8 +240,8 @@ %D %D The extra parameters are not treated. -\def\MPplus#1#2#3{\ctxlua{jobpositions.MPplus("#1",#2,"#3")}} \let\MPv \MPplus -\def\MPrest #1#2{\ctxlua{jobpositions.MPrest("#1","#2")}} \let\MPvv\MPrest +\def\MPplus#1#2#3{\ctxlua{_plib_.MPplus("#1",#2,"#3")}} \let\MPv \MPplus +\def\MPrest #1#2{\ctxlua{_plib_.MPrest("#1","#2")}} \let\MPvv\MPrest %D \macros %D {MPanchor} @@ -400,7 +402,7 @@ %D %D Again, this is a global action. -\def\copyposition#1#2{\ctxlua{jobpositions.copy('#1','#2')}} +\def\copyposition#1#2{\ctxlua{_plib_.copy('#1','#2')}} %D The fact that handling positions is a two pass operation, is %D one of the reasons why we need to be able to test for @@ -410,7 +412,7 @@ %D \doifpositionelse {identifier} {found action} {not found action} %D \stoptyping -\def\doifpositionelse#1{\ctxlua{jobpositions.doifelse('#1')}} +\def\doifpositionelse#1{\ctxlua{_plib_.doifelse('#1')}} %D We have now arrived at a few macros that would make sense as %D support macros, but ended up in the core. diff --git a/tex/context/base/attr-div.lua b/tex/context/base/attr-col.lua index 4397936d9..0f40b8b99 100644 --- a/tex/context/base/attr-div.lua +++ b/tex/context/base/attr-col.lua @@ -1,6 +1,6 @@ -if not modules then modules = { } end modules ['attr-div'] = { +if not modules then modules = { } end modules ['attr-col'] = { version = 1.001, - comment = "companion to attr-ini.mkiv", + comment = "companion to attr-col.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -10,17 +10,14 @@ if not modules then modules = { } end modules ['attr-div'] = { -- we can also do the nsnone via a metatable and then also se index 0 local type = type -local format, gmatch = string.format, string.gmatch +local format = string.format local concat = table.concat -local texsprint = tex.sprint local report_attributes = logs.new("attributes") local report_colors = logs.new("colors") local report_transparencies = logs.new("transparencies") -local report_viewerlayers = logs.new("viewerlayers") -local ctxcatcodes = tex.ctxcatcodes -local unsetvalue = attributes.unsetvalue +local attributes, nodes = attributes, nodes -- todo: document this but first reimplement this as it reflects the early -- days of luatex / mkiv and we have better ways now @@ -28,9 +25,11 @@ local unsetvalue = attributes.unsetvalue -- nb: attributes: color etc is much slower than normal (marks + literals) but ... -- nb. too many "0 g"s -nodes = nodes or { } -states = states or { } -shipouts = shipouts or { } +local states = attributes.states +local tasks = nodes.tasks +local nodeinjections = backends.nodeinjections +local registrations = backends.registrations +local unsetvalue = attributes.unsetvalue -- We can distinguish between rules and glyphs but it's not worth the trouble. A -- first implementation did that and while it saves a bit for glyphs and rules, it @@ -58,11 +57,12 @@ shipouts = shipouts or { } -- colors.strings[color] = "return colors." .. colorspace .. "(" .. concat({...},",") .. ")" -- end -- --- storage.register("colors/data", colors.strings, "colors.data") -- evaluated +-- storage.register("attributes/colors/data", colors.strings, "attributes.colors.data") -- evaluated -- -- We assume that only processcolors are defined in the format. -colors = colors or { } +attributes.colors = attributes.colors or { } +local colors = attributes.colors _clib_ = colors -- fast access (less tokens too) colors.data = colors.data or { } colors.values = colors.values or { } colors.registered = colors.registered or { } @@ -75,8 +75,8 @@ colors.main = nil colors.triggering = true colors.supported = true -storage.register("colors/values", colors.values, "colors.values") -storage.register("colors/registered", colors.registered, "colors.registered") +storage.register("attributes/colors/values", colors.values, "attributes.colors.values") +storage.register("attributes/colors/registered", colors.registered, "attributes.colors.registered") local templates = { rgb = "r:%s:%s:%s", @@ -106,10 +106,6 @@ local list = attributes.list local min, max, floor = math.min, math.max, math.floor -local nodeinjections = backends.nodeinjections -local codeinjections = backends.codeinjections -local registrations = backends.registrations - local function rgbtocmyk(r,g,b) -- we could reduce return 1-r, 1-g, 1-b, 0 end @@ -322,7 +318,7 @@ function colors.value(id) return values[id] end -shipouts.handle_color = nodes.install_attribute_handler { +attributes.colors.handler = nodes.install_attribute_handler { name = "color", namespace = colors, initializer = states.initialize, @@ -333,9 +329,9 @@ shipouts.handle_color = nodes.install_attribute_handler { function colors.enable(value) if value == false or not colors.supported then - tasks.disableaction("shipouts","shipouts.handle_color") + tasks.disableaction("shipouts","attributes.colors.handler") else - tasks.enableaction("shipouts","shipouts.handle_color") + tasks.enableaction("shipouts","attributes.colors.handler") end end @@ -347,7 +343,8 @@ end -- transparencies -transparencies = transparencies or { } +attributes.transparencies = attributes.transparencies or { } +local transparencies = attributes.transparencies _tlib_ = transparencies -- fast access (less tokens too) transparencies.registered = transparencies.registered or { } transparencies.data = transparencies.data or { } transparencies.values = transparencies.values or { } @@ -355,8 +352,8 @@ transparencies.triggering = true transparencies.attribute = attributes.private('transparency') transparencies.supported = true -storage.register("transparencies/registered", transparencies.registered, "transparencies.registered") -storage.register("transparencies/values", transparencies.values, "transparencies.values") +storage.register("attributes/transparencies/registered", transparencies.registered, "attributes.transparencies.registered") +storage.register("attributes/transparencies/values", transparencies.values, "attributes.transparencies.values") local registered = transparencies.registered -- we could use a 2 dimensional table instead local data = transparencies.data @@ -427,7 +424,7 @@ function transparencies.value(id) return values[id] end -shipouts.handle_transparency = nodes.install_attribute_handler { +attributes.transparencies.handler = nodes.install_attribute_handler { name = "transparency", namespace = transparencies, initializer = states.initialize, @@ -437,9 +434,9 @@ shipouts.handle_transparency = nodes.install_attribute_handler { function transparencies.enable(value) -- nil is enable if value == false or not transparencies.supported then - tasks.disableaction("shipouts","shipouts.handle_transparency") + tasks.disableaction("shipouts","attributes.transparencies.handler") else - tasks.enableaction("shipouts","shipouts.handle_transparency") + tasks.enableaction("shipouts","attributes.transparencies.handler") end end @@ -451,9 +448,10 @@ end --- colorintents: overprint / knockout -colorintents = colorintents or { } -colorintents.data = colorintents.data or { } -colorintents.attribute = attributes.private('colorintent') +attributes.colorintents = attributes.colorintents or {} +local colorintents = attributes.colorintents +colorintents.data = colorintents.data or { } +colorintents.attribute = attributes.private('colorintent') colorintents.registered = { overprint = 1, @@ -489,7 +487,7 @@ function colorintents.register(stamp) return registered[stamp] or registered.overprint end -shipouts.handle_colorintent = nodes.install_attribute_handler { +attributes.colorintents.handler = nodes.install_attribute_handler { name = "colorintent", namespace = colorintents, initializer = states.initialize, @@ -498,206 +496,5 @@ shipouts.handle_colorintent = nodes.install_attribute_handler { } function colorintents.enable() - tasks.enableaction("shipouts","shipouts.handle_colorintent") -end - ---- negative / positive - -negatives = negatives or { } -negatives.data = negatives.data or { } -negatives.attribute = attributes.private("negative") - -negatives.registered = { - positive = 1, - negative = 2, -} - -local data, registered = negatives.data, negatives.registered - -local function extender(negatives,key) - if key == "none" then - local d = data[1] - negatives.none = d - return d - end -end - -local function reviver(data,n) - if n == 1 then - local d = nodeinjections.positive() -- called once - data[1] = d - return d - elseif n == 2 then - local d = nodeinjections.negative() -- called once - data[2] = d - return d - end -end - -setmetatable(negatives, { __index = extender }) -setmetatable(negatives.data, { __index = reviver }) - -function negatives.register(stamp) - return registered[stamp] or registered.positive -end - -shipouts.handle_negative = nodes.install_attribute_handler { - name = "negative", - namespace = negatives, - initializer = states.initialize, - finalizer = states.finalize, - processor = states.process, -} - -function negatives.enable() - tasks.enableaction("shipouts","shipouts.handle_negative") -end - --- effects -- can be optimized (todo: metatables) - -effects = effects or { } -effects.data = effects.data or { } -effects.values = effects.values or { } -effects.registered = effects.registered or { } -effects.stamp = "%s:%s:%s" -effects.attribute = attributes.private("effect") - -storage.register("effects/registered", effects.registered, "effects.registered") -storage.register("effects/values", effects.values, "effects.values") - -local data, registered, values = effects.data, effects.registered, effects.values - --- valid effects: normal inner outer both hidden (stretch,rulethickness,effect) - -local function effect(...) effect = nodeinjections.effect return effect(...) end - -local function extender(effects,key) - if key == "none" then - local d = effect(0,0,0) - effects.none = d - return d - end -end - -local function reviver(data,n) - local e = values[n] -- we could nil values[n] now but hardly needed - local d = effect(e[1],e[2],e[3]) - data[n] = d - return d -end - -setmetatable(effects, { __index = extender }) -setmetatable(effects.data, { __index = reviver }) - -function effects.register(effect,stretch,rulethickness) - local stamp = format(effects.stamp,effect,stretch,rulethickness) - local n = registered[stamp] - if not n then - n = #values + 1 - values[n] = { effect, stretch, rulethickness } - registered[stamp] = n - end - return n -end - -shipouts.handle_effect = nodes.install_attribute_handler { - name = "effect", - namespace = effects, - initializer = states.initialize, - finalizer = states.finalize, - processor = states.process, -} - -function effects.enable() - tasks.enableaction("shipouts","shipouts.handle_effect") -end - --- layers (ugly code, due to no grouping and such); currently we use exclusive layers --- but when we need it stacked layers might show up too; the next function based --- approach can be replaced by static (metatable driven) resolvers - -viewerlayers = viewerlayers or { } -viewerlayers.data = viewerlayers.data or { } -viewerlayers.registered = viewerlayers.registered or { } -viewerlayers.values = viewerlayers.values or { } -viewerlayers.listwise = viewerlayers.listwise or { } -viewerlayers.attribute = attributes.private("viewerlayer") -viewerlayers.supported = true -viewerlayers.hasorder = true - -storage.register("viewerlayers/registered", viewerlayers.registered, "viewerlayers.registered") -storage.register("viewerlayers/values", viewerlayers.values, "viewerlayers.values") - -local data = viewerlayers.data -local values = viewerlayers.values -local listwise = viewerlayers.listwise -local registered = viewerlayers.registered -local template = "%s" - --- stacked - -local function extender(viewerlayers,key) - if viewerlayers.supported and key == "none" then - local d = nodeinjections.stoplayer() - viewerlayers.none = d - return d - end -end - -local function reviver(data,n) - if viewerlayers.supported then - local v = values[n] - if v then - local d = nodeinjections.startlayer(v) - data[n] = d - return d - else - logs.report("viewerlayers","error, unknown reference '%s'",tostring(n)) - end - end -end - -setmetatable(viewerlayers, { __index = extender }) -setmetatable(viewerlayers.data, { __index = reviver }) - -local function initializer(...) - return states.initialize(...) -end - -viewerlayers.register = function(name,lw) -- if not inimode redefine data[n] in first call - local stamp = format(template,name) - local n = registered[stamp] - if not n then - n = #values + 1 - values[n] = name - registered[stamp] = n - listwise[n] = lw or false - end - return registered[stamp] -- == n -end - -shipouts.handle_viewerlayer = nodes.install_attribute_handler { - name = "viewerlayer", - namespace = viewerlayers, - initializer = initializer, - finalizer = states.finalize, - processor = states.stacked, -} - -function viewerlayers.enable(value) - if value == false or not viewerlayers.supported then - tasks.disableaction("shipouts","shipouts.handle_viewerlayer") - else - tasks.enableaction("shipouts","shipouts.handle_viewerlayer") - end -end - -function viewerlayers.forcesupport(value) - viewerlayers.supported = value - report_viewerlayers("viewerlayers are %ssupported",value and "" or "not ") - viewerlayers.enable(value) -end - -function viewerlayers.setfeatures(hasorder) - viewerlayers.hasorder = hasorder + tasks.enableaction("shipouts","attributes.colorintents.handler") end diff --git a/tex/context/base/attr-col.mkiv b/tex/context/base/attr-col.mkiv new file mode 100644 index 000000000..5dc0e477e --- /dev/null +++ b/tex/context/base/attr-col.mkiv @@ -0,0 +1,83 @@ +%D \module +%D [ file=attr-col, +%D version=2007.06.06, +%D title=\CONTEXT\ Attribute Macros, +%D subtitle=Color, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Attribute Macros / Color} + +\registerctxluafile{attr-col}{1.001} + +\unprotect + +% todo: no need for 'color' argument, we can set that once at startup; currently +% a bit inconsistent + +% 1=off 2=gray 3=spot 4=rgb 5=cmyk 6=cmy % only 1/2/4/5 are supported +% +% We could combine this in one attribute but this is not faster and also +% less flexible because sometimes we want to freeze the attribute bit. +% +% Watch out: real color support will be implemented later. + +\newcount\currentcolormodel + +\def\dosetcolormodel#1% + {\currentcolormodel\ctxlua{tex.print(_clib_.setmodel('#1'))}% + \attribute\colormodelattribute\currentcolormodel} + +\dosetcolormodel{all} + +\appendtoks + \dosetcolormodel{all}% redundant? +\to \everyjob + +\def\registerrgbcolor #1#2#3#4{\ctxlua{_clib_.register('#1','rgb' ,#2,#3,#4)}} +\def\registercmykcolor#1#2#3#4#5{\ctxlua{_clib_.register('#1','cmyk',#2,#3,#4,#5)}} +\def\registergraycolor #1#2{\ctxlua{_clib_.register('#1','gray',#2)}} + +% transparency + +\def\registertransparency#1#2#3% + {\setevalue{(ts:#1)}{\attribute\transparencyattribute\ctxlua{tex.write(_tlib_.register(#2,#3))} }} + +\def\sometransparencyswitch#1{\csname(ts:#1)\endcsname} + +\def\sometransparencyswitch + {\ctxlua{_tlib_.enable()}% + \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% + \sometransparencyswitch} + +% \registertransparency {one} {1} {.5} +% \registertransparency {two} {1} {.6} + +% overprint + +\def\registercolorintent#1#2% + {\setevalue{(os:#1)}{\attribute\colorintentattribute\ctxlua{tex.write(attributes.colorintents.register('#2'))} }} + +\def\dotriggercolorintent + {\ctxlua{attributes.colorintents.enable()}% + \gdef\dotriggercolorintent##1{\csname(os:##1)\endcsname}% + \dotriggercolorintent} + +\registercolorintent{knockout} {knockout} +\registercolorintent{overprint}{overprint} + +\installattributestack\colorintentattribute + +\setevalue{(os:#\v!none}{\attribute\colorintentattribute\attributeunsetvalue} % does this work out ok? + +\protect \endinput + +% test case +% +% {\green \hbox to \hsize{\leaders\hrule \hfill a}\par} +% {\red \hbox to \hsize{\leaders\hbox{x}\hfill a}\par} diff --git a/tex/context/base/attr-div.mkiv b/tex/context/base/attr-div.mkiv deleted file mode 100644 index dea223da0..000000000 --- a/tex/context/base/attr-div.mkiv +++ /dev/null @@ -1,136 +0,0 @@ -%D \module -%D [ file=attr-div, -%D version=2007.06.06, -%D title=\CONTEXT\ Attribute Macros, -%D subtitle=Diverse, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA-ADE] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Attribute Macros / Diverse} - -%D This code will mnve. - -\unprotect - -\registerctxluafile{attr-div}{1.001} - -% \definesystemattribute[ignore] -% -% \edef\startignorecontent{\dosetattribute{ignore}\plusone} -% \edef\stopignorecontent {\doresetattribute{ignore}} - -% todo: no need for 'color' argument, we can set that once at startup; currently -% a bit inconsistent - -% 1=off 2=gray 3=spot 4=rgb 5=cmyk 6=cmy % only 1/2/4/5 are supported -% -% We could combine this in one attribute but this is not faster and also -% less flexible because sometimes we want to freeze the attribute bit. -% -% Watch out: real color support will be implemented later. - -\newcount\currentcolormodel - -\def\dosetcolormodel#1% - {\currentcolormodel\ctxlua{tex.print(colors.setmodel('#1'))}% - \attribute\colormodelattribute\currentcolormodel} - -\dosetcolormodel{all} - -\appendtoks - \dosetcolormodel{all}% redundant? -\to \everyjob - -\def\registerrgbcolor #1#2#3#4{\ctxlua{colors.register('#1','rgb' ,#2,#3,#4)}} -\def\registercmykcolor#1#2#3#4#5{\ctxlua{colors.register('#1','cmyk',#2,#3,#4,#5)}} -\def\registergraycolor #1#2{\ctxlua{colors.register('#1','gray',#2)}} - -% transparency - -\def\registertransparency#1#2#3% - {\setevalue{(ts:#1)}{\attribute\transparencyattribute\ctxlua{tex.write(transparencies.register(#2,#3))} }} - -\def\sometransparencyswitch#1{\csname(ts:#1)\endcsname} - -\def\sometransparencyswitch - {\ctxlua{transparencies.enable()}% - \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% - \sometransparencyswitch} - -% \registertransparency {one} {1} {.5} -% \registertransparency {two} {1} {.6} - -% overprint - -\def\registercolorintent#1#2% - {\setevalue{(os:#1)}{\attribute\colorintentattribute\ctxlua{tex.write(colorintents.register('#2'))} }} - -\def\dotriggercolorintent - {\ctxlua{colorintents.enable()}% - \gdef\dotriggercolorintent##1{\csname(os:##1)\endcsname}% - \dotriggercolorintent} - -\registercolorintent{knockout} {knockout} -\registercolorintent{overprint}{overprint} - -\installattributestack\colorintentattribute - -\setevalue{(os:#\v!none}{\attribute\colorintentattribute\attributeunsetvalue} % does this work out ok? - -% negative - -\def\registernegative#1#2% - {\setevalue{(ns:#1)}{\attribute\negativeattribute\ctxlua{tex.write(negatives.register('#2'))} }} - -\def\dotriggernegative - {\ctxlua{negatives.enable()}% - \gdef\dotriggernegative##1{\csname(ns:##1)\endcsname}% - \dotriggernegative} - -\registernegative{positive}{positive} -\registernegative{negative}{negative} - -% effect - -\def\registereffect#1#2#3% #2=stretch #3=rulethickness - {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}% - {\attribute\effectattribute\ctxlua{tex.write(effects.register('#1',#2,\number\dimexpr#3\relax))} }} - -\def\dotriggereffect - {\ctxlua{effects.enable()}% - \gdef\dotriggereffect##1##2##3% - {\ifcsname(es:##1:##2:\number\dimexpr##3\relax)\endcsname\else\registereffect{##1}{##2}{##3}\fi - \csname(es:##1:##2:\number\dimexpr##3\relax)\endcsname}% - \dotriggereffect} - -% \registereffect{normal} -% \registereffect{inner} -% \registereffect{outer} -% \registereffect{both} -% \registereffect{hidden} - -% viewerlayers (will probably change a bit) - -% needs to work over stopitemize grouping etc - -\def\registerviewerlayer#1#2% global ! - {\setxvalue{(vl:#1)}{\global\attribute\viewerlayerattribute\ctxlua{tex.write(viewerlayers.register('#2'))} }} - -\setevalue{(vl:)}{\global\attribute\viewerlayerattribute\attributeunsetvalue} - -\def\dotriggerviewerlayer - {\ctxlua{viewerlayers.enable()}% - \gdef\dotriggerviewerlayer##1{\csname(vl:##1)\endcsname}% - \dotriggerviewerlayer} - -\protect \endinput - -% test case -% -% {\green \hbox to \hsize{\leaders\hrule \hfill a}\par} -% {\red \hbox to \hsize{\leaders\hbox{x}\hfill a}\par} diff --git a/tex/context/base/attr-eff.lua b/tex/context/base/attr-eff.lua new file mode 100644 index 000000000..2dba1b459 --- /dev/null +++ b/tex/context/base/attr-eff.lua @@ -0,0 +1,73 @@ +if not modules then modules = { } end modules ['attr-eff'] = { + version = 1.001, + comment = "companion to attr-eff.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format + +local attributes, nodes = attributes, nodes + +local states = attributes.states +local tasks = nodes.tasks +local nodeinjections = backends.nodeinjections + +attributes.effects = attributes.effects or { } +local effects = attributes.effects +effects.data = effects.data or { } +effects.values = effects.values or { } +effects.registered = effects.registered or { } +effects.stamp = "%s:%s:%s" +effects.attribute = attributes.private("effect") + +storage.register("attributes/effects/registered", effects.registered, "attributes.effects.registered") +storage.register("attributes/effects/values", effects.values, "attributes.effects.values") + +local data, registered, values = effects.data, effects.registered, effects.values + +-- valid effects: normal inner outer both hidden (stretch,rulethickness,effect) + +local function effect(...) effect = nodeinjections.effect return effect(...) end + +local function extender(effects,key) + if key == "none" then + local d = effect(0,0,0) + effects.none = d + return d + end +end + +local function reviver(data,n) + local e = values[n] -- we could nil values[n] now but hardly needed + local d = effect(e[1],e[2],e[3]) + data[n] = d + return d +end + +setmetatable(effects, { __index = extender }) +setmetatable(effects.data, { __index = reviver }) + +function effects.register(effect,stretch,rulethickness) + local stamp = format(effects.stamp,effect,stretch,rulethickness) + local n = registered[stamp] + if not n then + n = #values + 1 + values[n] = { effect, stretch, rulethickness } + registered[stamp] = n + end + return n +end + +attributes.effects.handler = nodes.install_attribute_handler { + name = "effect", + namespace = effects, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function effects.enable() + tasks.enableaction("shipouts","attributes.effects.handler") +end diff --git a/tex/context/base/attr-eff.mkiv b/tex/context/base/attr-eff.mkiv new file mode 100644 index 000000000..f4b05a14e --- /dev/null +++ b/tex/context/base/attr-eff.mkiv @@ -0,0 +1,37 @@ +%D \module +%D [ file=attr-eff, +%D version=2007.06.06, +%D title=\CONTEXT\ Attribute Macros, +%D subtitle=Effects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Attribute Macros / Effects} + +\registerctxluafile{attr-eff}{1.001} + +\unprotect + +\def\registereffect#1#2#3% #2=stretch #3=rulethickness + {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}% + {\attribute\effectattribute\ctxlua{tex.write(attributes.effects.register('#1',#2,\number\dimexpr#3\relax))}\relax}} + +\def\dotriggereffect + {\ctxlua{attributes.effects.enable()}% + \gdef\dotriggereffect##1##2##3% + {\ifcsname(es:##1:##2:\number\dimexpr##3\relax)\endcsname\else\registereffect{##1}{##2}{##3}\fi + \csname(es:##1:##2:\number\dimexpr##3\relax)\endcsname}% + \dotriggereffect} + +% \registereffect{normal} +% \registereffect{inner} +% \registereffect{outer} +% \registereffect{both} +% \registereffect{hidden} + +\protect \endinput diff --git a/tex/context/base/attr-ini.lua b/tex/context/base/attr-ini.lua index 27d7fdd90..2a1879c9a 100644 --- a/tex/context/base/attr-ini.lua +++ b/tex/context/base/attr-ini.lua @@ -15,17 +15,21 @@ symbolic names later on.</p> attributes = attributes or { } -attributes.names = attributes.names or { } -attributes.numbers = attributes.numbers or { } -attributes.list = attributes.list or { } -attributes.unsetvalue = -0x7FFFFFFF +local attributes, nodes = attributes, nodes -storage.register("attributes/names", attributes.names, "attributes.names") -storage.register("attributes/numbers", attributes.numbers, "attributes.numbers") -storage.register("attributes/list", attributes.list, "attributes.list") +attributes.names = attributes.names or { } +attributes.numbers = attributes.numbers or { } +attributes.list = attributes.list or { } +attributes.states = attributes.states or { } +attributes.handlers = attributes.handlers or { } +attributes.unsetvalue = -0x7FFFFFFF local names, numbers, list = attributes.names, attributes.numbers, attributes.list +storage.register("attributes/names", names, "attributes.names") +storage.register("attributes/numbers", numbers, "attributes.numbers") +storage.register("attributes/list", list, "attributes.list") + function attributes.define(name,number) -- at the tex end if not numbers[name] then numbers[name], names[number], list[number] = number, name, { } diff --git a/tex/context/base/attr-lay.lua b/tex/context/base/attr-lay.lua new file mode 100644 index 000000000..80e54df77 --- /dev/null +++ b/tex/context/base/attr-lay.lua @@ -0,0 +1,118 @@ +if not modules then modules = { } end modules ['attr-lay'] = { + version = 1.001, + comment = "companion to attr-lay.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- layers (ugly code, due to no grouping and such); currently we use exclusive layers +-- but when we need it stacked layers might show up too; the next function based +-- approach can be replaced by static (metatable driven) resolvers + +local type = type +local format = string.format + +local report_viewerlayers = logs.new("viewerlayers") + +-- todo: document this but first reimplement this as it reflects the early +-- days of luatex / mkiv and we have better ways now + +-- nb: attributes: color etc is much slower than normal (marks + literals) but ... +-- nb. too many "0 g"s + +local attributes, nodes = attributes, nodes + +attributes.viewerlayers = attributes.viewerlayers or { } + +local viewerlayers = attributes.viewerlayers + +viewerlayers = viewerlayers or { } +viewerlayers.data = viewerlayers.data or { } +viewerlayers.registered = viewerlayers.registered or { } +viewerlayers.values = viewerlayers.values or { } +viewerlayers.listwise = viewerlayers.listwise or { } +viewerlayers.attribute = attributes.private("viewerlayer") +viewerlayers.supported = true +viewerlayers.hasorder = true + +local states = attributes.states +local tasks = nodes.tasks +local nodeinjections = backends.nodeinjections + +storage.register("attributes/viewerlayers/registered", viewerlayers.registered, "attributes.viewerlayers.registered") +storage.register("attributes/viewerlayers/values", viewerlayers.values, "attributes.viewerlayers.values") + +local data = viewerlayers.data +local values = viewerlayers.values +local listwise = viewerlayers.listwise +local registered = viewerlayers.registered +local template = "%s" + +-- stacked + +local function extender(viewerlayers,key) + if viewerlayers.supported and key == "none" then + local d = nodeinjections.stoplayer() + viewerlayers.none = d + return d + end +end + +local function reviver(data,n) + if viewerlayers.supported then + local v = values[n] + if v then + local d = nodeinjections.startlayer(v) + data[n] = d + return d + else + logs.report("viewerlayers","error, unknown reference '%s'",tostring(n)) + end + end +end + +setmetatable(viewerlayers, { __index = extender }) +setmetatable(viewerlayers.data, { __index = reviver }) + +local function initializer(...) + return states.initialize(...) +end + +viewerlayers.register = function(name,lw) -- if not inimode redefine data[n] in first call + local stamp = format(template,name) + local n = registered[stamp] + if not n then + n = #values + 1 + values[n] = name + registered[stamp] = n + listwise[n] = lw or false + end + return registered[stamp] -- == n +end + +attributes.viewerlayers.handler = nodes.install_attribute_handler { + name = "viewerlayer", + namespace = viewerlayers, + initializer = initializer, + finalizer = states.finalize, + processor = states.stacked, +} + +function viewerlayers.enable(value) + if value == false or not viewerlayers.supported then + tasks.disableaction("shipouts","attributes.viewerlayers.handler") + else + tasks.enableaction("shipouts","attributes.viewerlayers.handler") + end +end + +function viewerlayers.forcesupport(value) + viewerlayers.supported = value + report_viewerlayers("viewerlayers are %ssupported",value and "" or "not ") + viewerlayers.enable(value) +end + +function viewerlayers.setfeatures(hasorder) + viewerlayers.hasorder = hasorder +end diff --git a/tex/context/base/attr-lay.mkiv b/tex/context/base/attr-lay.mkiv new file mode 100644 index 000000000..42a628f03 --- /dev/null +++ b/tex/context/base/attr-lay.mkiv @@ -0,0 +1,32 @@ +%D \module +%D [ file=attr-lay, +%D version=2007.06.06, +%D title=\CONTEXT\ Attribute Macros, +%D subtitle=Viewerlayers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Attribute Macros / Viewerlayers} + +\unprotect + +\registerctxluafile{attr-lay}{1.001} + +% needs to work over stopitemize grouping etc + +\def\registerviewerlayer#1#2% global ! + {\setxvalue{(vl:#1)}{\global\attribute\viewerlayerattribute\ctxlua{tex.write(attributes.viewerlayers.register('#2'))} }} + +\setevalue{(vl:)}{\global\attribute\viewerlayerattribute\attributeunsetvalue} + +\def\dotriggerviewerlayer % move to lua + {\ctxlua{attributes.viewerlayers.enable()}% + \gdef\dotriggerviewerlayer##1{\csname(vl:##1)\endcsname}% + \dotriggerviewerlayer} + +\protect \endinput diff --git a/tex/context/base/attr-neg.lua b/tex/context/base/attr-neg.lua new file mode 100644 index 000000000..ab62fbab5 --- /dev/null +++ b/tex/context/base/attr-neg.lua @@ -0,0 +1,71 @@ +if not modules then modules = { } end modules ['attr-neg'] = { + version = 1.001, + comment = "companion to attr-neg.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this module is being reconstructed and code will move to other places +-- we can also do the nsnone via a metatable and then also se index 0 + +local format = string.format + +local attributes, nodes = attributes, nodes + +local states = attributes.states +local tasks = nodes.tasks +local nodeinjections = backends.nodeinjections + +--- negative / positive + +attributes.negatives = attributes.negatives or { } +local negatives = attributes.negatives +negatives.data = negatives.data or { } +negatives.attribute = attributes.private("negative") + +negatives.registered = { + positive = 1, + negative = 2, +} + +local data, registered = negatives.data, negatives.registered + +local function extender(negatives,key) + if key == "none" then + local d = data[1] + negatives.none = d + return d + end +end + +local function reviver(data,n) + if n == 1 then + local d = nodeinjections.positive() -- called once + data[1] = d + return d + elseif n == 2 then + local d = nodeinjections.negative() -- called once + data[2] = d + return d + end +end + +setmetatable(negatives, { __index = extender }) +setmetatable(negatives.data, { __index = reviver }) + +function negatives.register(stamp) + return registered[stamp] or registered.positive +end + +attributes.negatives.handler = nodes.install_attribute_handler { + name = "negative", + namespace = negatives, + initializer = states.initialize, + finalizer = states.finalize, + processor = states.process, +} + +function negatives.enable() + tasks.enableaction("shipouts","attributes.negatives.handler") +end diff --git a/tex/context/base/attr-neg.mkiv b/tex/context/base/attr-neg.mkiv new file mode 100644 index 000000000..20a1489c3 --- /dev/null +++ b/tex/context/base/attr-neg.mkiv @@ -0,0 +1,31 @@ +%D \module +%D [ file=attr-neg, +%D version=2007.06.06, +%D title=\CONTEXT\ Attribute Macros, +%D subtitle=Negation, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA-ADE] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Attribute Macros / Negation} + +\registerctxluafile{attr-neg}{1.001} + +\unprotect + +\def\registernegative#1#2% + {\setevalue{(ns:#1)}{\attribute\negativeattribute\ctxlua{tex.write(attributes.negatives.register('#2'))}\relax}} + +\def\dotriggernegative + {\ctxlua{attributes.negatives.enable()}% + \gdef\dotriggernegative##1{\csname(ns:##1)\endcsname}% + \dotriggernegative} + +\registernegative{positive}{positive} +\registernegative{negative}{negative} + +\protect \endinput diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua index 7331758ac..b50699d15 100644 --- a/tex/context/base/back-ini.lua +++ b/tex/context/base/back-ini.lua @@ -6,27 +6,37 @@ if not modules then modules = { } end modules ['back-ini'] = { license = "see context related readme files" } -backends = backends or { } +-- I need to check what is actually needed, maybe some can become +-- locals. -local trace_backend = false +backends = backends or { } +local backends = backends -local function nothing() return nil end +local trace_backend = false trackers.register("backend.initializers", function(v) trace_finalizers = v end) local report_backends = logs.new("backends") +local function nothing() return nil end + backends.nothing = nothing backends.nodeinjections = { + rgbcolor = nothing, cmykcolor = nothing, graycolor = nothing, spotcolor = nothing, + transparency = nothing, + overprint = nothing, knockout = nothing, + positive = nothing, negative = nothing, + effect = nothing, + startlayer = nothing, stoplayer = nothing, switchlayer = nothing, @@ -36,82 +46,107 @@ backends.nodeinjections = { addtags = nothing, + insertu3d = nothing, + insertswf = nothing, + insertmovie = nothing, + insertsound = nothing, + } backends.codeinjections = { - prerollreference = nothing, - - insertmovie = nothing, - insertsound = nothing, - - presetsymbollist = nothing, - registersymbol = nothing, - registeredsymbol = nothing, - - registercomment = nothing, - embedfile = nothing, - attachfile = nothing, - adddocumentinfo = nothing, - setupidentity = nothing, - setpagetransition = nothing, - defineviewerlayer = nothing, - addbookmarks = nothing, - addtransparencygroup = nothing, - - typesetfield = nothing, - doiffieldelse = nothing, - doiffieldgroupelse = nothing, - definefield = nothing, - clonefield = nothing, - definefieldset = nothing, - getfieldgroup = nothing, - setformsmethod = nothing, - getdefaultfieldvalue = nothing, - - setupcanvas = nothing, - - initializepage = nothing, - initializedocument = nothing, - finalizepage = nothing, - finalizedocument = nothing, - - flushpageactions = nothing, - flushdocumentactions = nothing, - - insertrenderingwindow = nothing, - processrendering = nothing, - kindofrendering = nothing, - flushrenderingwindow = nothing, - - setfigurecolorspace = nothing, - setfigurealternative = nothing, - - enabletags = nothing, - maptag = nothing, - mapping = nothing, -- returns table - - mergereferences = nothing, - mergelayers = nothing, - - setformat = nothing, - getformatoption = nothing, + prerollreference = nothing, + + presetsymbol = nothing, + presetsymbollist = nothing, + registersymbol = nothing, + registeredsymbol = nothing, + + registercomment = nothing, + + embedfile = nothing, + attachfile = nothing, + attachmentid = nothing, + + adddocumentinfo = nothing, + setupidentity = nothing, + setupcanvas = nothing, + + setpagetransition = nothing, + + defineviewerlayer = nothing, + + addbookmarks = nothing, + + addtransparencygroup = nothing, + + typesetfield = nothing, + doiffieldelse = nothing, + doiffieldgroupelse = nothing, + doiffieldsetelse = nothing, + definefield = nothing, + clonefield = nothing, + definefieldset = nothing, + setfieldcalculationset = nothing, + getfieldgroup = nothing, + getfieldset = nothing, + setformsmethod = nothing, + getdefaultfieldvalue = nothing, + + flushpageactions = nothing, + flushdocumentactions = nothing, + + insertrenderingwindow = nothing, + processrendering = nothing, + + setfigurecolorspace = nothing, + setfigurealternative = nothing, + + enabletags = nothing, + maptag = nothing, + mapping = nothing, -- returns table + + mergereferences = nothing, + mergeviewerlayers = nothing, + + setformat = nothing, + getformatoption = nothing, + supportedformats = nothing, + + -- called in tex + + finalizepage = nothing -- will go when we have a hook at the lua end + } backends.registrations = { + grayspotcolor = nothing, rgbspotcolor = nothing, cmykspotcolor = nothing, + grayindexcolor = nothing, rgbindexcolor = nothing, cmykindexcolor = nothing, + spotcolorname = nothing, + transparency = nothing, + } -local nodeinjections = backends.nodeinjections -local codeinjections = backends.codeinjections -local registrations = backends.registrations +local comment = { "comment", "" } + +backends.tables = { + vfspecials = { + red = comment, + green = comment, + blue = comment, + black = comment, + startslant = comment, + stopslant = comment, + } +} backends.current = "unknown" @@ -123,10 +158,10 @@ function backends.install(what) report_backends("initializing backend %s (%s)",what,backend.comment or "no comment") end backends.current = what - for _, category in next, { "nodeinjections", "codeinjections", "registrations"} do + for _, category in next, { "nodeinjections", "codeinjections", "registrations", "tables" } do local plugin = backend[category] + local whereto = backends[category] if plugin then - local whereto = backends[category] for name, meaning in next, whereto do if plugin[name] then whereto[name] = plugin[name] @@ -138,8 +173,18 @@ function backends.install(what) elseif trace_backend then report_backends("no category %s in %s",category,what) end + -- extra checks + for k, v in next, whereto do + if not plugin[k] then + report_backends("entry %s in %s is not set",k,category) + end + end + for k, v in next, plugin do + if not whereto[k] then + report_backends("entry %s in %s is not used",k,category) + end + end end - backends.helpers = backend.helpers elseif trace_backend then report_backends("no backend named %s",what) end diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua index d43bdb701..ece325729 100644 --- a/tex/context/base/back-pdf.lua +++ b/tex/context/base/back-pdf.lua @@ -23,13 +23,17 @@ local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes -local copy_node = node.copy +local backends, lpdf, nodes, node = backends, lpdf, nodes, node -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections -local registrations = backends.pdf.registrations +local copy_node = node.copy -local pdfliteral, register = nodes.pdfliteral, nodes.register +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local nodepool = nodes.pool + +local register = nodepool.register local pdfconstant = lpdf.constant local pdfstring = lpdf.string @@ -40,7 +44,8 @@ local pdfverbose = lpdf.verbose local pdfflushobject = lpdf.flushobject local pdfimmediateobject = lpdf.immediateobject -local pdfannotation_node = nodes.pdfannotation +local pdfliteral = nodepool.pdfliteral +local pdfannotation_node = nodepool.pdfannotation function nodeinjections.rgbcolor(r,g,b) return register(pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))) @@ -111,7 +116,7 @@ end -- code -function codeinjections.insertmovie(specification) +function nodeinjections.insertmovie(specification) -- managed in figure inclusion: width, height, factor, repeat, controls, preview, label, foundname local width = specification.width local height = specification.height @@ -135,9 +140,9 @@ function codeinjections.insertmovie(specification) node.write(pdfannotation_node(width,height,0,action())) end -function codeinjections.insertsound(specification) +function nodeinjections.insertsound(specification) -- rmanaged in interaction: repeat, label, foundname - local soundclip = interactions.soundclip(specification.label) + local soundclip = interactions.soundclips.soundclip(specification.label) if soundclip then local controldict = pdfdictionary { Mode = (specification["repeat"] and pdfconstant("Repeat")) or nil @@ -461,13 +466,4 @@ function codeinjections.setfigurealternative(data,figure) end end --- eventually we need to load this runtime --- --- backends.install((environment and environment.arguments and environment.arguments.backend) or "pdf") --- --- but now we need to force this as we also load the pdf tex part which hooks into all kind of places - -codeinjections.finalizepage = lpdf.finalizepage -codeinjections.finalizedocument = lpdf.finalizedocument - backends.install("pdf") diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv index 3cae2afd2..1a901133d 100644 --- a/tex/context/base/back-pdf.mkiv +++ b/tex/context/base/back-pdf.mkiv @@ -13,7 +13,24 @@ \writestatus{loading}{ConTeXt Backend Macros / PDF} -\registerctxluafile{back-pdf}{1.001} % this will change +\registerctxluafile{lpdf-ini}{1.001} +\registerctxluafile{lpdf-col}{1.000} +\registerctxluafile{lpdf-xmp}{1.001} +\registerctxluafile{lpdf-nod}{1.001} +\registerctxluafile{lpdf-mis}{1.001} +\registerctxluafile{lpdf-ano}{1.001} +\registerctxluafile{lpdf-ren}{1.001} +\registerctxluafile{lpdf-grp}{1.001} +\registerctxluafile{lpdf-wid}{1.001} +\registerctxluafile{lpdf-fld}{1.001} +\registerctxluafile{lpdf-u3d}{1.001} +\registerctxluafile{lpdf-swf}{1.001} +\registerctxluafile{lpdf-tag}{1.001} +\registerctxluafile{lpdf-pdx}{1.001} +\registerctxluafile{lpdf-epd}{1.001} +\registerctxluafile{lpdf-epa}{1.001} + +\registerctxluafile{back-pdf}{1.001} % some code will move to lpdf-* \unprotect @@ -37,6 +54,20 @@ \setjobsuffix{pdf} +%D PDF/X: + +\appendtoks + \doifsomething{\backendparameter\c!format} + {\ctxlua{backends.codeinjections.setformat { + format = "\backendparameter\c!format", + level = "\backendparameter\c!level", + option = "\backendparameter\c!option", + profile = "\backendparameter\c!profile", + intent = "\backendparameter\c!intent", + file = "\backendparameter\c!file", + }}}% +\to \everysetupbackend + %D For the moment we keep these. \newtoks \pdfbackendeveryximage @@ -157,14 +188,6 @@ \donothing \endgroup} -\def\doPDFgetobjectpage#1#2#3% - {\dogetobjectreferencepage{#1}{#2}#3% - \ifx#3\empty\def#3{\realfolio}\fi} - -\def\doPDFgetobjectpagereference#1#2#3% - {\dogetobjectreferencepage{#1}{#2}#3% - \doPDFgetpagereference{\ifx#3\empty\realfolio\else#3\fi}#3} - \let\lastpredefinedsymbol\empty % some day we can do more at the lua end \def\predefinesymbol[#1]% @@ -175,4 +198,244 @@ \ctxlua{backends.codeinjections.registersymbol("#1",\lastref)}% \endgroup} +% for the moment here + +%D \macros +%D {doovalbox} +%D +%D Drawing frames with round corners is inherited from the +%D main module. +%D +%D For drawing ovals we use quite raw \PDF\ code. The next +%D implementation does not differ that much from the one +%D implemented in the \POSTSCRIPT\ driver. This code is +%D somewhat obsolete as we now have metapost embedded. + +\def\doPDFovalcalc#1#2#3% + {\PointsToBigPoints{\dimexpr#1+#2\relax}#3} + +\def\doovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox + {\forcecolorhack + \bgroup + \dimen0=#4\divide\dimen0 \plustwo + \doPDFovalcalc{0pt}{+\dimen0}\xmin + \doPDFovalcalc{#1}{-\dimen0}\xmax + \doPDFovalcalc{#2}{-\dimen0}\ymax + \doPDFovalcalc{-#3}{+\dimen0}\ymin + \advance\dimen0 by #5% + \doPDFovalcalc{0pt}{+\dimen0}\xxmin + \doPDFovalcalc{#1}{-\dimen0}\xxmax + \doPDFovalcalc{#2}{-\dimen0}\yymax + \doPDFovalcalc{-#3}{+\dimen0}\yymin + \doPDFovalcalc{#4}{\zeropoint}\stroke + \doPDFovalcalc{#5}{\zeropoint}\radius + \edef\dostroke{#6}% + \edef\dofill{#7}% + \edef\mode{\number#8 \space}% + % no \ifcase, else \relax in pdfcode + \setbox\scratchbox\hbox + {\ifnum\dostroke\dofill>\zerocount + \pdfliteral + {q + \stroke\space w + \ifcase\mode + \xxmin\space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 1 + \xxmin\space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 2 + \xxmin\space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or % 3 + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + h + \or % 4 + \xmin \space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xmin \space \ymax \space l + \xmin \space \ymin\space l + h + \or % 5 + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax\space \ymax \space y + \xmin \space \ymax \space l + \xmin \space \ymin \space l + h + \or % 6 + \xmin \space \ymin \space m + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \ymin \space l + h + \or + \xxmin\space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xmin \space \ymax \space l + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + h + \or + \xmin \space \ymin \space m + \xmax \space \ymin \space l + \xmax \space \ymax \space l + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + h + \or % 9 top open + \xmin \space \ymax \space m + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + \xxmax\space \ymin \space l + \xmax \space \ymin \space \xmax \space \yymin\space y + \xmax \space \ymax \space l + \or % 10 right open + \xmax \space \ymax \space m + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \yymin\space l + \xmin \space \ymin \space \xxmin\space \ymin \space y + \xmax\space \ymin \space l + \or % 11 bottom open + \xmax \space \ymin \space m + \xmax \space \yymax\space l + \xmax \space \ymax \space \xxmax \space \ymax\space y + \xxmin\space \ymax \space l + \xmin \space \ymax \space \xmin \space \yymax\space y + \xmin \space \ymin \space l + \or % 12 left open + \xmin \space \ymax \space m + \xxmax\space \ymax \space l + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space l + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \ymin \space l + \or % 13 + \xmin \space \ymax \space m + \xxmax\space \ymax \space l + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax\space \ymin \space l + \or % 14 + \xmax \space \ymax \space m + \xmax \space \yymin\space l + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \ymin \space l + \or % 15 + \xmax \space \ymin \space m + \xxmin\space \ymin \space l + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \ymax \space l + \or % 16 + \xmin \space \ymin \space m + \xmin \space \yymax\space l + \xmin \space \ymax \space \xxmin\space \ymax \space y + \xmax \space \ymax \space l + \or % 17 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \or % 18 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \or % 19 + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 20 + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 21 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 22 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \or % 23 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 24 + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 25 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 26 + \xmax \space \yymin\space m + \xmax \space \ymin \space \xxmax\space \ymin \space y + \xmin \space \yymax\space m + \xmin \space \ymax \space \xxmin\space \ymax \space y + \or % 27 + \xxmax\space \ymax \space m + \xmax \space \ymax \space \xmax \space \yymax\space y + \xxmin\space \ymin \space m + \xmin \space \ymin \space \xmin \space \yymin\space y + \or % 28 + \fi + \ifnum\mode>8 + S + \else + \ifnum\dostroke=\plusone S \fi + \ifnum\dofill =\plusone f \fi + \fi + Q}% + \fi}% + \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox + \egroup} + +\unexpanded\def\pdfactualtext#1#2% + {\pdfliteral direct{/Span <</ActualText \ctxlua{tex.write(lpdf.tosixteen("#2"))} >> BDC}% + #1% + \pdfliteral direct{EMC}} + +% \starttext +% text \pdfactualtext{Meier}{Müller} text +% \stoptext + \protect \endinput diff --git a/tex/context/base/bibl-bib.lua b/tex/context/base/bibl-bib.lua index a74511427..3bf005201 100644 --- a/tex/context/base/bibl-bib.lua +++ b/tex/context/base/bibl-bib.lua @@ -19,7 +19,7 @@ local utfchar = utf.char local lpegmatch = lpeg.match local textoutf = characters and characters.tex.toutf local variables = interfaces and interfaces.variables - +local settings_to_hash = utilities.parsers.settings_to_hash local finalizers = xml.finalizers.tex local xmlfilter, xmltext = xml.filter, xml.text @@ -27,7 +27,8 @@ local trace_bibxml = false trackers.register("publications.bibxml", function(v) local report_publications = logs.new("publications") -bibtex = bibtex or { } +bibtex = bibtex or { } +local bibtex = bibtex bibtex.size = 0 bibtex.definitions = 0 @@ -103,7 +104,7 @@ local collapsed = (space^1)/ " " local function add(a,b) if b then return a..b else return a end end -local keyword = C((lpeg.R("az","AZ","09") + S("@_:-"))^1) -- lpeg.C((1-space)^1) +local keyword = C((R("az","AZ","09") + S("@_:-"))^1) -- lpeg.C((1-space)^1) local s_quoted = ((escape*single) + collapsed + (1-single))^0 local d_quoted = ((escape*double) + collapsed + (1-double))^0 local balanced = lpeg.patterns.balanced @@ -196,7 +197,7 @@ function bibtex.toxml(session,options) -- format slows down things a bit but who cares statistics.starttiming(bibtex) local result = { } - local options = aux.settings_to_hash(options) + local options = settings_to_hash(options) local convert = options.convert -- todo: interface local strip = options.strip -- todo: interface local entries = session.entries @@ -306,7 +307,7 @@ local commasplitter = Ct(lpeg.splitat(space^0 * comma * space^0)) local spacesplitter = Ct(lpeg.splitat(space^1)) local firstcharacter = lpeg.patterns.utf8byte -function is_upper(str) +local function is_upper(str) local first = lpegmatch(firstcharacter,str) local okay = chardata[first] return okay and okay.category == "lu" @@ -580,7 +581,7 @@ end -- pays off. local function collectauthoryears(id,list) - list = aux.settings_to_hash(list) + list = settings_to_hash(list) id = lxml.get_id(id) local found = { } for e in xml.collected(id,"/bibtex/entry") do @@ -738,6 +739,7 @@ if commands then texsprint(ctxcatcodes,singular) end end + end diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv index e4a92b3c0..6f2863fd8 100644 --- a/tex/context/base/bibl-bib.mkiv +++ b/tex/context/base/bibl-bib.mkiv @@ -169,7 +169,7 @@ \def\bibxmlflush #1{\xmlcontext \currentbibxmlnode{/field[@name='#1']}} \def\bibxmlsetup {\xmlsetup \currentbibxmlnode} % {#1} -\def\currentbibtexformat{apa} % ho wto interface this, maybe split loading and key +\def\currentbibtexformat{apa} % how to interface this, maybe split loading and key \def\currentbibxmlnode {unset} \def\currentbibxmltag {unset} @@ -299,7 +299,7 @@ % lists \def\bibtexlistprocessor - {\ctxlua{bibtex.hacks.add(structure.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} + {\ctxlua{bibtex.hacks.add(structures.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} \appendtoks \definelist[\currentbibtexsession]% @@ -466,7 +466,7 @@ \appendtoks \doloadbibtexpublicationalternative -\to \everyjob +\to \everystarttext % was everyjob, will change anyway % whatever, should be key @@ -578,7 +578,7 @@ {\ifx\currentbibtexnumbering\v!short \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\bibtexpublicationsparameter\c!samplesize}}% \else - \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\ctxlua{tex.write(structure.lists.size())}}}% + \setbox\scratchbox\hbox{\bibtexpublicationsparameter\c!numbercommand{\ctxlua{tex.write(structures.lists.size())}}}% \fi \bibtexnumberwidth\wd\scratchbox \setuplist[\currentbibtexsession][\c!distance=\zeropoint]} diff --git a/tex/context/base/bibl-tra.lua b/tex/context/base/bibl-tra.lua index f9a16f699..4c62475d0 100644 --- a/tex/context/base/bibl-tra.lua +++ b/tex/context/base/bibl-tra.lua @@ -6,8 +6,11 @@ if not modules then modules = { } end modules ['bibl-bib'] = { license = "see context related readme files" } -bibtex = bibtex or { } +bibtex = bibtex or { } +local bibtex = bibtex + bibtex.hacks = bibtex.hacks or { } +local hacks = bibtex.hacks local match, gmatch, format, concat, sort = string.match, string.gmatch, string.format, table.concat, table.sort local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes @@ -17,7 +20,10 @@ local trace_bibtex = false trackers.register("publications.bibtex", function(v) local report_publications = logs.new("publications") -local hacks = bibtex.hacks +local context, structures, references = context, structures, references + +local references = structures.references +local sections = structures.sections local list, done, alldone, used, registered, ordered = { }, { }, { }, { }, { }, { } local mode = 0 @@ -60,14 +66,14 @@ function hacks.add(str,listindex) -- skip elseif mode == 1 then -- all locals but no duplicates - local sc = structure.sections.currentid() + local sc = sections.currentid() if done[str] ~= sc then done[str], alldone[str] = sc, true list[#list+1] = { str, listindex } end elseif mode == 2 then -- all locals but no preceding - local sc = structure.sections.currentid() + local sc = sections.currentid() if not alldone[str] and done[str] ~= sc then done[str], alldone[str] = sc, true list[#list+1] = { str, listindex } @@ -113,7 +119,7 @@ local function compare(a,b) end function hacks.resolve(prefix,block,reference) -- maybe already feed it split - local subset = jobreferences.collected[prefix or ""] or jobreferences.collected[""] + local subset = references.collected[prefix or ""] or references.collected[""] if subset then local result, done = { }, { } block = tonumber(block) diff --git a/tex/context/base/bibl-tra.mkiv b/tex/context/base/bibl-tra.mkiv index 519af0c6f..4ebc817db 100644 --- a/tex/context/base/bibl-tra.mkiv +++ b/tex/context/base/bibl-tra.mkiv @@ -188,7 +188,7 @@ \c!width=] \installstructurelistprocessor{pubs:userdata}% - {\ctxlua{bibtex.hacks.add(structure.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} + {\ctxlua{bibtex.hacks.add(structures.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}} \newcount\bibtexblock \bibtexblock\plusone @@ -832,7 +832,7 @@ {\ifx\@@pbnumbering\v!short \setbox\scratchbox\hbox{\@@pbnumbercommand{\listparameter\c!samplesize}}% \else - \setbox\scratchbox\hbox{\@@pbnumbercommand{\ctxlua{tex.write(structure.lists.size())}}}% + \setbox\scratchbox\hbox{\@@pbnumbercommand{\ctxlua{tex.write(structures.lists.size())}}}% \fi \edef\publistnumberbox{\hbox to \the\wd\scratchbox}% \expanded{\setuplist[pubs][\c!width=\the\wd\scratchbox,\c!distance=\zeropoint]}% diff --git a/tex/context/base/blob-ini.lua b/tex/context/base/blob-ini.lua index be044d58f..fec304f7d 100644 --- a/tex/context/base/blob-ini.lua +++ b/tex/context/base/blob-ini.lua @@ -31,8 +31,10 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local fontdata = fonts.identifiers -local new_glyph_node = nodes.glyph -local new_glue_node = nodes.glyph +local nodepool = nodes.pool + +local new_glyph = nodepool.glyph +local new_glue = nodepool.glue local copy_node = node.copy local copy_node_list = node.copy_list @@ -76,7 +78,7 @@ local function tonodes(str,fnt,attr) -- (str,template_glyph) if s == 32 then if not space then local parameters = fontdata[fnt].parameters - space = new_glue_node(parameters.space,parameters.space_stretch,parameters.space_shrink) + space = new_glue(parameters.space,parameters.space_stretch,parameters.space_shrink) n = space else n = copy_node(space) @@ -85,7 +87,7 @@ local function tonodes(str,fnt,attr) -- (str,template_glyph) n = copy_node(template) n.char = s else - n = new_glyph_node(fnt,s) + n = new_glyph(fnt,s) end if attr then -- normally false when template n.attr = copy_node_list(attr) diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index 0cf8c8804..70d187f1a 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -13,13 +13,6 @@ if not modules then modules = { } end modules ['buff-ini'] = { -- redefine buffers.get -buffers = { } -buffers.data = { } -buffers.hooks = { } -buffers.flags = { } -buffers.commands = { } -buffers.visualizers = { } - -- if needed we can make 'm local local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) @@ -33,13 +26,27 @@ local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.prin local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub local type, next = type, next local huge = math.huge -local byte, sub, find, char, gsub, rep, lower, format, gmatch, match = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format, string.gmatch, string.match +local byte, sub, find, char, gsub, rep, lower, format, gmatch, match, count = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format, string.gmatch, string.match, string.count local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables local lpegmatch = lpeg.match +local settings_to_array = utilities.parsers.settings_to_array + +buffers = { + data = { }, + hooks = { }, + flags = { }, + commands = { }, + visualizers = { }, +} -local data, flags, hooks, visualizers = buffers.data, buffers.flags, buffers.hooks, buffers.visualizers +local buffers = buffers + +local data = buffers.data +local flags = buffers.flags +local hooks = buffers.hooks +local visualizers = buffers.visualizers visualizers.defaultname = variables.typing @@ -70,7 +77,7 @@ function buffers.grab(name,begintag,endtag,bufferdata) if dn == "" then buffers.level = 0 end - buffers.level = buffers.level + bufferdata:count("\\"..begintag) - bufferdata:count("\\"..endtag) + buffers.level = buffers.level + count(bufferdata,"\\"..begintag) - count(bufferdata,"\\"..endtag) local more = buffers.level > 0 if more then dn = dn .. bufferdata .. endtag @@ -87,7 +94,7 @@ function buffers.grab(name,begintag,endtag,bufferdata) end end data[name] = dn - cs.testcase(more) + commands.testcase(more) end function buffers.exists(name) @@ -95,7 +102,7 @@ function buffers.exists(name) end function buffers.doifelsebuffer(name) - cs.testcase(data[name] ~= nil) + commands.testcase(data[name] ~= nil) end flags.optimize_verbatim = true @@ -145,7 +152,7 @@ end function buffers.range(lines,first,last,range) -- 1,3 1,+3 fromhere,tothere local first, last = first or 1, last or #lines - local what = aux.settings_to_array(range) + local what = settings_to_array(range) local r_first, r_last = what[1], what[2] local f, l = tonumber(r_first), tonumber(r_last) if r_first then @@ -353,7 +360,7 @@ function buffers.collect(names,separator) -- no print -- maybe we should always store a buffer as table so -- that we can pass it directly if type(names) == "string" then - names = aux.settings_to_array(names) + names = settings_to_array(names) end local t = { } for i=1,#names do @@ -484,7 +491,7 @@ function visualizers.reset() end function buffers.doifelsevisualizer(str) - cs.testcase((str ~= "") and (handlers[lower(str)] ~= nil)) + commands.testcase((str ~= "") and (handlers[lower(str)] ~= nil)) end -- calling routines, don't change @@ -592,65 +599,79 @@ function default.flush_line(str) end end --- not needed any more - -local function escaped_token(c) - if utffind(c,"^(%a%d)$") then - return c - elseif c == " " then - return "\\obs " - else - return "\\char" .. utfbyte(c) .. " " - end -end - -buffers.escaped_token = escaped_token - -function buffers.escaped(str) - -- use the utfcharacters loop - return (utfgsub(str,"(.)", escaped_token)) -end - -- special one buffers.commands.nested = "\\switchslantedtype " --- todo : utf + faster, direct print and such. no \\char, vrb catcodes, see end +--~ function visualizers.flushnested(str, enable) -- todo: no utf, vrb catcodes, kind of obsolete mess +--~ str = gsub(str," *[\n\r]+ *"," ") +--~ local result, c, nested, i = "", "", 0, 1 +--~ local commands = buffers.commands -- otherwise wrong commands +--~ while i < #str do -- slow +--~ c = sub(str,i,i+1) +--~ if c == "<<" then +--~ nested = nested + 1 +--~ if enable then +--~ result = result .. "{" .. commands.nested +--~ else +--~ result = result .. "{" +--~ end +--~ i = i + 2 +--~ elseif c == ">>" then +--~ if nested > 0 then +--~ nested = nested - 1 +--~ result = result .. "}" +--~ end +--~ i = i + 2 +--~ else +--~ c = sub(str,i,i) +--~ if c == " " then +--~ result = result .. "\\obs " +--~ elseif find(c,"%a") then +--~ result = result .. c +--~ else +--~ result = result .. "\\char" .. byte(c) .. " " +--~ end +--~ i = i + 1 +--~ end +--~ end +--~ result = result .. "\\char" .. byte(sub(str,i,i)) .. " " .. rep("}",nested) +--~ texsprint(ctxcatcodes,result) +--~ end -function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess +function visualizers.flushnested(str, enable) -- todo: no utf, vrb catcodes, kind of obsolete mess str = gsub(str," *[\n\r]+ *"," ") - local result, c, nested, i = "", "", 0, 1 + local c, nested, i = "", 0, 1 local commands = buffers.commands -- otherwise wrong commands while i < #str do -- slow c = sub(str,i,i+1) if c == "<<" then nested = nested + 1 if enable then - result = result .. "{" .. commands.nested + texsprint(ctxcatcodes,"{",commands.nested) else - result = result .. "{" + texsprint(ctxcatcodes,"{") end i = i + 2 elseif c == ">>" then if nested > 0 then nested = nested - 1 - result = result .. "}" + texsprint(ctxcatcodes,"}") end i = i + 2 else c = sub(str,i,i) if c == " " then - result = result .. "\\obs " + texsprint(ctxcatcodes,"\\obs") elseif find(c,"%a") then - result = result .. c + texsprint(ctxcatcodes,c) else - result = result .. "\\char" .. byte(c) .. " " + texsprint(ctxcatcodes,"\\char",byte(c)," ") end i = i + 1 end end - result = result .. "\\char" .. byte(sub(str,i,i)) .. " " .. rep("}",nested) - texsprint(ctxcatcodes,result) + texsprint(ctxcatcodes,"\\char",byte(sub(str,i,i))," ",rep("}",nested)) end -- handy helpers @@ -663,7 +684,7 @@ end buffers.currentcolors = { } -function buffers.change_state(n, state) +function buffers.changestate(n, state) if n then if state ~= n then if state > 0 then @@ -680,7 +701,7 @@ function buffers.change_state(n, state) return state end -function buffers.finish_state(state) +function buffers.finishstate(state) if state > 0 then texsprint(ctxcatcodes,"\\eop") return 0 @@ -689,20 +710,20 @@ function buffers.finish_state(state) end end -buffers.open_nested = rep("\\char"..byte('<').." ",2) -buffers.close_nested = rep("\\char"..byte('>').." ",2) +local opennested = rep("\\char"..byte('<').." ",2) +local closenested = rep("\\char"..byte('>').." ",2) -function buffers.replace_nested(result) - result = gsub(result,buffers.open_nested, "{") - result = gsub(result,buffers.close_nested,"}") +function buffers.replacenested(result) + result = gsub(result,opennested, "{") + result = gsub(result,closenested,"}") return result end -function buffers.flush_result(result,nested) +function buffers.flushresult(result,nested) if nested then - texsprint(ctxcatcodes,buffers.replace_nested(concat(result,""))) + texsprint(ctxcatcodes,buffers.replacenested(concat(result))) else - texsprint(ctxcatcodes,concat(result,"")) + texsprint(ctxcatcodes,concat(result)) end end @@ -745,7 +766,7 @@ function buffers.realign(name,forced_n) -- no, auto, <number> return d end --- escapes: buffers.set_escape("tex","/BTEX","/ETEX") +-- escapes: buffers.setescapepair("tex","/BTEX","/ETEX") local function flush_escaped_line(str,pattern,flushline) while true do @@ -769,7 +790,7 @@ local function flush_escaped_line(str,pattern,flushline) end end -function buffers.set_escape(name,pair) +function buffers.setescapepair(name,pair) if pair and pair ~= "" then local visualizer = buffers.getvisualizer(name) visualizer.normal_flush_line = visualizer.normal_flush_line or visualizer.flush_line diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index 8c4e7a557..98430363c 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -216,7 +216,7 @@ %D \typebuffer \start \getbuffer \stop \unexpanded\def\setupcommandsintype - {\ctxlua{buffers.set_escape("\currenttyping",\!!bs\typingparameter\c!escape\!!es)}} + {\ctxlua{buffers.setescapepair("\currenttyping",\!!bs\typingparameter\c!escape\!!es)}} \appendtoks \setupcommandsintype @@ -363,7 +363,7 @@ \def\dodotypeBB#1% {\doinitializeverbatim \dostarttagged\t!verbatim\currenttyping - \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,false)}% + \ctxlua{buffers.visualizers.flushnested(\!!bs\detokenize{#1}\!!es,false)}% \dostoptagged \egroup \gobbleoneargument} % grab last > @@ -383,7 +383,7 @@ \dostoptagged \else \def\obs{\obeyedspace}% - \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,true)}% + \ctxlua{buffers.visualizers.flushnested(\!!bs\detokenize{#1}\!!es,true)}% \fi \egroup \gobbleoneargument} % grab last > diff --git a/tex/context/base/char-cmp.lua b/tex/context/base/char-cmp.lua index c7deb7901..848eeebee 100644 --- a/tex/context/base/char-cmp.lua +++ b/tex/context/base/char-cmp.lua @@ -6,11 +6,16 @@ if not modules then modules = { } end modules ['char-cmp'] = { license = "see context related readme files" } +local type = type local utf = unicode.utf8 +local utfchar = utf.char local unpack = unpack or table.unpack -characters = characters or { } +characters = characters or { } +local characters = characters + characters.uncomposed = characters.uncomposed or { } +local uncomposed = characters.uncomposed --[[ldx-- <p>The code defined here may move to the big character table.</p> @@ -45,7 +50,7 @@ Of course they may come in handy elsewhere too</p> -- => shcode == { ub('a') } -- => reduction = "a" -characters.uncomposed.left = { +uncomposed.left = { AEligature = "A", aeligature = "a", OEligature = "O", oeligature = "o", IJligature = "I", ijligature = "i", @@ -55,7 +60,7 @@ characters.uncomposed.left = { Ssharp = "S", ssharp = "s", } -characters.uncomposed.right = { +uncomposed.right = { AEligature = "E", aeligature = "e", OEligature = "E", oeligature = "e", IJligature = "J", ijligature = "j", @@ -65,7 +70,7 @@ characters.uncomposed.right = { Ssharp = "S", ssharp = "s", } -characters.uncomposed.both = { +uncomposed.both = { Acircumflex = "A", acircumflex = "a", Ccircumflex = "C", ccircumflex = "c", Ecircumflex = "E", ecircumflex = "e", @@ -200,11 +205,11 @@ function characters.uncompose(n) -- n == string|number, returns string if cdn then local shcode = cdn.shcode if not shcode then - return characters.uncomposed.both[cdn.contextname] or n + return uncomposed.both[cdn.contextname] or n elseif type(shcode) == "table" then - return utf.char(unpack(cdn.shcode)) + return utfchar(unpack(cdn.shcode)) else - return utf.char(cdn.shcode) + return utfchar(cdn.shcode) end end return n diff --git a/tex/context/base/char-enc.lua b/tex/context/base/char-enc.lua index 45f404ee9..8addff0e8 100644 --- a/tex/context/base/char-enc.lua +++ b/tex/context/base/char-enc.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['char-syn'] = { -- thanks to tex4ht for these mappings -characters = characters or { } +characters = characters or { } +local characters = characters characters.synonyms = { angle = 0x2220, diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua index e61f1ce78..99afe6ec4 100644 --- a/tex/context/base/char-ini.lua +++ b/tex/context/base/char-ini.lua @@ -6,9 +6,7 @@ if not modules then modules = { } end modules ['char-ini'] = { license = "see context related readme files" } -tex = tex or { } -xml = xml or { } - +local tex = tex local utf = unicode.utf8 local utfchar, utfbyte, utfvalues = utf.char, utf.byte, string.utfvalues @@ -29,10 +27,10 @@ from the big character table that we use for all kind of purposes: loaded!</p> --ldx]]-- -characters = characters or { } -characters.data = characters.data or { } - -local data = characters.data +characters = characters or { } +local characters = characters +characters.data = characters.data or { } +local data = characters.data if not characters.ranges then characters.ranges = { } diff --git a/tex/context/base/char-tex.lua b/tex/context/base/char-tex.lua index ed9a244d7..5a1edb42e 100644 --- a/tex/context/base/char-tex.lua +++ b/tex/context/base/char-tex.lua @@ -6,11 +6,16 @@ if not modules then modules = { } end modules ['char-tex'] = { license = "see context related readme files" } -characters = characters or { } -characters.tex = characters.tex or { } - local find = string.find +local lpeg = lpeg +local P, C, R, S, Cs, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc +local U, lpegmatch = lpeg.patterns.utf8, lpeg.match + +characters = characters or { } +local characters = characters +characters.tex = characters.tex or { } + local accent_map = { ['~'] = "̃" , -- ̃ Ẽ ['"'] = "̈" , -- ̈ Ë @@ -57,9 +62,6 @@ local function remap_commands(c) end end -local P, C, R, S, Cs, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc -local U, lpegmatch = lpeg.patterns.utf8, lpeg.match - local accents = (P('\\') * C(S(accents)) * (P("{") * C(U) * P("}" * Cc(true)) + C(U) * Cc(false))) / remap_accents local commands = (P('\\') * C(R("az","AZ")^1)) / remap_commands diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua index 6dd85fdc8..71e2805ad 100644 --- a/tex/context/base/char-utf.lua +++ b/tex/context/base/char-utf.lua @@ -20,46 +20,49 @@ over a string.</p> --ldx]]-- local utf = unicode.utf8 +local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub local concat, gmatch = table.concat, string.gmatch local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues - local ctxcatcodes = tex.ctxcatcodes +local texsprint = tex.sprint -characters = characters or { } -characters.graphemes = characters.graphemes or { } -characters.filters = characters.filters or { } -characters.filters.utf = characters.filters.utf or { } +-- todo: trackers -characters.filters.utf.initialized = false -characters.filters.utf.collapsing = true -characters.filters.utf.expanding = true +characters = characters or { } +local characters = characters -local graphemes = characters.graphemes -local utffilters = characters.filters.utf -local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub +characters.graphemes = characters.graphemes or { } +local graphemes = characters.graphemes + +characters.filters = characters.filters or { } +local filters = characters.filters + +filters.utf = filters.utf or { } +local utffilters = characters.filters.utf + +utffilters.collapsing = true +utffilters.expanding = true --[[ldx-- <p>It only makes sense to collapse at runtime, since we don't expect source code to depend on collapsing.</p> --ldx]]-- -function utffilters.initialize() - if utffilters.collapsing and not utffilters.initialized then - for k,v in next, characters.data do - -- using vs and first testing for length is faster (.02->.01 s) - local vs = v.specials - if vs and #vs == 3 and vs[1] == 'char' then - local first, second = utfchar(vs[2]), utfchar(vs[3]) - local cgf = graphemes[first] - if not cgf then - cgf = { } - graphemes[first] = cgf - end - cgf[second] = utfchar(k) +local function initialize() + for k,v in next, characters.data do + -- using vs and first testing for length is faster (.02->.01 s) + local vs = v.specials + if vs and #vs == 3 and vs[1] == 'char' then + local first, second = utfchar(vs[2]), utfchar(vs[3]) + local cgf = graphemes[first] + if not cgf then + cgf = { } + graphemes[first] = cgf end + cgf[second] = utfchar(k) end - utffilters.initialized = true end + initialize = false end -- utffilters.add_grapheme(utfchar(318),'l','\string~') @@ -79,8 +82,8 @@ end function utffilters.collapse(str) -- old one if utffilters.collapsing and str and #str > 1 then - if not utffilters.initialized then -- saves a call - utffilters.initialize() + if initialize then -- saves a call + initialize() end local tokens, first, done = { }, false, false for second in utfcharacters(str) do @@ -120,18 +123,20 @@ to their right glyph there.</p> 0x100000.</p> --ldx]]-- -utffilters.private = { - high = { }, - low = { }, - escapes = { }, +local low = { } +local high = { } +local escapes = { } +local special = "~#$%^&_{}\\|" + +local private = { + low = low, + high = high, + escapes = escapes, } -local low = utffilters.private.low -local high = utffilters.private.high -local escapes = utffilters.private.escapes -local special = "~#$%^&_{}\\|" +utffilters.private = private -function utffilters.private.set(ch) +local function set(ch) local cb if type(ch) == "number" then cb, ch = ch, utfchar(ch) @@ -145,11 +150,11 @@ function utffilters.private.set(ch) end end -function utffilters.private.replace(str) return utfgsub(str,"(.)", low ) end -function utffilters.private.revert(str) return utfgsub(str,"(.)", high ) end -function utffilters.private.escape(str) return utfgsub(str,"(.)", escapes) end +private.set = set -local set = utffilters.private.set +function private.replace(str) return utfgsub(str,"(.)", low ) end +function private.revert(str) return utfgsub(str,"(.)", high ) end +function private.escape(str) return utfgsub(str,"(.)", escapes) end for ch in gmatch(special,".") do set(ch) end @@ -162,12 +167,7 @@ first snippet uses the relocated dollars.</p> <typing> [x] [$x$] </typing> ---ldx]]-- - -local cr = utffilters.private.high -- kan via een lpeg -local cf = utffilters ---[[ldx-- <p>The next variant has lazy token collecting, on a 140 page mk.tex this saves about .25 seconds, which is understandable because we have no graphmes and not collecting tokens is not only faster but also saves garbage collecting. @@ -177,15 +177,15 @@ not collecting tokens is not only faster but also saves garbage collecting. -- lpeg variant is not faster function utffilters.collapse(str) -- not really tested (we could preallocate a table) - if cf.collapsing and str then + if utffilters.collapsing and str then if #str > 1 then - if not cf.initialized then -- saves a call - cf.initialize() + if initialize then -- saves a call + initialize() end local tokens, first, done, n = { }, false, false, 0 for second in utfcharacters(str) do if done then - local crs = cr[second] + local crs = high[second] if crs then if first then tokens[#tokens+1] = first @@ -203,7 +203,7 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t end end else - local crs = cr[second] + local crs = high[second] if crs then for s in utfcharacters(str) do if n == 1 then @@ -238,7 +238,7 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t return concat(tokens) -- seldom called end elseif #str > 0 then - return cr[str] or str + return high[str] or str end end return str @@ -251,7 +251,7 @@ end commands = commands or { } function commands.uchar(first,second) - tex.sprint(ctxcatcodes,utfchar(first*256+second)) + texsprint(ctxcatcodes,utfchar(first*256+second)) end --[[ldx-- diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua index d5c189fff..776647554 100644 --- a/tex/context/base/chem-ini.lua +++ b/tex/context/base/chem-ini.lua @@ -9,13 +9,16 @@ if not modules then modules = { } end modules ['chem-ini'] = { local format, texsprint = string.format, tex.sprint local lpegmatch = lpeg.match +local P, R, V, Cc, Cs = lpeg.P, lpeg.R, lpeg.V, lpeg.Cc, lpeg.Cs + local trace_molecules = false trackers.register("chemistry.molecules", function(v) trace_molecules = v end) local report_chemistry = logs.new("chemistry") local ctxcatcodes = tex.ctxcatcodes -chemicals = chemicals or { } +chemicals = chemicals or { } +local chemicals = chemicals --[[ <p>The next code is an adaptation of code from Wolfgang Schuster @@ -27,38 +30,37 @@ of input then.</p> -- some lpeg, maybe i'll make an syst-lpg module -local lowercase = lpeg.R("az") -local uppercase = lpeg.R("AZ") -local backslash = lpeg.P("\\") -local csname = backslash * lpeg.P(1) * (1-backslash)^0 -local plus = lpeg.P("+") / "\\textplus " -local minus = lpeg.P("-") / "\\textminus " -local digit = lpeg.R("09") +local lowercase = R("az") +local uppercase = R("AZ") +local backslash = P("\\") +local csname = backslash * P(1) * (1-backslash)^0 +local plus = P("+") / "\\textplus " +local minus = P("-") / "\\textminus " +local digit = R("09") local sign = plus + minus local cardinal = digit^1 local integer = sign^0 * cardinal -local leftbrace = lpeg.P("{") -local rightbrace = lpeg.P("}") +local leftbrace = P("{") +local rightbrace = P("}") local nobrace = 1 - (leftbrace + rightbrace) -local nested = lpeg.P { leftbrace * (csname + sign + nobrace + lpeg.V(1))^0 * rightbrace } -local any = lpeg.P(1) +local nested = P { leftbrace * (csname + sign + nobrace + V(1))^0 * rightbrace } +local any = P(1) -local subscript = lpeg.P("_") -local superscript = lpeg.P("^") +local subscript = P("_") +local superscript = P("^") local somescript = subscript + superscript ---~ local content = lpeg.Cs(nested + integer + sign + any) -local content = lpeg.Cs(csname + nested + sign + any) +local content = Cs(csname + nested + sign + any) -- could be made more efficient -local lowhigh = lpeg.Cc("\\lohi{%s}{%s}") * subscript * content * superscript * content / format -local highlow = lpeg.Cc("\\hilo{%s}{%s}") * superscript * content * subscript * content / format -local low = lpeg.Cc("\\low{%s}") * subscript * content / format -local high = lpeg.Cc("\\high{%s}") * superscript * content / format +local lowhigh = Cc("\\lohi{%s}{%s}") * subscript * content * superscript * content / format +local highlow = Cc("\\hilo{%s}{%s}") * superscript * content * subscript * content / format +local low = Cc("\\low{%s}") * subscript * content / format +local high = Cc("\\high{%s}") * superscript * content / format local justtext = (1 - somescript)^1 -local parser = lpeg.Cs((csname + lowhigh + highlow + low + high + sign + any)^0) +local parser = Cs((csname + lowhigh + highlow + low + high + sign + any)^0) chemicals.moleculeparser = parser -- can be used to avoid functioncall diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua index 0a963d781..7cd713470 100644 --- a/tex/context/base/chem-str.lua +++ b/tex/context/base/chem-str.lua @@ -17,13 +17,17 @@ local report_chemistry = logs.new("chemistry") local format, gmatch, match, lower, gsub = string.format, string.gmatch, string.match, string.lower, string.gsub local concat, insert, remove = table.concat, table.insert, table.remove -local apply = structure.processors.apply +local apply = structures.processors.apply local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local lpegmatch = lpeg.match +local settings_to_array = utilities.parsers.settings_to_array + +local P, R, S, C, Cs, Ct, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc local variables = interfaces.variables chemicals = chemicals or { } +local chemicals = chemicals chemicals.instance = "metafun" -- "ppchtex" chemicals.format = "metafun" @@ -152,8 +156,8 @@ function chemicals.define(name,spec,text) local dn = definitions[name] if not dn then dn = { } definitions[name] = dn end dn[#dn+1] = { - spec = aux.settings_to_array(lower(spec)), - text = aux.settings_to_array(text), + spec = settings_to_array(lower(spec)), + text = settings_to_array(text), } end @@ -163,42 +167,41 @@ local molecule = chemicals.molecule -- or use lpegmatch(chemicals.moleculeparser local function fetch(txt) local st = stack[txt] local t = st.text[st.n] ---~ st.n = st.n + 1 while not t and txt > 1 do txt = txt - 1 st = stack[txt] t = st.text[st.n] ---~ st.n = st.n + 1 end if t then if trace_textstack then report_chemistry("fetching from stack %s slot %s: %s",txt,st.n,t) end -st.n = st.n + 1 + st.n = st.n + 1 end return txt, t end -local digit = lpeg.R("09")/tonumber -local colon = lpeg.P(":") -local equal = lpeg.P("=") +local digit = R("09")/tonumber +local colon = P(":") +local equal = P("=") local other = 1 - digit - colon - equal -local remapped = lpeg.S("+-") / remapper -local operation = lpeg.Cs((remapped^0 * other)^1) +local remapped = S("+-") / remapper +local operation = Cs((remapped^0 * other)^1) local amount = digit local single = digit -local special = (colon * lpeg.C(other^1)) + lpeg.Cc("") -local range = digit * lpeg.P("..") * digit -local set = lpeg.Ct(digit^2) -local text = (equal * lpeg.C(lpeg.P(1)^0)) + lpeg.Cc(false) +local special = (colon * C(other^1)) + Cc("") +local range = digit * P("..") * digit +local set = Ct(digit^2) +local text = (equal * C(P(1)^0)) + Cc(false) + local pattern = - (amount + lpeg.Cc(1)) * + (amount + Cc(1)) * operation * special * ( - range * lpeg.Cc(false) * text + - lpeg.Cc(false) * lpeg.Cc(false) * set * text + - single * lpeg.Cc(false) * lpeg.Cc(false) * text + - lpeg.Cc(false) * lpeg.Cc(false) * lpeg.Cc(false) * text + range * Cc(false) * text + + Cc(false) * Cc(false) * set * text + + single * Cc(false) * Cc(false) * text + + Cc(false) * Cc(false) * Cc(false) * text ) --~ local n, operation, index, upto, set, text = lpegmatch(pattern,"RZ1357") @@ -451,8 +454,8 @@ end function chemicals.component(spec,text,settings) rulethickness, rulecolor, offset = settings.rulethickness, settings.rulecolor - local spec = aux.settings_to_array(lower(spec)) - local text = aux.settings_to_array(text) + local spec = settings_to_array(lower(spec)) + local text = settings_to_array(text) metacode[#metacode+1] = "chem_start_component ;" process(spec,text,1,rulethickness,rulecolor) metacode[#metacode+1] = "chem_stop_component ;" @@ -473,7 +476,7 @@ local inline = { -- todo: top / bottom function chemicals.inline(spec) - local spec = aux.settings_to_array(spec) + local spec = settings_to_array(spec) for i=1,#spec do local s = spec[i] local inl = inline[lower(s)] diff --git a/tex/context/base/colo-ext.mkiv b/tex/context/base/colo-ext.mkiv index b17608f59..5fda96692 100644 --- a/tex/context/base/colo-ext.mkiv +++ b/tex/context/base/colo-ext.mkiv @@ -94,7 +94,7 @@ \def\dododefineintermediatecolor[#1][#2,#3,#4][#5]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{colors.defineintermediatecolor("#1","#2", + \ctxlua{_clib_.defineintermediatecolor("#1","#2", \thecolorattribute{#3},\thecolorattribute{#4}, \thetransparencyattribute{#3},\thetransparencyattribute{#4}, "#5",false,\iffreezecolors true\else false\fi)}% not global diff --git a/tex/context/base/colo-icc.lua b/tex/context/base/colo-icc.lua index 724ff3241..5df4b9663 100644 --- a/tex/context/base/colo-icc.lua +++ b/tex/context/base/colo-icc.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['colo-ini'] = { local char, byte, gsub, match, format, strip = string.char, string.byte, string.gsub, string.match, string.format, string.strip local readstring, readnumber = io.readstring, io.readnumber -colors = colors or { } -- can also be used in mtxrun +local colors = attributes and attributes.colors or { } -- when used in mtxrun local R, Cs, lpegmatch = lpeg.R, lpeg.Cs, lpeg.match diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index 28ce4ac6a..cba78954d 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -16,12 +16,13 @@ local trace_define = false trackers.register("colors.define",function(v) trace_ local report_colors = logs.new("colors") -local settings_to_hash_strict = aux.settings_to_hash_strict +local attributes, context, commands = attributes, context, commands -colors = colors or { } -transparencies = transparencies or { } +local settings_to_hash_strict = utilities.parsers.settings_to_hash_strict -local registrations = backends.registrations +local colors = attributes.colors +local transparencies = attributes.transparencies +local registrations = backends.registrations local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv index 0d1dd50e5..1795f2e3a 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -21,7 +21,6 @@ \registerctxluafile{colo-ini}{1.000} \registerctxluafile{colo-icc}{1.000} -\registerctxluafile{lpdf-col}{1.000} \unprotect @@ -720,7 +719,7 @@ % \dosetcolormodel{#1}} \def\dosetcolormodel#1% no message - {\currentcolormodel\ctxlua{tex.print(colors.setmodel('#1',\ifweightGRAY true\else false\fi))}% + {\currentcolormodel\ctxlua{tex.print(_clib_.setmodel('#1',\ifweightGRAY true\else false\fi))}% \attribute\colormodelattribute\currentcolormodel} \dosetcolormodel{all} @@ -786,7 +785,7 @@ \def\doactivatecolor {\ifproductionrun - \ctxlua{colors.enable() transparencies.enable()}% not that efficient but at least robust + \ctxlua{_clib_.enable() _tlib_.enable()}% not that efficient but at least robust \let\doactivatecolor\normaldoactivatecolor \expandafter\doactivatecolor \else @@ -805,44 +804,44 @@ \setfalse\collectcolorsinlist \def\collectcolorinlist#1{\doglobal\addtocommalist{#1}\colorlist} -\def\doregistercolor#1#2{\ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}} +\def\doregistercolor#1#2{\ctxlua{_clib_.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}} \def\dodefinecolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \ctxlua{_clib_.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} \def\dodefineglobalcolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{colors.defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}% + \ctxlua{_clib_.defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setgvalue{#1}} \def\dodefinenamedcolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \ctxlua{_clib_.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} \def\dodefinespotcolor[#1][#2][#3]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{colors.definespotcolor("#1","#2","#3",true)}% + \ctxlua{_clib_.definespotcolor("#1","#2","#3",true)}% \dodefinecolorcommand\setxvalue{#1}} \def\dodefinemultitonecolor[#1][#2][#3][#4]% - {\ctxlua{colors.definemultitonecolor("#1","#2","#3","#4",true)}% + {\ctxlua{_clib_.definemultitonecolor("#1","#2","#3","#4",true)}% \dodefinecolorcommand\setxvalue{#1}} \def\dodefinetransparency[#1][#2]% - {\ctxlua{colors.definetransparency("#1",#2)}} + {\ctxlua{_clib_.definetransparency("#1",#2)}} \def\dosetrastercolor#1% slow, we need a fast one {\edef\@@rastervalue{#1}% \ifx\@@rastervalue\empty \let\@@rastervalue\@@rsscreen \fi - \attribute\colorattribute\ctxlua{tex.sprint(colors.definesimplegray("_raster_",\@@rastervalue))}\relax} + \attribute\colorattribute\ctxlua{tex.sprint(_clib_.definesimplegray("_raster_",\@@rastervalue))}\relax} \def\dodefinefastcolor[#1][#2]% still not fast but ok - {\ctxlua{colors.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + {\ctxlua{_clib_.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} %D \macros @@ -876,7 +875,7 @@ %D A bit like \type {\definedfont}: \unexpanded\def\colored[#1]% - {\ctxlua{colors.defineprocesscolor("@colored@","#1",false,false)}% + {\ctxlua{_clib_.defineprocesscolor("@colored@","#1",false,false)}% \groupedcommand{\doactivatecolor{@colored@}}{}} %D \macros @@ -916,7 +915,7 @@ \ifx\maintextcolor\empty\else\doactivatecolor\maintextcolor\fi \to \everybeforeoutput -\def\registermaintextcolor{\ctxlua{colors.main = \thecolorattribute\maintextcolor}} +\def\registermaintextcolor{\ctxlua{_clib_.main = \thecolorattribute\maintextcolor}} \unexpanded\def\starttextcolor[#1]% {\doifsomething{#1} @@ -998,7 +997,7 @@ \def\colorformatseparator{ } -\def\MPcolor#1{\ctxlua{tex.sprint(colors.mp(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1}))}} +\def\MPcolor#1{\ctxlua{tex.sprint(_clib_.mp(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1}))}} \let\currentcolorname\s!black % todo \let\outercolorname \s!black % todo @@ -1006,18 +1005,18 @@ \def\thecolorattribute #1{\number\csname(ca:\ifcsname(ca:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ca:#1)\endcsname#1\fi\fi)\endcsname} \def\thetransparencyattribute#1{\number\csname(ta:\ifcsname(ta:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ta:#1)\endcsname#1\fi\fi)\endcsname} -\def\internalspotcolorname #1{\ctxlua{tex.sprint(colors.spotcolorname (\thecolorattribute{#1}))}} -\def\internalspotcolorparent#1{\ctxlua{tex.sprint(colors.spotcolorparent(\thecolorattribute{#1}))}} -\def\internalspotcolorsize #1{\ctxlua{tex.sprint(colors.spotcolorvalue (\thecolorattribute{#1}))}} +\def\internalspotcolorname #1{\ctxlua{tex.sprint(_clib_.spotcolorname (\thecolorattribute{#1}))}} +\def\internalspotcolorparent#1{\ctxlua{tex.sprint(_clib_.spotcolorparent(\thecolorattribute{#1}))}} +\def\internalspotcolorsize #1{\ctxlua{tex.sprint(_clib_.spotcolorvalue (\thecolorattribute{#1}))}} -\def\colorcomponents #1{\ctxlua{tex.sprint(colors.colorcomponents (\thecolorattribute {#1}))}} -\def\transparencycomponents#1{\ctxlua{tex.sprint(colors.transparencycomponents(\thetransparencyattribute{#1}))}} +\def\colorcomponents #1{\ctxlua{tex.sprint(_clib_.colorcomponents (\thecolorattribute {#1}))}} +\def\transparencycomponents#1{\ctxlua{tex.sprint(_clib_.transparencycomponents(\thetransparencyattribute{#1}))}} -\def\colorvalue#1{\ctxlua{tex.sprint(colors.formatcolor(\thecolorattribute{#1},"\colorformatseparator"))}} -\def\grayvalue #1{\ctxlua{tex.sprint(colors.formatgray (\thecolorattribute{#1},"\colorformatseparator"))}} +\def\colorvalue#1{\ctxlua{tex.sprint(_clib_.formatcolor(\thecolorattribute{#1},"\colorformatseparator"))}} +\def\grayvalue #1{\ctxlua{tex.sprint(_clib_.formatgray (\thecolorattribute{#1},"\colorformatseparator"))}} -\def\doifblackelse #1{\ctxlua{commands.doifelse(colors.isblack(\thecolorattribute{#1}))}} -\def\doifdrawingblackelse {\ctxlua{commands.doifelse(colors.isblack(tex.attribute[attributes.numbers['color']]))}} +\def\doifblackelse #1{\ctxlua{commands.doifelse(_clib_.isblack(\thecolorattribute{#1}))}} +\def\doifdrawingblackelse {\ctxlua{commands.doifelse(_clib_.isblack(tex.attribute[attributes.numbers['color']]))}} %D \macros %D {forcecolorhack} diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 08307b0d5..81baf2923 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -37,4 +37,12 @@ \let\\=\crlf +% for a while + +\startluacode + jobregisters = logs.obsolete("jobregisters", "structures.registers") + buffers.finish_state = logs.obsolete("buffers.finish_state","buffers.finishstate") + buffers.change_state = logs.obsolete("buffers.change_state","buffers.finishstate") +\stopluacode + \protect \endinput diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index b59c65679..b9f8747dd 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2010.08.10 17:14} +\newcontextversion{2010.08.19 01:08} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 9590eb652..1cf1aeacc 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -87,11 +87,10 @@ \loadmarkfile{core-var} \loadmarkfile{back-ini} -\loadmarkfile{lpdf-ini} % some day back-ini will load this -\loadmarkfile{lpdf-pdx} % might be merged into lpdf-ini -\loadmarkfile{back-pdf} % some day back-ini will load this -\loadmarkfile{attr-div} % code will move +\loadmarkfile{attr-col} +\loadmarkfile{attr-lay} +\loadmarkfile{attr-eff} \loadmarkfile{core-env} @@ -264,7 +263,7 @@ \loadmarkfile{typo-spa} \loadmarkfile{typo-krn} -\loadmarkfile{typo-mir} +\loadmarkfile{typo-dir} \loadmarkfile{typo-brk} \loadmarkfile{typo-cap} \loadmarkfile{typo-dig} @@ -277,17 +276,14 @@ \loadmarkfile{prop-ini} \loadmarkfile{prop-lay} -\loadmarkfile{prop-mis} +\loadmarkfile{prop-eff} +\loadmarkfile{prop-neg} \loadmarkfile{mlib-ctx} -\loadmarkfile{mlib-pdf} -\loadmarkfile{mlib-pps} \loadmarkfile{meta-ini} \loadmarkfile{meta-tex} -\loadmarkfile{meta-pdf} \loadmarkfile{meta-fun} - \loadmarkfile{meta-pag} \loadmarkfile{page-flw} @@ -330,7 +326,6 @@ \loadmarkfile{grph-trf} \loadmarkfile{grph-inc} \loadmarkfile{grph-fig} -\loadmarkfile{grph-epd} \loadmarkfile{pack-box} \loadmarkfile{pack-bar} @@ -361,6 +356,14 @@ %usemodule[x][res-08] % rlx runtime conversion %usemodule[x][res-12] % rli external indentification +% now we hook in backend code (needs checking) + +\loadmarkfile{back-pdf} % actually, this one should load the next three +\loadmarkfile{mlib-pdf} +\loadmarkfile{mlib-pps} +\loadmarkfile{grph-epd} +\loadmarkfile{meta-pdf} + \unprotect \setupcurrentlanguage[\s!en] diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 5e3324eb7..27eb2b55e 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2010.08.10 17:14} +\edef\contextversion{2010.08.19 01:08} %D For those who want to use this: diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua index 257de625b..e83f9a487 100644 --- a/tex/context/base/core-con.lua +++ b/tex/context/base/core-con.lua @@ -20,9 +20,16 @@ local floor, date, time, concat = math.floor, os.date, os.time, table.concat local lower, format, rep = string.lower, string.format, string.rep local texsprint, utfchar = tex.sprint, utf.char local tonumber, tostring = tonumber, tostring +local settings_to_array = utilities.parsers.settings_to_array local ctxcatcodes = tex.ctxcatcodes +converters = converters or { } +local converters = converters + +languages = languages or { } +local languages = languages + local function flush(...) texsprint(ctxcatcodes,...) end @@ -40,9 +47,6 @@ function converters.numberst(n,direct) return direct and n or flush(n) end -converters = converters or { } -languages = languages or { } - --~ ['arabic-digits'] = { --~ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, --~ 0x0665, 0x0666, 0x0667, 0x0668, 0x0669 @@ -630,7 +634,7 @@ storage.register("converters/sequences", converters.sequences, "converters.seque local sequences = converters.sequences function converters.define(name,set) - sequences[name] = aux.settings_to_array(set) + sequences[name] = settings_to_array(set) end function converters.convert(method,n,direct) -- todo: language diff --git a/tex/context/base/core-ctx.lua b/tex/context/base/core-ctx.lua index 1dad7c2d7..b1427f0e0 100644 --- a/tex/context/base/core-ctx.lua +++ b/tex/context/base/core-ctx.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['core-ctx'] = { local trace_prepfiles = false trackers.register("resolvers.prepfiles", function(v) trace_prepfiles = v end) -commands = commands or { } +commands = commands or { } +local commands = commands local list, suffix, islocal, found = { }, "prep", false, false diff --git a/tex/context/base/core-fil.mkiv b/tex/context/base/core-fil.mkiv index 31cf22458..14856fc0f 100644 --- a/tex/context/base/core-fil.mkiv +++ b/tex/context/base/core-fil.mkiv @@ -115,7 +115,7 @@ %D can \type {\end} in modules. \def\dodousemodules#1#2% - {\ctxlua{support.usemodules("#1","#2","\truefilename{#2}")}} + {\ctxlua{commands.usemodules("#1","#2","\truefilename{#2}")}} \def\usemodules {\dotripleempty\dousemodules} diff --git a/tex/context/base/core-job.lua b/tex/context/base/core-job.lua index d557818bb..f58344f93 100644 --- a/tex/context/base/core-job.lua +++ b/tex/context/base/core-job.lua @@ -11,6 +11,8 @@ local ctxcatcodes, texcatcodes = tex.ctxcatcodes, tex.texcatcodes local lower, format, find, gmatch, gsub, match = string.lower, string.format, string.find, string.gmatch, string.gsub, string.match local concat = table.concat +local commands, resolvers = commands, resolvers + -- main code resolvers.maxreadlevel = 3 diff --git a/tex/context/base/core-sys.lua b/tex/context/base/core-sys.lua index c5aa89d98..e4e49762d 100644 --- a/tex/context/base/core-sys.lua +++ b/tex/context/base/core-sys.lua @@ -8,6 +8,8 @@ if not modules then modules = { } end modules ['core-sys'] = { local lower, extname, basename, removesuffix = string.lower, file.extname, file.basename, file.removesuffix +local environment = environment + function commands.updatefilenames(inputfilename,outputfilename) environment.inputfilename = inputfilename or "" environment.outputfilename = outputfilename or "" diff --git a/tex/context/base/core-two.lua b/tex/context/base/core-two.lua index 24a3191a7..67bf2fc03 100644 --- a/tex/context/base/core-two.lua +++ b/tex/context/base/core-two.lua @@ -15,9 +15,12 @@ local texprint = tex.print bit of a mess because we support old and new methods.</p> --ldx]]-- -jobpasses = jobpasses or { } -jobpasses.collected = jobpasses.collected or { } -jobpasses.tobesaved = jobpasses.tobesaved or { } +local jobpasses = { + collected = { }, + tobesaved = { }, +} + +job.passes = jobpasses local collected, tobesaved = jobpasses.collected, jobpasses.tobesaved @@ -25,7 +28,7 @@ local function initializer() collected, tobesaved = jobpasses.collected, jobpasses.tobesaved end -job.register('jobpasses.collected', jobpasses.tobesaved, initializer, nil) +job.register('job.passes.collected', jobpasses.tobesaved, initializer, nil) local function allocate(id) local p = tobesaved[id] diff --git a/tex/context/base/core-two.mkiv b/tex/context/base/core-two.mkiv index 2cc9412af..332b2c89b 100644 --- a/tex/context/base/core-two.mkiv +++ b/tex/context/base/core-two.mkiv @@ -79,11 +79,11 @@ %D I'm not that sure if this behaves exactly like mkii. This needs a cleanup. -\def\immediatesavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlua {jobpasses.save('#1',"#3")}}} -\def\savetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobpasses.save('#1',"#3")}}} -\def\lazysavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobpasses.save('#1',"#3")}}} -\def\savetaggedtwopassdata #1#2#3#4{\normalexpanded{\noexpand\ctxlua {jobpasses.savetagged('#1','#3',"#4")}}} -\def\lazysavetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\ctxlatelua{jobpasses.savetagged('#1','#3',"#4")}}} +\def\immediatesavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlua {job.passes.save('#1',"#3")}}} +\def\savetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{job.passes.save('#1',"#3")}}} +\def\lazysavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{job.passes.save('#1',"#3")}}} +\def\savetaggedtwopassdata #1#2#3#4{\normalexpanded{\noexpand\ctxlua {job.passes.savetagged('#1','#3',"#4")}}} +\def\lazysavetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\ctxlatelua{job.passes.savetagged('#1','#3',"#4")}}} % temp hack: needs a proper \starteverytimeluacode @@ -91,15 +91,15 @@ % todo: move the edef to lua -\unexpanded\def\definetwopasslist #1{\ctxlua{jobpasses.define('#1')}} -\def\gettwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.get("#1")}}\testtwopassdata} -\def\checktwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.check("#1")}}\testtwopassdata} -\def\findtwopassdata #1#2{\edef\twopassdata{\ctxlua{jobpasses.find("#1","#2")}}\testtwopassdata} -\def\getfirsttwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.first("#1")}}\testtwopassdata} -\def\getlasttwopassdata #1{\edef\twopassdata{\ctxlua{jobpasses.last("#1")}}\edef\noftwopassitems{\ctxlua{jobpasses.count("#1")}}\testtwopassdata} -\def\getnamedtwopassdatalist#1#2{\edef#1{\ctxlua{jobpasses.list("#2")}}} -\def\gettwopassdatalist #1{\edef\twopassdatalist{\ctxlua{jobpasses.list("#1")}}} -\def\doifelseintwopassdata #1#2{\ctxlua{jobpasses.doifinlistelse("#1","#2")}} +\unexpanded\def\definetwopasslist #1{\ctxlua{job.passes.define('#1')}} +\def\gettwopassdata #1{\edef\twopassdata{\ctxlua{job.passes.get("#1")}}\testtwopassdata} +\def\checktwopassdata #1{\edef\twopassdata{\ctxlua{job.passes.check("#1")}}\testtwopassdata} +\def\findtwopassdata #1#2{\edef\twopassdata{\ctxlua{job.passes.find("#1","#2")}}\testtwopassdata} +\def\getfirsttwopassdata #1{\edef\twopassdata{\ctxlua{job.passes.first("#1")}}\testtwopassdata} +\def\getlasttwopassdata #1{\edef\twopassdata{\ctxlua{job.passes.last("#1")}}\edef\noftwopassitems{\ctxlua{job.passes.count("#1")}}\testtwopassdata} +\def\getnamedtwopassdatalist#1#2{\edef#1{\ctxlua{job.passes.list("#2")}}} +\def\gettwopassdatalist #1{\edef\twopassdatalist{\ctxlua{job.passes.list("#1")}}} +\def\doifelseintwopassdata #1#2{\ctxlua{job.passes.doifinlistelse("#1","#2")}} \let\getfromtwopassdata\findtwopassdata diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index 2a8f31364..538feb959 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -17,16 +17,20 @@ utility file under different setups, we now load a table once. This saves much runtime but at the cost of more memory usage.</p> --ldx]]-- -local sort, concat, format, match = table.sort, table.concat, string.format, string.match +local format, match = string.format, string.match local next, type, tostring = next, type, tostring local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local definetable, accesstable = utilities.tables.definetable, utilities.tables.accesstable +local serialize = table.serialize local report_jobcontrol = logs.new("jobcontrol") if not jobs then jobs = { } end if not job then jobs['main'] = { } end job = jobs['main'] -jobs.version = 1.10 +local packers = utilities.packers + +jobs.version = 1.14 --[[ldx-- <p>Variables are saved using in the previously defined table and passed @@ -43,7 +47,7 @@ end job.comment(format("version: %1.2f",jobs.version)) function job.initialize(loadname,savename) - job.load(loadname) + job.load(loadname) -- has to come after structure is defined ! luatex.register_stop_actions(function() if not status.lasterrorstring or status.lasterrorstring == "" then job.save(savename) @@ -57,15 +61,18 @@ end -- as an example we implement variables -jobvariables = jobvariables or { } -jobvariables.collected = jobvariables.collected or { } -jobvariables.tobesaved = jobvariables.tobesaved or { } -jobvariables.checksums = jobvariables.checksums or { } +local jobvariables = { + collected = { }, + tobesaved = { }, + checksums = { }, +} + +job.variables = jobvariables if not jobvariables.checksums.old then jobvariables.checksums.old = md5.HEX("old") end -- used in experiment if not jobvariables.checksums.new then jobvariables.checksums.new = md5.HEX("new") end -- used in experiment -job.register('jobvariables.checksums', jobvariables.checksums) +job.register('job.variables.checksums', jobvariables.checksums) local function initializer() local r = jobvariables.collected.randomseed @@ -83,112 +90,12 @@ local function initializer() end end -job.register('jobvariables.collected', jobvariables.tobesaved, initializer) +job.register('job.variables.collected', jobvariables.tobesaved, initializer) function jobvariables.save(cs,value) jobvariables.tobesaved[cs] = value end --- experiment (bugged: some loop in running) - --- for the moment here, very experimental stuff - -packer = packer or { } -packer.version = 1.00 - -local function hashed(t) - local s = { } - for k, v in next, t do - if type(v) == "table" then - s[#s+1] = k.."={"..hashed(v).."}" - else - s[#s+1] = k.."="..tostring(v) - end - end - sort(s) - return concat(s,",") -end - -local function pack(t,keys,hash,index) - for k,v in next, t do - if type(v) == "table" then - pack(v,keys,hash,index) - end - if keys[k] and type(v) == "table" then - local h = hashed(v) - local i = hash[h] - if not i then - i = #index+1 - index[i] = v - hash[h] = i - end - t[k] = i - end - end -end - -local function unpack(t,keys,index) - for k,v in next, t do - if keys[k] and type(v) == "number" then - local iv = index[v] - if iv then - v = iv - t[k] = v - end - end - if type(v) == "table" then - unpack(v,keys,index) - end - end -end - -function packer.new(keys,version) - return { - version = version or packer.version, - keys = table.tohash(keys), - hash = { }, - index = { }, - } -end - -function packer.pack(t,p,shared) - if shared then - pack(t,p.keys,p.hash,p.index) - elseif not t.packer then - pack(t,p.keys,p.hash,p.index) - if #p.index > 0 then - t.packer = { - version = p.version or packer.version, - keys = p.keys, - index = p.index, - } - end - p.hash, p.index = { }, { } - end -end - -function packer.unpack(t,p,shared) - if shared then - if p then - unpack(t,p.keys,p.index) - end - else - local tp = t.packer - if tp then - if tp.version == (p and p.version or packer.version) then - unpack(t,tp.keys,tp.index) - else - -- fatal error, wrong version - end - t.packer = nil - end - end -end - -function packer.strip(p) - p.hash = nil -end - local packlist = { "numbers", "metadata", @@ -199,10 +106,10 @@ local packlist = { "directives", "specification", "processors", -- might become key under directives or metadata --- "references", -- we need to rename of them as only one packs (not structure.lists.references) +-- "references", -- we need to rename of them as only one packs (not structures.lists.references) } -local jobpacker = packer.new(packlist,1.01) +local jobpacker = packers.new(packlist,1.01) job.pack = true @@ -223,14 +130,14 @@ function job.save(filename) finalizer() end if job.pack then - packer.pack(data,jobpacker,true) + packers.pack(data,jobpacker,true) end - f:write(aux.definetable(target),"\n") - f:write(table.serialize(data,target,true,true),"\n") + f:write(definetable(target),"\n") + f:write(serialize(data,target,true,true),"\n") end if job.pack then - packer.strip(jobpacker) - f:write(table.serialize(jobpacker,"job.packer",true,true),"\n") + packers.strip(jobpacker) + f:write(serialize(jobpacker,"job.packed",true,true),"\n") end f:close() end @@ -252,12 +159,12 @@ function job.load(filename) for l=1,#savelist do local list = savelist[l] local target, initializer = list[1], list[3] - packer.unpack(aux.accesstable(target),job.packer,true) + packers.unpack(accesstable(target),job.packed,true) if type(initializer) == "function" then - initializer(aux.accesstable(target)) + initializer(accesstable(target)) end end - job.packer = nil + job.packed = nil end end statistics.stoptiming(job._load_) diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv index d16d33ce0..46a1e398a 100644 --- a/tex/context/base/core-uti.mkiv +++ b/tex/context/base/core-uti.mkiv @@ -18,7 +18,7 @@ \registerctxluafile{core-uti}{1.001} \def\savecurrentvalue#1#2% - {\ctxlua{jobvariables.save("\strippedcsname#1","#2")}} + {\ctxlua{job.variables.save("\strippedcsname#1","#2")}} \appendtoks \ctxlua { diff --git a/tex/context/base/data-aux.lua b/tex/context/base/data-aux.lua index 06322a848..943bf0a52 100644 --- a/tex/context/base/data-aux.lua +++ b/tex/context/base/data-aux.lua @@ -11,6 +11,8 @@ local type, next = type, next local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) +local resolvers = resolvers + local report_resolvers = logs.new("resolvers") function resolvers.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix diff --git a/tex/context/base/data-bin.lua b/tex/context/base/data-bin.lua index 5e4397a54..f25b423e1 100644 --- a/tex/context/base/data-bin.lua +++ b/tex/context/base/data-bin.lua @@ -6,9 +6,12 @@ if not modules then modules = { } end modules ['data-bin'] = { license = "see context related readme files" } -local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local unpack = unpack or table.unpack +local resolvers = resolvers + +local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders + function resolvers.findbinfile(filename, filetype) return resolvers.methodhandler('finders',filename, filetype) end diff --git a/tex/context/base/data-con.lua b/tex/context/base/data-con.lua index 0c16571cb..a38440fbf 100644 --- a/tex/context/base/data-con.lua +++ b/tex/context/base/data-con.lua @@ -25,8 +25,8 @@ table structures without bothering about the disk cache.</p> <p>Examples of usage can be found in the font related code.</p> --ldx]]-- -containers = containers or { } - +containers = containers or { } +local containers = containers containers.usecache = true local report_cache = logs.new("cache") diff --git a/tex/context/base/data-crl.lua b/tex/context/base/data-crl.lua index b83e59bdf..8fa947191 100644 --- a/tex/context/base/data-crl.lua +++ b/tex/context/base/data-crl.lua @@ -8,11 +8,15 @@ if not modules then modules = { } end modules ['data-crl'] = { -- this one is replaced by data-sch.lua -- -curl = curl or { } - local gsub = string.gsub + +local resolvers = resolvers + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +curl = curl or { } +local curl = curl + local cached = { } function curl.fetch(protocol, name) -- todo: use socket library diff --git a/tex/context/base/data-ctx.lua b/tex/context/base/data-ctx.lua index 47f9c527e..30f974131 100644 --- a/tex/context/base/data-ctx.lua +++ b/tex/context/base/data-ctx.lua @@ -10,6 +10,8 @@ local format = string.format local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + function resolvers.save_used_files_in_trees() local jobname = environment.jobname if not jobname or jobname == "" then jobname = "luatex" end diff --git a/tex/context/base/data-env.lua b/tex/context/base/data-env.lua index f3997b989..d1c110e80 100644 --- a/tex/context/base/data-env.lua +++ b/tex/context/base/data-env.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['data-env'] = { license = "see context related readme files", } +local resolvers = resolvers + local formats = { } resolvers.formats = formats local suffixes = { } resolvers.suffixes = suffixes local dangerous = { } resolvers.dangerous = dangerous diff --git a/tex/context/base/data-exp.lua b/tex/context/base/data-exp.lua index 785679275..fb7e48efd 100644 --- a/tex/context/base/data-exp.lua +++ b/tex/context/base/data-exp.lua @@ -20,6 +20,8 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- As this bit of code is somewhat special it gets its own module. After -- all, when working on the main resolver code, I don't want to scroll -- past this every time. diff --git a/tex/context/base/data-ini.lua b/tex/context/base/data-ini.lua index 5805c4301..80a01c588 100644 --- a/tex/context/base/data-ini.lua +++ b/tex/context/base/data-ini.lua @@ -24,7 +24,8 @@ local ostype, osname, ossetenv, osgetenv = os.type, os.name, os.setenv, os.geten -- we now split it over multiple files. As this file is now the -- starting point we introduce resolvers here. -resolvers = resolvers or { } +resolvers = resolvers or { } +local resolvers = resolvers -- We don't want the kpse library to kick in. Also, we want to be able to -- execute programs. Control over execution is implemented later. diff --git a/tex/context/base/data-inp.lua b/tex/context/base/data-inp.lua index b7354e1ae..45a348b7d 100644 --- a/tex/context/base/data-inp.lua +++ b/tex/context/base/data-inp.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['data-inp'] = { license = "see context related readme files" } +local resolvers = resolvers + resolvers.finders = resolvers.finders or { } resolvers.openers = resolvers.openers or { } resolvers.loaders = resolvers.loaders or { } diff --git a/tex/context/base/data-lst.lua b/tex/context/base/data-lst.lua index 0cea5b4d9..f1463fb45 100644 --- a/tex/context/base/data-lst.lua +++ b/tex/context/base/data-lst.lua @@ -12,6 +12,8 @@ local find, concat, upper, format = string.find, table.concat, string.upper, str resolvers.listers = resolvers.listers or { } +local resolvers = resolvers + local function tabstr(str) if type(str) == 'table' then return concat(str," | ") diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua index d11a066e2..754dbddb5 100644 --- a/tex/context/base/data-lua.lua +++ b/tex/context/base/data-lua.lua @@ -17,6 +17,8 @@ local report_resolvers = logs.new("resolvers") local gsub, insert = string.gsub, table.insert local unpack = unpack or table.unpack +local resolvers, package = resolvers, package + local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' local clibformats = { 'lib' } diff --git a/tex/context/base/data-met.lua b/tex/context/base/data-met.lua index 7f2e612e8..fb9b4d923 100644 --- a/tex/context/base/data-met.lua +++ b/tex/context/base/data-met.lua @@ -12,6 +12,8 @@ local trace_locating = false trackers.register("resolvers.locating", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + resolvers.locators = { notfound = { nil } } -- locate databases resolvers.hashers = { notfound = { nil } } -- load databases resolvers.generators = { notfound = { nil } } -- generate databases diff --git a/tex/context/base/data-out.lua b/tex/context/base/data-out.lua index f73ff9bdc..94c12bd8c 100644 --- a/tex/context/base/data-out.lua +++ b/tex/context/base/data-out.lua @@ -6,5 +6,5 @@ if not modules then modules = { } end modules ['data-out'] = { license = "see context related readme files" } -outputs = outputs or { } +-- not used yet diff --git a/tex/context/base/data-pre.lua b/tex/context/base/data-pre.lua index 391ee2ccd..94992c102 100644 --- a/tex/context/base/data-pre.lua +++ b/tex/context/base/data-pre.lua @@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['data-pre'] = { local upper, lower, gsub = string.upper, string.lower, string.gsub +local resolvers = resolvers + local prefixes = { } local getenv = resolvers.getenv diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index b2a59d753..a9582262f 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -17,6 +17,7 @@ if not modules then modules = { } end modules ['data-res'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local os = os local lpegP, lpegS, lpegR, lpegC, lpegCc, lpegCs, lpegCt = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns @@ -30,10 +31,14 @@ local trace_expansions = false trackers.register("resolvers.expansions", functi local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local expanded_path_from_list = resolvers.expanded_path_from_list local checked_variable = resolvers.checked_variable local split_configuration_path = resolvers.split_configuration_path +local initializesetter = utilities.setters.initialize + local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.setenv, os.getenv resolvers.cacheversion = '1.0.1' @@ -255,7 +260,7 @@ local function load_configuration_files() t[k] = v elseif kind == "table" then -- this operates on the table directly - setters.initialize(filename,k,v) + initializesetter(filename,k,v) -- this doesn't (maybe metatables some day) for kk, vv in next, v do -- vv = variable if vv ~= unset_variable then diff --git a/tex/context/base/data-sch.lua b/tex/context/base/data-sch.lua index 28f18389e..232722749 100644 --- a/tex/context/base/data-sch.lua +++ b/tex/context/base/data-sch.lua @@ -15,15 +15,17 @@ local trace_schemes = false trackers.register("resolvers.schemes",function(v) t local report_schemes = logs.new("schemes") -schemes = schemes or { } +local resolvers = resolvers +resolvers.schemes = resolvers.schemes or { } +local schemes = resolvers.schemes schemes.threshold = 24 * 60 * 60 directives.register("schemes.threshold", function(v) schemes.threshold = tonumber(v) or schemes.threshold end) local cached, loaded, reused = { }, { }, { } -function schemes.curl(name,cachename) +function schemes.curl(name,cachename) -- will use sockets instead or the curl library local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name -- no protocol .. "://" os.spawn(command) end diff --git a/tex/context/base/data-tex.lua b/tex/context/base/data-tex.lua index 727964d1f..d597b26a2 100644 --- a/tex/context/base/data-tex.lua +++ b/tex/context/base/data-tex.lua @@ -15,8 +15,12 @@ local trace_locating = false trackers.register("resolvers.locating", function(v) local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +local checkgarbage = utilities.garbagecollector and utilities.garbagecollector.check + function finders.generic(tag,filename,filetype) local foundname = resolvers.find_file(filename,filetype) if foundname and foundname ~= "" then @@ -135,7 +139,7 @@ function openers.text_opener(filename,file_handle,tag) logs.show_close(filename) file_handle:close() t = nil - collectgarbage("step") -- saves some memory + collectgarbage("step") -- saves some memory, maybe checkgarbage but no # end, handle = function() return file_handle @@ -175,7 +179,9 @@ function loaders.generic(tag,filename) report_resolvers("%s loader, file '%s' loaded",tag,filename) end local s = f:read("*a") - if garbagecollector and garbagecollector.check then garbagecollector.check(#s) end + if checkgarbage then + checkgarbage(#s) + end f:close() if s then return true, s, #s diff --git a/tex/context/base/data-tmf.lua b/tex/context/base/data-tmf.lua index c26f8e6e6..d98e0ec66 100644 --- a/tex/context/base/data-tmf.lua +++ b/tex/context/base/data-tmf.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local resolvers = resolvers + -- = << -- ? ?? -- < += diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua index 664e9ccff..ebb5c3e5e 100644 --- a/tex/context/base/data-tmp.lua +++ b/tex/context/base/data-tmp.lua @@ -28,11 +28,13 @@ local mkdirs, isdir = dir.mkdirs, lfs.isdir local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end) -local report_cache = logs.new("cache") - +local report_cache = logs.new("cache") local report_resolvers = logs.new("resolvers") -caches = caches or { } +local resolvers = resolvers + +caches = caches or { } +local caches = caches caches.base = caches.base or "luatex-cache" caches.more = caches.more or "context" @@ -277,7 +279,7 @@ function caches.savedata(filepath,filename,data,raw) end local cleanup = resolvers.boolean_variable("PURGECACHE", false) local strip = resolvers.boolean_variable("LUACSTRIP", true) - utils.lua.compile(tmaname, tmcname, cleanup, strip) + utilities.lua.compile(tmaname, tmcname, cleanup, strip) end -- moved from data-res: @@ -339,7 +341,7 @@ function caches.savecontent(cachename,dataname,content) if trace_locating then report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname) end - if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip + if utilities.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip if trace_locating then report_resolvers("'%s' compiled to '%s'",dataname,lucname) end diff --git a/tex/context/base/data-tre.lua b/tex/context/base/data-tre.lua index 75cb39c3a..cfa8e3c5d 100644 --- a/tex/context/base/data-tre.lua +++ b/tex/context/base/data-tre.lua @@ -13,6 +13,8 @@ local unpack = unpack or table.unpack local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + local done, found, notfound = { }, { }, resolvers.finders.notfound function resolvers.finders.tree(specification,filetype) diff --git a/tex/context/base/data-use.lua b/tex/context/base/data-use.lua index 1093a4ac7..3d2dbe190 100644 --- a/tex/context/base/data-use.lua +++ b/tex/context/base/data-use.lua @@ -12,6 +12,8 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local report_resolvers = logs.new("resolvers") +local resolvers = resolvers + -- we will make a better format, maybe something xml or just text or lua resolvers.automounted = resolvers.automounted or { } diff --git a/tex/context/base/data-zip.lua b/tex/context/base/data-zip.lua index a43a19b3f..1b261c45e 100644 --- a/tex/context/base/data-zip.lua +++ b/tex/context/base/data-zip.lua @@ -19,15 +19,20 @@ local report_resolvers = logs.new("resolvers") -- zip:///texmf.zip?tree=/tex/texmf-local -- zip:///texmf-mine.zip?tree=/tex/texmf-projects -zip = zip or { } -zip.archives = zip.archives or { } -zip.registeredfiles = zip.registeredfiles or { } +local resolvers = resolvers + +zip = zip or { } +local zip = zip + +zip.archives = zip.archives or { } +local archives = zip.archives + +zip.registeredfiles = zip.registeredfiles or { } +local registeredfiles = zip.registeredfiles local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local locators, hashers, concatinators = resolvers.locators, resolvers.hashers, resolvers.concatinators -local archives = zip.archives - local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str @@ -191,7 +196,7 @@ function resolvers.usezipfile(zipname) zipname = validzip(zipname) local specification = resolvers.splitmethod(zipname) local zipfile = specification.path - if zipfile and not zip.registeredfiles[zipname] then + if zipfile and not registeredfiles[zipname] then local tree = url.query(specification.query).tree or "" local z = zip.openarchive(zipfile) if z then @@ -202,7 +207,7 @@ function resolvers.usezipfile(zipname) statistics.starttiming(instance) resolvers.prepend_hash('zip',zipname,zipfile) resolvers.extend_texmf_var(zipname) -- resets hashes too - zip.registeredfiles[zipname] = z + registeredfiles[zipname] = z instance.files[zipname] = resolvers.register_zip_file(z,tree or "") statistics.stoptiming(instance) elseif trace_locating then diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua index 75b3cddef..e29363c11 100644 --- a/tex/context/base/font-afm.lua +++ b/tex/context/base/font-afm.lua @@ -23,26 +23,31 @@ local trace_loading = false trackers.register("afm.loading", function(v) trac local report_afm = logs.new("load afm") +local next, type = next, type local format, match, gmatch, lower, gsub = string.format, string.match, string.gmatch, string.lower, string.gsub local lpegmatch = lpeg.match local abs = math.abs -fonts = fonts or { } -fonts.afm = fonts.afm or { } +local fonts = fonts +fonts.afm = fonts.afm or { } -local afm = fonts.afm -local tfm = fonts.tfm +local afm = fonts.afm +local tfm = fonts.tfm afm.version = 1.402 -- incrementing this number one up will force a re-cache afm.syncspace = true -- when true, nicer stretch values afm.enhance_data = true -- best leave this set to true -afm.features = { } -afm.features.aux = { } -afm.features.data = { } -afm.features.list = { } -afm.features.default = { } afm.cache = containers.define("fonts", "afm", afm.version, true) +local afmfeatures = { + aux = { }, + data = { }, + list = { }, + default = { }, +} + +afm.features = afmfeatures + --[[ldx-- <p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/> and <l n='otf'/> reader.</p> @@ -64,11 +69,13 @@ built in <l n='tfm'/> and <l n='otf'/> reader.</p> --~ Comment DELIM 2390 1010 --~ Comment AXISHEIGHT 250 -local c = lpeg.P("Comment") -local s = lpeg.S(" \t") -local l = lpeg.S("\n\r") -local w = lpeg.C((1 - l)^1) -local n = lpeg.C((lpeg.R("09") + lpeg.S("."))^1) / tonumber * s^0 +local P, S, C = lpeg.P, lpeg.S, lpeg.C + +local c = P("Comment") +local s = S(" \t") +local l = S("\n\r") +local w = C((1 - l)^1) +local n = C((lpeg.R("09") + S("."))^1) / tonumber * s^0 local fd = { } @@ -253,6 +260,8 @@ by adding ligatures and kern information to the afm derived data. That way we can set them faster when defining a font.</p> --ldx]]-- +local add_kerns, add_ligatures, unify -- we will implement these later + function afm.load(filename) -- hm, for some reasons not resolved yet filename = resolvers.find_file(filename,'afm') or "" @@ -284,14 +293,14 @@ function afm.load(filename) report_afm("no pfb file for %s",filename) end report_afm( "unifying %s",filename) - afm.unify(data,filename) + unify(data,filename) if afm.enhance_data then report_afm( "add ligatures") - afm.add_ligatures(data,'ligatures') -- easier this way + add_ligatures(data,'ligatures') -- easier this way report_afm( "add tex-ligatures") - afm.add_ligatures(data,'texligatures') -- easier this way + add_ligatures(data,'texligatures') -- easier this way report_afm( "add extra kerns") - afm.add_kerns(data) -- faster this way + add_kerns(data) -- faster this way end report_afm( "add tounicode data") fonts.map.add_to_unicode(data,filename) @@ -311,7 +320,7 @@ function afm.load(filename) end end -function afm.unify(data, filename) +unify = function(data, filename) local unicodevector = fonts.enc.load('unicode').hash local glyphs, indices, unicodes, names = { }, { }, { }, { } local verbose, private = fonts.verbose, fonts.private @@ -361,7 +370,7 @@ end and extra kerns. This saves quite some lookups later.</p> --ldx]]-- -function afm.add_ligatures(afmdata,ligatures) +add_ligatures = function(afmdata,ligatures) local glyphs, luatex = afmdata.glyphs, afmdata.luatex local indices, unicodes, names = luatex.indices, luatex.unicodes, luatex.names for k,v in next, characters[ligatures] do -- main characters table @@ -389,7 +398,7 @@ end them selectively.</p> --ldx]]-- -function afm.add_kerns(afmdata) +add_kerns = function(afmdata) local glyphs = afmdata.glyphs local names = afmdata.luatex.names local uncomposed = characters.uncomposed @@ -449,7 +458,7 @@ end -- once we have otf sorted out (new format) we can try to make the afm -- cache similar to it (similar tables) -function afm.add_dimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name +local function add_dimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name if data then for index, glyph in next, data.glyphs do local bb = glyph.boundingbox @@ -594,11 +603,13 @@ to treat this fontformat like any other and handle features in a more configurable way.</p> --ldx]]-- -function afm.features.register(name,default) - afm.features.list[#afm.features.list+1] = name - afm.features.default[name] = default +local function register_feature(name,default) + afmfeatures.list[#afmfeatures.list+1] = name + afmfeatures.default[name] = default end +afmfeatures.register = register_feature + function afm.set_features(tfmdata) local shared = tfmdata.shared local afmdata = shared.afmdata @@ -611,7 +622,7 @@ function afm.set_features(tfmdata) if fiafm then local lists = { fonts.triggers, - afm.features.list, + afmfeatures.list, fonts.manipulators, } for l=1,3 do @@ -636,7 +647,7 @@ function afm.set_features(tfmdata) local fmafm = fm and fm.afm if fmafm then local lists = { - afm.features.list, + afmfeatures.list, } local sp = shared.processors for l=1,1 do @@ -660,7 +671,7 @@ function afm.set_features(tfmdata) end function afm.check_features(specification) - local features, done = fonts.define.check(specification.features.normal,afm.features.default) + local features, done = fonts.define.check(specification.features.normal,afmfeatures.default) if done then specification.features.normal = features tfm.hash_instance(specification,true) @@ -693,13 +704,14 @@ function afm.afm_to_tfm(specification) if not tfmdata then local afmdata = afm.load(afmname) if afmdata and next(afmdata) then - afm.add_dimensions(afmdata) + add_dimensions(afmdata) tfmdata = afm.copy_to_tfm(afmdata) if tfmdata and next(tfmdata) then - tfmdata.shared = tfmdata.shared or { } - tfmdata.unique = tfmdata.unique or { } - tfmdata.shared.afmdata = afmdata - tfmdata.shared.features = features + local shared = tfmdata.shared + local unique = tfmdata.unique + if not shared then shared = { } tfmdata.shared = shared end + if not unique then unique = { } tfmdata.unique = unique end + shared.afmdata, shared.features = afmdata, features afm.set_features(tfmdata) end elseif trace_loading then @@ -723,9 +735,17 @@ tfm.default_encoding = 'unicode' function tfm.set_normal_feature(specification,name,value) if specification and name then - specification.features = specification.features or { } - specification.features.normal = specification.features.normal or { } - specification.features.normal[name] = value + local features = specification.features + if not features then + features = { } + specification.features = features + end + local normalfeatures = features.normal + if normalfeatures then + normalfeatures[name] = value + else + features.normal = { [name] = value } + end end end @@ -745,7 +765,7 @@ end those that make sense for this format.</p> --ldx]]-- -function afm.features.prepare_ligatures(tfmdata,ligatures,value) +local function prepare_ligatures(tfmdata,ligatures,value) if value then local afmdata = tfmdata.shared.afmdata local luatex = afmdata.luatex @@ -774,7 +794,7 @@ function afm.features.prepare_ligatures(tfmdata,ligatures,value) end end -function afm.features.prepare_kerns(tfmdata,kerns,value) +local function prepare_kerns(tfmdata,kerns,value) if value then local afmdata = tfmdata.shared.afmdata local luatex = afmdata.luatex @@ -800,59 +820,68 @@ function afm.features.prepare_kerns(tfmdata,kerns,value) end end --- hm, register? - -function fonts.initializers.base.afm.ligatures (tfmdata,value) afm.features.prepare_ligatures(tfmdata,'ligatures', value) end -function fonts.initializers.base.afm.texligatures(tfmdata,value) afm.features.prepare_ligatures(tfmdata,'texligatures',value) end -function fonts.initializers.base.afm.kerns (tfmdata,value) afm.features.prepare_kerns (tfmdata,'kerns', value) end -function fonts.initializers.base.afm.extrakerns (tfmdata,value) afm.features.prepare_kerns (tfmdata,'extrakerns', value) end - -afm.features.register('liga',true) -afm.features.register('kerns',true) -afm.features.register('extrakerns') -- needed? +afmfeatures.prepare_kerns = prepare_kerns +afmfeatures.prepare_ligatures = prepare_ligatures -fonts.initializers.node.afm.ligatures = fonts.initializers.base.afm.ligatures -fonts.initializers.node.afm.texligatures = fonts.initializers.base.afm.texligatures -fonts.initializers.node.afm.kerns = fonts.initializers.base.afm.kerns -fonts.initializers.node.afm.extrakerns = fonts.initializers.base.afm.extrakerns - -fonts.initializers.base.afm.liga = fonts.initializers.base.afm.ligatures -fonts.initializers.node.afm.liga = fonts.initializers.base.afm.ligatures -fonts.initializers.base.afm.tlig = fonts.initializers.base.afm.texligatures -fonts.initializers.node.afm.tlig = fonts.initializers.base.afm.texligatures - -fonts.initializers.base.afm.trep = tfm.replacements -fonts.initializers.node.afm.trep = tfm.replacements +-- hm, register? -afm.features.register('tlig',true) -- todo: also proper features for afm -afm.features.register('trep',true) -- todo: also proper features for afm +local base_initializers = fonts.initializers.base.afm +local node_initializers = fonts.initializers.node.afm +local common_initializers = fonts.initializers.common + +local function ligatures (tfmdata,value) prepare_ligatures(tfmdata,'ligatures', value) end +local function texligatures(tfmdata,value) prepare_ligatures(tfmdata,'texligatures',value) end +local function kerns (tfmdata,value) prepare_kerns (tfmdata,'kerns', value) end +local function extrakerns (tfmdata,value) prepare_kerns (tfmdata,'extrakerns', value) end + +register_feature('liga',true) +register_feature('kerns',true) +register_feature('extrakerns') -- needed? + +base_initializers.ligatures = ligatures +node_initializers.ligatures = ligatures +base_initializers.texligatures = texligatures +node_initializers.texligatures = texligatures +base_initializers.kerns = kerns +node_initializers.kerns = kerns +node_initializers.extrakerns = extrakerns +base_initializers.extrakerns = extrakerns + +base_initializers.liga = ligatures +node_initializers.liga = ligatures +base_initializers.tlig = texligatures +node_initializers.tlig = texligatures +base_initializers.trep = tfm.replacements +node_initializers.trep = tfm.replacements + +register_feature('tlig',true) -- todo: also proper features for afm +register_feature('trep',true) -- todo: also proper features for afm -- tfm features -fonts.initializers.base.afm.equaldigits = fonts.initializers.common.equaldigits -fonts.initializers.node.afm.equaldigits = fonts.initializers.common.equaldigits -fonts.initializers.base.afm.lineheight = fonts.initializers.common.lineheight -fonts.initializers.node.afm.lineheight = fonts.initializers.common.lineheight +base_initializers.equaldigits = common_initializers.equaldigits +node_initializers.equaldigits = common_initializers.equaldigits +base_initializers.lineheight = common_initializers.lineheight +node_initializers.lineheight = common_initializers.lineheight -- vf features -fonts.initializers.base.afm.compose = fonts.initializers.common.compose -fonts.initializers.node.afm.compose = fonts.initializers.common.compose +base_initializers.compose = common_initializers.compose +node_initializers.compose = common_initializers.compose -- afm specific, encodings ...kind of obsolete -afm.features.register('encoding') +register_feature('encoding') -fonts.initializers.base.afm.encoding = fonts.initializers.common.encoding -fonts.initializers.node.afm.encoding = fonts.initializers.common.encoding +base_initializers.encoding = common_initializers.encoding +node_initializers.encoding = common_initializers.encoding -- todo: oldstyle smallcaps as features for afm files (use with care) -fonts.initializers.base.afm.onum = fonts.initializers.common.oldstyle -fonts.initializers.base.afm.smcp = fonts.initializers.common.smallcaps -fonts.initializers.base.afm.fkcp = fonts.initializers.common.fakecaps - -afm.features.register('onum',false) -afm.features.register('smcp',false) -afm.features.register('fkcp',false) +base_initializers.onum = common_initializers.oldstyle +base_initializers.smcp = common_initializers.smallcaps +base_initializers.fkcp = common_initializers.fakecaps +register_feature('onum',false) +register_feature('smcp',false) +register_feature('fkcp',false) diff --git a/tex/context/base/font-agl.lua b/tex/context/base/font-agl.lua index 8a087b123..3eac792d7 100644 --- a/tex/context/base/font-agl.lua +++ b/tex/context/base/font-agl.lua @@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['font-map'] = { comment = "Adobe Glyph List, version 2.0, September 20, 2002", } -fonts = fonts or { } -fonts.map = fonts.map or { } +local fonts = fonts +fonts.map = fonts.map or { } fonts.map.unicode_to_agl = { "controlSTX", diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua index dc13a4aee..4e6f2cd9e 100644 --- a/tex/context/base/font-chk.lua +++ b/tex/context/base/font-chk.lua @@ -10,13 +10,15 @@ if not modules then modules = { } end modules ['font-chk'] = { local report_fonts = logs.new("fonts") -fonts = fonts or { } -fonts.checkers = fonts.checkers or { } +local fonts = fonts +fonts.checkers = fonts.checkers or { } local checkers = fonts.checkers + local fontdata = fonts.ids local is_character = characters.is_character local chardata = characters.data +local tasks = nodes.tasks local glyph = node.id('glyph') local traverse_id = node.traverse_id diff --git a/tex/context/base/font-cid.lua b/tex/context/base/font-cid.lua index 84d676782..55b84e4ee 100644 --- a/tex/context/base/font-cid.lua +++ b/tex/context/base/font-cid.lua @@ -14,11 +14,12 @@ local trace_loading = false trackers.register("otf.loading", function(v) t local report_otf = logs.new("load otf") -fonts = fonts or { } -fonts.cid = fonts.cid or { } -fonts.cid.map = fonts.cid.map or { } -fonts.cid.max = fonts.cid.max or 10 +local fonts = fonts +fonts.cid = fonts.cid or { } +local cid = fonts.cid +cid.map = cid.map or { } +cid.max = cid.max or 10 -- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap -- @@ -27,12 +28,14 @@ fonts.cid.max = fonts.cid.max or 10 -- 1..95 0020 -- 99 3000 -local number = lpeg.C(lpeg.R("09","af","AF")^1) -local space = lpeg.S(" \n\r\t") +local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C + +local number = C(R("09","af","AF")^1) +local space = S(" \n\r\t") local spaces = space^0 -local period = lpeg.P(".") +local period = P(".") local periods = period * period -local name = lpeg.P("/") * lpeg.C((1-space)^1) +local name = P("/") * C((1-space)^1) local unicodes, names = { }, { } @@ -60,7 +63,7 @@ local grammar = lpeg.P { "start", named = (number * spaces * name) / do_name } -function fonts.cid.load(filename) +function cid.load(filename) local data = io.loaddata(filename) if data then unicodes, names = { }, { } @@ -81,23 +84,22 @@ end local template = "%s-%s-%s.cidmap" - local function locate(registry,ordering,supplement) local filename = format(template,registry,ordering,supplement) local hashname = lower(filename) - local cidmap = fonts.cid.map[hashname] + local cidmap = cid.map[hashname] if not cidmap then if trace_loading then report_otf("checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename) end local fullname = resolvers.find_file(filename,'cid') or "" if fullname ~= "" then - cidmap = fonts.cid.load(fullname) + cidmap = cid.load(fullname) if cidmap then if trace_loading then report_otf("using cidmap file %s",filename) end - fonts.cid.map[hashname] = cidmap + cid.map[hashname] = cidmap cidmap.usedname = file.basename(filename) return cidmap end @@ -106,7 +108,7 @@ local function locate(registry,ordering,supplement) return cidmap end -function fonts.cid.getmap(registry,ordering,supplement) +function cid.getmap(registry,ordering,supplement) -- cf Arthur R. we can safely scan upwards since cids are downward compatible local supplement = tonumber(supplement) if trace_loading then @@ -116,8 +118,8 @@ function fonts.cid.getmap(registry,ordering,supplement) if not cidmap then local cidnum = nil -- next highest (alternatively we could start high) - if supplement < fonts.cid.max then - for supplement=supplement+1,fonts.cid.max do + if supplement < cid.max then + for supplement=supplement+1,cid.max do local c = locate(registry,ordering,supplement) if c then cidmap, cidnum = c, supplement @@ -139,8 +141,8 @@ function fonts.cid.getmap(registry,ordering,supplement) if cidmap and cidnum > 0 then for s=0,cidnum-1 do filename = format(template,registry,ordering,s) - if not fonts.cid.map[filename] then - fonts.cid.map[filename] = cidmap -- copy of ref + if not cid.map[filename] then + cid.map[filename] = cidmap -- copy of ref end end end diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua index af72ff0da..357567d14 100644 --- a/tex/context/base/font-col.lua +++ b/tex/context/base/font-col.lua @@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['font-col'] = { local format, gmatch, texsprint, type = string.format, string.gmatch, tex.sprint, type local traverse_id, first_character = node.traverse_id, node.first_character local lpegmatch = lpeg.match +local settings_to_hash = utilities.parsers.settings_to_hash local ctxcatcodes = tex.ctxcatcodes @@ -18,19 +19,20 @@ local trace_collecting = false trackers.register("fonts.collecting", function(v local report_fonts = logs.new("fonts") -local fontdata = fonts.ids +local fonts = fonts -local glyph = node.id('glyph') +fonts.collections = fonts.collections or { } +local collections = fonts.collections + +collections.definitions = collections.definitions or { } +local definitions = collections.definitions -fonts.normalizers = fonts.normalizers or { } +collections.vectors = collections.vectors or { } +local vectors = collections.vectors -fonts.collections = fonts.collections or { } -fonts.collections.definitions = fonts.collections.definitions or { } -fonts.collections.vectors = fonts.collections.vectors or { } +local fontdata = fonts.ids -local collections = fonts.collections -local definitions = fonts.collections.definitions -local vectors = fonts.collections.vectors +local glyph = node.id('glyph') local list, current, active = { }, 0, false @@ -65,7 +67,7 @@ function collections.define(name,font,ranges,details) d = { } definitions[name] = d end - details = aux.settings_to_hash(details) + details = settings_to_hash(details) -- todo, combine per font start/stop as arrays for s in gmatch(ranges,"([^, ]+)") do local start, stop, description = characters.getrange(s) diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index a6945e39d..727142db2 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['font-ctx'] = { local texsprint, count, texsetcount = tex.sprint, tex.count, tex.setcount local format, concat, gmatch, match, find, lower, gsub, byte = string.format, table.concat, string.gmatch, string.match, string.find, string.lower, string.gsub, string.byte +local settings_to_hash, hash_to_string = utilities.parsers.settings_to_hash, utilities.parsers.hash_to_string +local formatcolumns = utilities.formatters.formatcolumns local tostring, next, type = tostring, next, type local lpegmatch = lpeg.match @@ -25,6 +27,7 @@ local report_define = logs.new("define fonts") local report_usage = logs.new("fonts usage") local report_mapfiles = logs.new("mapfiles") +local fonts = fonts local tfm = fonts.tfm local define = fonts.define local fontdata = fonts.identifiers @@ -76,7 +79,6 @@ storage.register("fonts/merged", define.specify.context_merged, "fonts.define storage.register("fonts/synonyms", define.specify.synonyms, "fonts.define.specify.synonyms") local normalize_meanings = fonts.otf.meanings.normalize -local settings_to_hash = aux.settings_to_hash local default_features = fonts.otf.features.default local function preset_context(name,parent,features) -- currently otf only @@ -307,7 +309,7 @@ end specify.split_context = split_context function specify.context_tostring(name,kind,separator,yes,no,strict,omit) -- not used - return aux.hash_to_string(table.merged(fonts[kind].features.default or {},setups[name] or {}),separator,yes,no,strict,omit) + return hash_to_string(table.merged(fonts[kind].features.default or {},setups[name] or {}),separator,yes,no,strict,omit) end function specify.starred(features) -- no longer fallbacks here @@ -687,7 +689,7 @@ function fonts.report_defined_fonts() data.hash or "", } end - aux.formatcolumns(t," ") + formatcolumns(t," ") report_usage() report_usage("defined fonts:") report_usage() @@ -711,7 +713,7 @@ function fonts.report_used_features() t[#t+1] = { i, name, table.sequenced(setup,false,true) } -- simple mode setup.number = n -- restore it (normally not needed as we're done anyway) end - aux.formatcolumns(t," ") + formatcolumns(t," ") report_usage() report_usage("defined featuresets:") report_usage() diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index e3c7d934a..a466ca655 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -24,34 +24,33 @@ local report_afm = logs.new("load afm") default loader that only handles <l n='tfm'/>.</p> --ldx]]-- -fonts = fonts or { } -fonts.define = fonts.define or { } -fonts.tfm = fonts.tfm or { } -fonts.ids = fonts.ids or { } -fonts.vf = fonts.vf or { } -fonts.used = fonts.used or { } +local fonts = fonts +local tfm = fonts.tfm +local vf = fonts.vf +local fontids = fonts.ids -local tfm = fonts.tfm -local vf = fonts.vf -local define = fonts.define +fonts.used = fonts.used or { } -tfm.version = 1.01 -tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm +tfm.readers = tfm.readers or { } +tfm.fonts = tfm.fonts or { } +tfm.internalized = tfm.internalized or { } -- internal tex numbers -define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm -define.specify = fonts.define.specify or { } -define.methods = fonts.define.methods or { } +local readers = tfm.readers +local sequence = { 'otf', 'ttf', 'afm', 'tfm' } +readers.sequence = sequence -tfm.fonts = tfm.fonts or { } -tfm.readers = tfm.readers or { } -tfm.internalized = tfm.internalized or { } -- internal tex numbers +tfm.version = 1.01 +tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm +tfm.auto_afm = true -tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' } +fonts.define = fonts.define or { } +local define = fonts.define -tfm.auto_afm = true +define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm +define.specify = define.specify or { } +define.methods = define.methods or { } -local readers = tfm.readers -local sequence = readers.sequence +local findbinfile = resolvers.findbinfile --[[ldx-- <p>We hardly gain anything when we cache the final (pre scaled) @@ -127,10 +126,6 @@ function define.makespecification(specification, lookup, name, sub, method, deta specification, (lookup ~= "" and lookup) or "[file]", (name ~= "" and name) or "-", (sub ~= "" and sub) or "-", (method ~= "" and method) or "-", (detail ~= "" and detail) or "-") end ---~ if specification.lookup then ---~ lookup = specification.lookup -- can come from xetex [] syntax ---~ specification.lookup = nil ---~ end if not lookup or lookup == "" then lookup = define.defaultlookup end @@ -210,7 +205,7 @@ function tfm.hash_instance(specification,force) specification.hash = hash end if size < 1000 and fonts.designsizes[hash] then - size = math.round(tfm.scaled(size, fonts.designsizes[hash])) + size = math.round(tfm.scaled(size,fonts.designsizes[hash])) specification.size = size end --~ local mathsize = specification.mathsize or 0 @@ -234,11 +229,12 @@ end <p>We can resolve the filename using the next function:</p> --ldx]]-- -define.resolvers = resolvers +define.resolvers = define.resolvers or { } +local resolvers = define.resolvers -- todo: reporter -function define.resolvers.file(specification) +function resolvers.file(specification) local suffix = file.suffix(specification.name) if fonts.formats[suffix] then specification.forced = suffix @@ -246,7 +242,7 @@ function define.resolvers.file(specification) end end -function define.resolvers.name(specification) +function resolvers.name(specification) local resolve = fonts.names.resolve if resolve then local resolved, sub = fonts.names.resolve(specification.name,specification.sub) @@ -261,11 +257,11 @@ function define.resolvers.name(specification) end end else - define.resolvers.file(specification) + resolvers.file(specification) end end -function define.resolvers.spec(specification) +function resolvers.spec(specification) local resolvespec = fonts.names.resolvespec if resolvespec then specification.resolved, specification.sub = fonts.names.resolvespec(specification.name,specification.sub) @@ -274,13 +270,13 @@ function define.resolvers.spec(specification) specification.name = file.removesuffix(specification.resolved) end else - define.resolvers.name(specification) + resolvers.name(specification) end end function define.resolve(specification) if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash - local r = define.resolvers[specification.lookup] + local r = resolvers[specification.lookup] if r then r(specification) end @@ -290,7 +286,7 @@ function define.resolve(specification) else specification.forced = specification.forced end - -- for the moment here (goodies eset outside features) + -- for the moment here (goodies set outside features) local goodies = specification.goodies if goodies and goodies ~= "" then local normalgoodies = specification.features.normal.goodies @@ -402,9 +398,9 @@ evolved. Each one has its own way of dealing with its format.</p> local function check_tfm(specification,fullname) -- ofm directive blocks local path search unless set; btw, in context we -- don't support ofm files anyway as this format is obsolete - local foundname = resolvers.findbinfile(fullname, 'tfm') or "" -- just to be sure + local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure if foundname == "" then - foundname = resolvers.findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context + foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context end if foundname ~= "" then specification.filename, specification.format = foundname, "ofm" @@ -413,11 +409,11 @@ local function check_tfm(specification,fullname) end local function check_afm(specification,fullname) - local foundname = resolvers.findbinfile(fullname, 'afm') or "" -- just to be sure + local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure if foundname == "" and tfm.auto_afm then local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* if encoding and shortname and fonts.enc.known[encoding] then - shortname = resolvers.findbinfile(shortname,'afm') or "" -- just to be sure + shortname = findbinfile(shortname,'afm') or "" -- just to be sure if shortname ~= "" then foundname = shortname -- tfm.set_normal_feature(specification,'encoding',encoding) -- will go away @@ -481,17 +477,17 @@ local function check_otf(forced,specification,suffix,what) if forced then name = file.addsuffix(name,suffix,true) end - local fullname, tfmtable = resolvers.findbinfile(name,suffix) or "", nil -- one shot + local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot if fullname == "" then local fb = fonts.names.old_to_new[name] if fb then - fullname = resolvers.findbinfile(fb,suffix) or "" + fullname = findbinfile(fb,suffix) or "" end end if fullname == "" then local fb = fonts.names.new_to_old[name] if fb then - fullname = resolvers.findbinfile(fb,suffix) or "" + fullname = findbinfile(fb,suffix) or "" end end if fullname ~= "" then @@ -650,7 +646,7 @@ function vf.find(name) if trace_defining then report_define("locating vf for %s",name) end - return resolvers.findbinfile(name,"ovf") + return findbinfile(name,"ovf") else if trace_defining then report_define("vf for %s is already taken care of",name) @@ -661,7 +657,7 @@ function vf.find(name) if trace_defining then report_define("locating vf for %s",name) end - return resolvers.findbinfile(name,"ovf") + return findbinfile(name,"ovf") end end diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua index 71dea4327..648ccf4fb 100644 --- a/tex/context/base/font-enc.lua +++ b/tex/context/base/font-enc.lua @@ -14,7 +14,6 @@ them in tables. But we may do so some day, for consistency.</p> --ldx]]-- fonts.enc = fonts.enc or { } - local enc = fonts.enc enc.version = 1.03 diff --git a/tex/context/base/font-enh.lua b/tex/context/base/font-enh.lua index 31f2b2387..7a585a7d1 100644 --- a/tex/context/base/font-enh.lua +++ b/tex/context/base/font-enh.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-enh'] = { license = "see context related readme files" } +-- todo: optimize a bit + local next, match = next, string.match local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) @@ -21,7 +23,8 @@ local report_define = logs.new("define fonts") <p>Here we only implement a few helper functions.</p> --ldx]]-- -local tfm = fonts.tfm +local fonts = fonts +local tfm = fonts.tfm --[[ldx-- <p>The next function encapsulates the standard <l n='tfm'/> loader as diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua index 5ae5e7ba7..9888a578e 100644 --- a/tex/context/base/font-ext.lua +++ b/tex/context/base/font-ext.lua @@ -10,6 +10,7 @@ local utf = unicode.utf8 local next, type, byte = next, type, string.byte local gmatch, concat = string.gmatch, table.concat local utfchar = utf.char +local getparameters = utilities.parsers.getparameters local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) @@ -24,19 +25,28 @@ will depend of the font format. Here we define the few that are kind of neutral.</p> --ldx]]-- -fonts.triggers = fonts.triggers or { } -fonts.initializers = fonts.initializers or { } -fonts.methods = fonts.methods or { } -fonts.initializers.common = fonts.initializers.common or { } +local fonts = fonts -local initializers = fonts.initializers -local methods = fonts.methods +fonts.triggers = fonts.triggers or { } +local triggers = fonts.triggers + +fonts.methods = fonts.methods or { } +local methods = fonts.methods + +fonts.manipulators = fonts.manipulators or { } +local manipulators = fonts.manipulators + +fonts.initializers = fonts.initializers or { } +local initializers = fonts.initializers +initializers.common = initializers.common or { } + +local otf = fonts.otf --[[ldx-- <p>This feature will remove inter-digit kerns.</p> --ldx]]-- -table.insert(fonts.triggers,"equaldigits") +table.insert(triggers,"equaldigits") function initializers.common.equaldigits(tfmdata,value) if value then @@ -56,7 +66,7 @@ values are <type>none</type>, <type>height</type>, <type>depth</type> and <type>both</type>.</p> --ldx]]-- -table.insert(fonts.triggers,"lineheight") +table.insert(triggers,"lineheight") function initializers.common.lineheight(tfmdata,value) if value and type(value) == "string" then @@ -114,20 +124,21 @@ end -- expansion (hz) -- -- -- -- -- -- -fonts.expansions = fonts.expansions or { } -fonts.expansions.classes = fonts.expansions.classes or { } -fonts.expansions.vectors = fonts.expansions.vectors or { } +fonts.expansions = fonts.expansions or { } +local expansions = fonts.expansions -local expansions = fonts.expansions -local classes = fonts.expansions.classes -local vectors = fonts.expansions.vectors +expansions.classes = expansions.classes or { } +expansions.vectors = expansions.vectors or { } + +local classes = expansions.classes +local vectors = expansions.vectors -- beware, pdftex itself uses percentages * 10 classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } function commands.setupfontexpansion(class,settings) - aux.getparameters(classes,class,'preset',settings) + getparameters(classes,class,'preset',settings) end classes['quality'] = { @@ -204,7 +215,7 @@ function initializers.common.expansion(tfmdata,value) end end -table.insert(fonts.manipulators,"expansion") +table.insert(manipulators,"expansion") initializers.base.otf.expansion = initializers.common.expansion initializers.node.otf.expansion = initializers.common.expansion @@ -220,20 +231,21 @@ local report_opbd = logs.new("otf opbd") -- protrusion -- -- -- -- -- -- -fonts.protrusions = fonts.protrusions or { } -fonts.protrusions.classes = fonts.protrusions.classes or { } -fonts.protrusions.vectors = fonts.protrusions.vectors or { } +fonts.protrusions = fonts.protrusions or { } +local protrusions = fonts.protrusions + +protrusions.classes = protrusions.classes or { } +protrusions.vectors = protrusions.vectors or { } -local protrusions = fonts.protrusions -local classes = fonts.protrusions.classes -local vectors = fonts.protrusions.vectors +local classes = protrusions.classes +local vectors = protrusions.vectors -- the values need to be revisioned classes.preset = { factor = 1, left = 1, right = 1 } function commands.setupfontprotrusion(class,settings) - aux.getparameters(classes,class,'preset',settings) + getparameters(classes,class,'preset',settings) end classes['pure'] = { @@ -489,7 +501,7 @@ function initializers.common.protrusion(tfmdata,value) end end -table.insert(fonts.manipulators,"protrusion") +table.insert(manipulators,"protrusion") initializers.base.otf.protrusion = initializers.common.protrusion initializers.node.otf.protrusion = initializers.common.protrusion @@ -505,12 +517,12 @@ function initializers.common.nostackmath(tfmdata,value) tfmdata.ignore_stack_math = value end -table.insert(fonts.manipulators,"nostackmath") +table.insert(manipulators,"nostackmath") initializers.base.otf.nostackmath = initializers.common.nostackmath initializers.node.otf.nostackmath = initializers.common.nostackmath -table.insert(fonts.triggers,"itlc") +table.insert(triggers,"itlc") function initializers.common.itlc(tfmdata,value) if value then @@ -541,7 +553,7 @@ initializers.node.afm.itlc = initializers.common.itlc -- slanting -table.insert(fonts.triggers,"slant") +table.insert(triggers,"slant") function initializers.common.slant(tfmdata,value) value = tonumber(value) @@ -561,7 +573,7 @@ initializers.node.otf.slant = initializers.common.slant initializers.base.afm.slant = initializers.common.slant initializers.node.afm.slant = initializers.common.slant -table.insert(fonts.triggers,"extend") +table.insert(triggers,"extend") function initializers.common.extend(tfmdata,value) value = tonumber(value) @@ -584,9 +596,11 @@ initializers.node.afm.extend = initializers.common.extend -- historic stuff, move from font-ota local delete_node = nodes.delete -local glyph = node.id("glyph") local fontdata = fonts.ids +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph + fonts.strippables = fonts.strippables or { -- just a placeholder [0x200C] = true, -- zwnj [0x200D] = true, -- zwj @@ -599,7 +613,7 @@ local function processformatters(head,font) if how == nil or how == "strip" then -- nil when forced local current, done = head, false while current do - if current.id == glyph and current.subtype<256 and current.font == font then + if current.id == glyph_code and current.subtype<256 and current.font == font then local char = current.char if strippables[char] then head, current = delete_node(head,current) @@ -624,4 +638,4 @@ fonts.otf.tables.features['formatters'] = 'Hide Formatting Characters' fonts.otf.features.register("formatters") -table.insert(fonts.manipulators,"formatters") -- at end +table.insert(manipulators,"formatters") -- at end diff --git a/tex/context/base/font-fbk.lua b/tex/context/base/font-fbk.lua index 3341a1e72..d4692e341 100644 --- a/tex/context/base/font-fbk.lua +++ b/tex/context/base/font-fbk.lua @@ -14,20 +14,25 @@ local trace_combining = false trackers.register("fonts.combining", function(v) <p>This is very experimental code!</p> --ldx]]-- +local fonts = fonts +local vf = fonts.vf +local tfm = fonts.tfm + fonts.fallbacks = fonts.fallbacks or { } +local fallbacks = fonts.fallbacks +local commands = vf.aux.combine.commands -local vf = fonts.vf -local tfm = fonts.tfm +local push, pop = { "push" }, { "pop" } -vf.aux.combine.commands["enable-tracing"] = function(g,v) +commands["enable-tracing"] = function(g,v) trace_combining = true end -vf.aux.combine.commands["disable-tracing"] = function(g,v) +commands["disable-tracing"] = function(g,v) trace_combining = false end -vf.aux.combine.commands["set-tracing"] = function(g,v) +commands["set-tracing"] = function(g,v) if v[2] == nil then trace_combining = true else @@ -35,53 +40,70 @@ vf.aux.combine.commands["set-tracing"] = function(g,v) end end -function vf.aux.combine.initialize_trace() - if trace_combining then - return "special", "pdf: .8 0 0 rg .8 0 0 RG", "pdf: 0 .8 0 rg 0 .8 0 RG", "pdf: 0 0 .8 rg 0 0 .8 RG", "pdf: 0 g 0 G" - else - return "comment", "", "", "", "" - end -end +local force_fallback = false -vf.aux.combine.force_fallback = false - -vf.aux.combine.commands["fake-character"] = function(g,v) -- g, nr, fallback_id +commands["fake-character"] = function(g,v) -- g, nr, fallback_id local index, fallback = v[2], v[3] - if vf.aux.combine.force_fallback or not g.characters[index] then - if fonts.fallbacks[fallback] then - g.characters[index], g.descriptions[index] = fonts.fallbacks[fallback](g) - end + if (force_fallback or not g.characters[index]) and fallbacks[fallback] then + g.characters[index], g.descriptions[index] = fallbacks[fallback](g) end end -fonts.fallbacks['textcent'] = function (g) +fallbacks['textcent'] = function (g) local c = ("c"):byte() local t = table.fastcopy(g.characters[c]) local a = - tan(rad(g.italicangle or 0)) - local special, red, green, blue, black = vf.aux.combine.initialize_trace() + local vfspecials = backends.tables.vfspecials + local green, black + if trace_combining then + green, black = vfspecials.green, vfspecials.black + end + local startslant, stopslant = vfspecials.startslant, vfspecials.stopslant local quad = g.parameters.quad if a == 0 then - t.commands = { - {"push"}, {"slot", 1, c}, {"pop"}, - {"right", .5*t.width}, - {"down", .2*t.height}, - {special, green}, - {"rule", 1.4*t.height, .02*quad}, - {special, black}, - } + if trace_combining then + t.commands = { + push, {"slot", 1, c}, pop, + {"right", .5*t.width}, + {"down", .2*t.height}, + green, + {"rule", 1.4*t.height, .02*quad}, + black, + } + else + t.commands = { + push, {"slot", 1, c}, pop, + {"right", .5*t.width}, + {"down", .2*t.height}, + {"rule", 1.4*t.height, .02*quad}, + } + end else - t.commands = { - {"push"}, - {"right", .5*t.width-.025*quad}, - {"down", .2*t.height}, - {"special",format("pdf: q 1 0 %s 1 0 0 cm",a)}, - {special, green}, - {"rule", 1.4*t.height, .025*quad}, - {special, black}, - {"special","pdf: Q"}, - {"pop"}, - {"slot", 1, c} -- last else problems with cm - } + if trace_combining then + t.commands = { + push, + {"right", .5*t.width-.025*quad}, + {"down", .2*t.height}, + startslant(a), + green, + {"rule", 1.4*t.height, .025*quad}, + black, + stopslant, + pop, + {"slot", 1, c} -- last else problems with cm + } + else + t.commands = { + push, + {"right", .5*t.width-.025*quad}, + {"down", .2*t.height}, + startslant(a), + {"rule", 1.4*t.height, .025*quad}, + stopslant, + pop, + {"slot", 1, c} -- last else problems with cm + } + end end -- somehow the width is messed up now -- todo: set height @@ -92,31 +114,43 @@ fonts.fallbacks['textcent'] = function (g) return t, d and d[c] end -fonts.fallbacks['texteuro'] = function (g) +fallbacks['texteuro'] = function (g) local c = ("C"):byte() local t = table.fastcopy(g.characters[c]) local d = cos(rad(90+(g.italicangle))) - local special, red, green, blue, black = vf.aux.combine.initialize_trace() + local vfspecials = backends.tables.vfspecials + local green, black + if trace_combining then + green, black = vfspecials.green, vfspecials.black + end local quad = g.parameters.quad t.width = 1.05*t.width - t.commands = { - {"right", .05*t.width}, - {"push"}, {"slot", 1, c}, {"pop"}, - {"right", .5*t.width*d}, - {"down", -.5*t.height}, - {special, green}, - {"rule", .05*quad, .4*quad}, - {special, black}, - } + if trace_combining then + t.commands = { + {"right", .05*t.width}, + push, {"slot", 1, c}, pop, + {"right", .5*t.width*d}, + {"down", -.5*t.height}, + green, + {"rule", .05*quad, .4*quad}, + black, + } + else + t.commands = { + {"right", .05*t.width}, + push, {"slot", 1, c}, pop, + {"right", .5*t.width*d}, + {"down", -.5*t.height}, + {"rule", .05*quad, .4*quad}, + } + end g.virtualized = true return t, g.descriptions[c] end -- maybe store llx etc instead of bbox in tfm blob / more efficient -vf.aux.combine.force_composed = false - -local push, pop = { "push" }, { "pop" } +local force_composed = false local cache = { } -- we could make these weak @@ -130,16 +164,15 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location local scale = g.factor or 1 local cap_lly = scale*xdesc.boundingbox[4] local ita_cor = cos(rad(90+(g.italicangle or 0))) - local force = vf.aux.combine.force_composed local fallbacks = characters.fallbacks - local special, red, green, blue, black + local vfspecials = backends.tables.vfspecials + local red, green, blue, black if trace_combining then - special, red, green, blue, black = vf.aux.combine.initialize_trace() - red, green, blue, black = { special, red }, { special, green }, { special, blue }, { special, black } + red, green, blue, black = vfspecials.red, vfspecials.green, vfspecials.blue, vfspecials.black end local done = false for i,c in next, characters.data do - if force or not chars[i] then + if force_composed or not chars[i] then local s = c.specials if s and s[1] == 'char' then local chr = s[2] @@ -155,14 +188,14 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location end end local charsacc = chars[acc] ---~ local ca = charsacc.category ---~ if ca == "mn" then ---~ -- mark nonspacing ---~ elseif ca == "ms" then ---~ -- mark spacing combining ---~ elseif ca == "me" then ---~ -- mark enclosing ---~ else + --~ local ca = charsacc.category + --~ if ca == "mn" then + --~ -- mark nonspacing + --~ elseif ca == "ms" then + --~ -- mark spacing combining + --~ elseif ca == "me" then + --~ -- mark enclosing + --~ else if not charsacc then acc = fallbacks[acc] charsacc = acc and chars[acc] @@ -232,20 +265,20 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location else if trace_combining then t.commands = { - {"push"}, + push, {"right", dx+dd}, blue, acc_t, black, - {"pop"}, + pop, chr_t, } else t.commands = { - {"push"}, + push, {"right", dx+dd}, acc_t, - {"pop"}, + pop, chr_t, } end @@ -272,7 +305,7 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location end end -vf.aux.combine.commands["complete-composed-characters"] = function(g,v) +commands["complete-composed-characters"] = function(g,v) vf.aux.compose_characters(g) end @@ -284,21 +317,24 @@ end -- for documentation purposes we provide: -fonts.define.methods.install("fallback", { -- todo: auto-fallback with loop over data.characters +commands["enable-force"] = function(g,v) + force_composed = true + force_fallback = true +end + +commands["disable-force"] = function(g,v) + force_composed = false + force_fallback = false +end + +local install = fonts.define.methods.install + +install("fallback", { -- todo: auto-fallback with loop over data.characters { "fake-character", 0x00A2, 'textcent' }, { "fake-character", 0x20AC, 'texteuro' } }) -vf.aux.combine.commands["enable-force"] = function(g,v) - vf.aux.combine.force_composed = true - vf.aux.combine.force_fallback = true -end -vf.aux.combine.commands["disable-force"] = function(g,v) - vf.aux.combine.force_composed = false - vf.aux.combine.force_fallback = false -end - -fonts.define.methods.install("demo-2", { +install("demo-2", { { "enable-tracing" }, { "enable-force" }, { "initialize" }, @@ -308,7 +344,7 @@ fonts.define.methods.install("demo-2", { { "disable-force" }, }) -fonts.define.methods.install("demo-3", { +install("demo-3", { { "enable-tracing" }, { "initialize" }, { "complete-composed-characters" }, diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua index 79a1417d3..f25458110 100644 --- a/tex/context/base/font-gds.lua +++ b/tex/context/base/font-gds.lua @@ -17,16 +17,19 @@ local report_fonts = logs.new("fonts") -- -- goodies=auto --- goodies +local fonts, nodes, attributes = fonts, nodes, attributes +local node = node -fonts.goodies = fonts.goodies or { } -fonts.goodies.data = fonts.goodies.data or { } -fonts.goodies.list = fonts.goodies.list or { } +fonts.goodies = fonts.goodies or { } +local fontgoodies = fonts.goodies -local data = fonts.goodies.data -local list = fonts.goodies.list +fontgoodies.data = fontgoodies.data or { } +local data = fontgoodies.data -function fonts.goodies.report(what,trace,goodies) +fontgoodies.list = fontgoodies.list or { } +local list = fontgoodies.list + +function fontgoodies.report(what,trace,goodies) if trace_goodies or trace then local whatever = goodies[what] if whatever then @@ -66,17 +69,17 @@ local function getgoodies(filename) -- maybe a merge is better return goodies end -function fonts.goodies.register(name,fnc) +function fontgoodies.register(name,fnc) list[name] = fnc end -fonts.goodies.get = getgoodies +fontgoodies.get = getgoodies -- register goodies file local preset_context = fonts.define.specify.preset_context -function fonts.initializers.common.goodies(tfmdata,value) +local function set_goodies(tfmdata,value) local goodies = tfmdata.goodies or { } -- future versions might store goodies in the cached instance for filename in gmatch(value,"[^, ]+") do -- we need to check for duplicates @@ -88,6 +91,8 @@ function fonts.initializers.common.goodies(tfmdata,value) tfmdata.goodies = goodies -- shared ? end +-- this will be split into good-* files and this file might become good-ini.lua + -- featuresets local function flattened_features(t,tt) @@ -115,7 +120,7 @@ end fonts.flattened_features = flattened_features -function fonts.goodies.prepare_features(goodies,name,set) +function fontgoodies.prepare_features(goodies,name,set) if set then local ff = flattened_features(set) local fullname = goodies.name .. "::" .. name @@ -136,14 +141,14 @@ local function initialize(goodies,tfmdata) report_fonts("checking featuresets in '%s'",goodies.name) end for name, set in next, featuresets do - fonts.goodies.prepare_features(goodies,name,set) + fontgoodies.prepare_features(goodies,name,set) end end end -fonts.goodies.register("featureset",initialize) +fontgoodies.register("featureset",initialize) -function fonts.initializers.common.featureset(tfmdata,set) +local function set_featureset(tfmdata,set) local goodies = tfmdata.goodies -- shared ? if goodies then local features = tfmdata.shared.features @@ -166,12 +171,11 @@ end -- colorschemes -fonts.goodies.colorschemes = fonts.goodies.colorschemes or { } -fonts.goodies.colorschemes.data = fonts.goodies.colorschemes.data or { } +fontgoodies.colorschemes = fontgoodies.colorschemes or { } +local colorschemes = fontgoodies.colorschemes +colorschemes.data = colorschemes.data or { } -local colorschemes = fonts.goodies.colorschemes - -function fonts.initializers.common.colorscheme(tfmdata,scheme) +local function set_colorscheme(tfmdata,scheme) if type(scheme) == "string" then local goodies = tfmdata.goodies -- todo : check for already defined in shared @@ -211,7 +215,7 @@ local traverse_id = node.traverse_id local a_colorscheme = attributes.private('colorscheme') local glyph = node.id("glyph") -function fonts.goodies.colorschemes.coloring(head) +function colorschemes.coloring(head) local lastfont, lastscheme local done = false for n in traverse_id(glyph,head) do @@ -233,9 +237,9 @@ function fonts.goodies.colorschemes.coloring(head) return head, done end -function fonts.goodies.colorschemes.enable() - tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") - function fonts.goodies.colorschemes.enable() end +function colorschemes.enable() + nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + function colorschemes.enable() end end -- installation (collected to keep the overview) @@ -252,14 +256,17 @@ table.insert(fonts.triggers, 1, "goodies") table.insert(fonts.triggers, 2, "featureset") -- insert after table.insert(fonts.triggers, "colorscheme") -fonts.initializers.base.otf.goodies = fonts.initializers.common.goodies -fonts.initializers.node.otf.goodies = fonts.initializers.common.goodies +local base_initializers = fonts.initializers.base.otf +local node_initializers = fonts.initializers.node.otf + +base_initializers.goodies = set_goodies +node_initializers.goodies = set_goodies -fonts.initializers.base.otf.featureset = fonts.initializers.common.featureset -fonts.initializers.node.otf.featureset = fonts.initializers.common.featureset +base_initializers.featureset = set_featureset +node_initializers.featureset = set_featureset -fonts.initializers.base.otf.colorscheme = fonts.initializers.common.colorscheme -fonts.initializers.node.otf.colorscheme = fonts.initializers.common.colorscheme +base_initializers.colorscheme = set_colorscheme +node_initializers.colorscheme = set_colorscheme -- experiment, we have to load the definitions immediately as they precede -- the definition so they need to be initialized in the typescript @@ -286,7 +293,7 @@ local function initialize(goodies) end end -fonts.goodies.register("mathematics", initialize) +fontgoodies.register("mathematics", initialize) -- The following file (husayni.lfg) is the experimental setup that we used -- for Idris font. For the moment we don't store this in the cache and quite diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua index 290d031f9..210edbbe8 100644 --- a/tex/context/base/font-ini.lua +++ b/tex/context/base/font-ini.lua @@ -17,8 +17,6 @@ local lower = string.lower local report_define = logs.new("define fonts") -if not fontloader then fontloader = fontforge end - fontloader.totable = fontloader.to_table -- vtf comes first @@ -33,6 +31,10 @@ fonts.chr = fonts.chr or { } fonts.characters = fonts.chr -- aka chardata fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata fonts.tfm = fonts.tfm or { } +fonts.vf = fonts.vf or { } +fonts.afm = fonts.afm or { } +fonts.pfb = fonts.pfb or { } +fonts.otf = fonts.otf or { } fonts.private = 0xF0000 -- 0x10FFFF fonts.verbose = false -- more verbose cache tables diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv index abcfba8d8..ef2eadbcb 100644 --- a/tex/context/base/font-ini.mkiv +++ b/tex/context/base/font-ini.mkiv @@ -16,7 +16,8 @@ % simplification ... we no longer deal with specific mmtfa specifications -% todo: always fontclass, then less testing +% todo: always fontclass, then less testing +% todo: bodyfontvariable: parent % \definefontfeature[smallcaps][smcp=yes,script=latn] % \definefontfeature[smallcaps][SmallCapitals=yes,script=latn] @@ -517,6 +518,11 @@ \def\dosetmathfamily#1#2% {\let\savedfontbody\fontbody % op hoger plan \let\fontfamily#2% + % new per 20100817 + \checkbodyfontenvironment[\scriptscriptface]% + \checkbodyfontenvironment[\scriptface]% + \checkbodyfontenvironment[\textface]% + % \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\dodosetmathfamily\scriptscriptfont#1% \let\currentmathsize\!!plustwo \let\fontbody\scriptface \dodosetmathfamily\scriptfont #1% \let\currentmathsize\!!plusone \let\fontbody\textface \dodosetmathfamily\textfont #1% @@ -1465,6 +1471,8 @@ \ifcsname\??ft#2#1\c!em\endcsname % we test for em as we assume it to be set \else + % speeding this up saves 0.01 sec on a run (tested 20100817) + % but some day we will clean this up anyway \def\docommand##1% {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize diff --git a/tex/context/base/font-log.lua b/tex/context/base/font-log.lua index 2e7c53e43..3f9e111b3 100644 --- a/tex/context/base/font-log.lua +++ b/tex/context/base/font-log.lua @@ -12,7 +12,9 @@ local trace_defining = false trackers.register("fonts.defining", function(v) tr local report_define = logs.new("define fonts") +local fonts = fonts fonts.logger = fonts.logger or { } +local logger = fonts.logger --[[ldx-- <p>The following functions are used for reporting about the fonts @@ -21,7 +23,7 @@ we now have several readers it may be handy to know what reader is used for which font.</p> --ldx]]-- -function fonts.logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! ! +function logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! ! if tfmtable and specification and specification.specification then local name = lower(specification.name) if trace_defining and not fonts.used[name] then @@ -34,7 +36,7 @@ function fonts.logger.save(tfmtable,source,specification) -- save file name in s end end -function fonts.logger.report(complete) +function logger.report(complete) local t = { } for name, used in table.sortedhash(fonts.used) do if complete then @@ -46,13 +48,13 @@ function fonts.logger.report(complete) return t end -function fonts.logger.format(name) +function logger.format(name) return fonts.used[name] or "unknown" end statistics.register("loaded fonts", function() if next(fonts.used) then - local t = fonts.logger.report() + local t = logger.report() return (#t > 0 and format("%s files: %s",#t,concat(t," "))) or "none" else return nil diff --git a/tex/context/base/font-map.lua b/tex/context/base/font-map.lua index faf38d7f6..6230ee326 100644 --- a/tex/context/base/font-map.lua +++ b/tex/context/base/font-map.lua @@ -24,8 +24,8 @@ of obsolete. Some code may move to runtime or auxiliary modules.</p> <p>The name to unciode related code will stay of course.</p> --ldx]]-- -fonts = fonts or { } -fonts.map = fonts.map or { } +local fonts = fonts +fonts.map = fonts.map or { } local function load_lum_table(filename) -- will move to font goodies local lumname = file.replacesuffix(file.basename(filename),"lum") @@ -39,15 +39,16 @@ local function load_lum_table(filename) -- will move to font goodies end end -local hex = lpeg.R("AF","09") +local P, R, S, C, Ct, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc + +local hex = R("AF","09") local hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end local hexsix = (hex^1) / function(s) return tonumber(s,16) end -local dec = (lpeg.R("09")^1) / tonumber -local period = lpeg.P(".") - -local unicode = lpeg.P("uni") * (hexfour * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexfour^1) * lpeg.Cc(true)) -local ucode = lpeg.P("u") * (hexsix * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexsix ^1) * lpeg.Cc(true)) -local index = lpeg.P("index") * dec * lpeg.Cc(false) +local dec = (R("09")^1) / tonumber +local period = P(".") +local unicode = P("uni") * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) +local ucode = P("u") * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) +local index = P("index") * dec * Cc(false) local parser = unicode + ucode + index @@ -59,7 +60,7 @@ local function make_name_parser(str) else local p = parsers[str] if not p then - p = lpeg.P(str) * period * dec * lpeg.Cc(false) + p = P(str) * period * dec * Cc(false) parsers[str] = p end return p @@ -126,9 +127,9 @@ fonts.map.make_name_parser = make_name_parser fonts.map.tounicode16 = tounicode16 fonts.map.tounicode16sequence = tounicode16sequence -local separator = lpeg.S("_.") -local other = lpeg.C((1 - separator)^1) -local ligsplitter = lpeg.Ct(other * (separator * other)^0) +local separator = S("_.") +local other = C((1 - separator)^1) +local ligsplitter = Ct(other * (separator * other)^0) --~ print(table.serialize(lpegmatch(ligsplitter,"this"))) --~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua index 0e5b55542..0ec7bac73 100644 --- a/tex/context/base/font-ota.lua +++ b/tex/context/base/font-ota.lua @@ -17,34 +17,37 @@ local trace_cjk = false trackers.register("cjk.injections", function(v) t trackers.register("cjk.analyzing","otf.analyzing") -fonts = fonts or { } -fonts.analyzers = fonts.analyzers or { } -fonts.analyzers.initializers = fonts.analyzers.initializers or { node = { otf = { } } } -fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } } +local fonts, nodes = fonts, nodes +local node = node local otf = fonts.otf local tfm = fonts.tfm -local initializers = fonts.analyzers.initializers -local methods = fonts.analyzers.methods +fonts.analyzers = fonts.analyzers or { } +local analyzers = fonts.analyzers -local glyph = node.id('glyph') -local glue = node.id('glue') -local penalty = node.id('penalty') +analyzers.initializers = analyzers.initializers or { node = { otf = { } } } +analyzers.methods = analyzers.methods or { node = { otf = { } } } + +local initializers = analyzers.initializers +local methods = analyzers.methods + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph local set_attribute = node.set_attribute local has_attribute = node.has_attribute local traverse_id = node.traverse_id local traverse_node_list = node.traverse -local fontdata = fonts.ids -local state = attributes.private('state') +local fontdata = fonts.ids +local state = attributes.private('state') -local fcs = (fonts.color and fonts.color.set) or function() end -local fcr = (fonts.color and fonts.color.reset) or function() end +local fcs = (fonts.color and fonts.color.set) or function() end +local fcr = (fonts.color and fonts.color.reset) or function() end -local a_to_script = otf.a_to_script -local a_to_language = otf.a_to_language +local a_to_script = otf.a_to_script +local a_to_language = otf.a_to_language -- in the future we will use language/script attributes instead of the -- font related value, but then we also need dynamic features which is @@ -98,7 +101,7 @@ table.insert(fonts.triggers,"analyze") -- we need a proper function for doing t -- latin -fonts.analyzers.methods.latn = fonts.analyzers.aux.setstate +analyzers.methods.latn = analyzers.aux.setstate -- this info eventually will go into char-def @@ -180,8 +183,8 @@ local function warning(current,what) end end -function fonts.analyzers.methods.nocolor(head,font,attr) - for n in traverse_node_list(head,glyph) do +function analyzers.methods.nocolor(head,font,attr) + for n in traverse_id(glyph_code,head) do if not font or n.font == font then fcr(n) end @@ -230,12 +233,12 @@ local function finish(first,last) return first, last end -function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace +function analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace local tfmdata = fontdata[font] local marks = tfmdata.marks local first, last, current, done = nil, nil, head, false while current do - if current.id == glyph and current.subtype<256 and current.font == font and not has_attribute(current,state) then + if current.id == glyph_code and current.subtype<256 and current.font == font and not has_attribute(current,state) then done = true local char = current.char if marks[char] then diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua index f76e6686c..7c9a28e38 100644 --- a/tex/context/base/font-otb.lua +++ b/tex/context/base/font-otb.lua @@ -11,8 +11,9 @@ local format, gmatch, gsub, find, match, lower, strip = string.format, string.gm local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match -local otf = fonts.otf -local tfm = fonts.tfm +local fonts = fonts +local otf = fonts.otf +local tfm = fonts.tfm local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end) local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end) @@ -49,7 +50,7 @@ local function gref(descriptions,n) for j=1,#ni do local nj = ni[j] nnum[j] = format("U+%04X",nj) - nnam[j] = descriptions[nj].name or "?" + nnam[j] = descriptions[nj].name or "?" end num[i] = concat(nnum,"|") nam[i] = concat(nnam,"|") diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua index 65688e27f..b57b5b880 100644 --- a/tex/context/base/font-otc.lua +++ b/tex/context/base/font-otc.lua @@ -13,10 +13,10 @@ local type, next = type, next local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) -local report_otf = logs.new("load otf") +local fonts = fonts +local otf = fonts.otf -local otf = fonts.otf -local tfm = fonts.tfm +local report_otf = logs.new("load otf") -- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to -- have always); some day we can write a "force always when true" trick for other @@ -108,11 +108,11 @@ local extra_features = { -- maybe just 1..n so that we prescribe order }, } -fonts.otf.enhancers["add some missing characters"] = function(data,filename) +otf.enhancers["add some missing characters"] = function(data,filename) -- todo end -fonts.otf.enhancers["enrich with features"] = function(data,filename) +otf.enhancers["enrich with features"] = function(data,filename) -- could be done elsewhere (true can be #) local used = { } for i=1,#otf.glists do @@ -195,21 +195,30 @@ fonts.otf.enhancers["enrich with features"] = function(data,filename) end end -otf.tables.features['tlig'] = 'TeX Ligatures' -otf.tables.features['trep'] = 'TeX Replacements' -otf.tables.features['anum'] = 'Arabic Digits' +local features = otf.tables.features + +features['tlig'] = 'TeX Ligatures' +features['trep'] = 'TeX Replacements' +features['anum'] = 'Arabic Digits' -otf.features.register_base_substitution('tlig') -otf.features.register_base_substitution('trep') -otf.features.register_base_substitution('anum') +local register_base_substitution = otf.features.register_base_substitution + +register_base_substitution('tlig') +register_base_substitution('trep') +register_base_substitution('anum') -- the functionality is defined elsewhere -fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits -fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits +local initializers = fonts.initializers +local common_initializers = initializers.common +local base_initializers = initializers.base.otf +local node_initializers = initializers.node.otf + +base_initializers.equaldigits = common_initializers.equaldigits +node_initializers.equaldigits = common_initializers.equaldigits -fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight -fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight +base_initializers.lineheight = common_initializers.lineheight +node_initializers.lineheight = common_initializers.lineheight -fonts.initializers.base.otf.compose = fonts.initializers.common.compose -fonts.initializers.node.otf.compose = fonts.initializers.common.compose +base_initializers.compose = common_initializers.compose +node_initializers.compose = common_initializers.compose diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua index 62522f916..8e770a128 100644 --- a/tex/context/base/font-otd.lua +++ b/tex/context/base/font-otd.lua @@ -6,13 +6,11 @@ if not modules then modules = { } end modules ['font-otd'] = { license = "see context related readme files" } -local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end) +local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end) local report_otf = logs.new("load otf") -fonts = fonts or { } -fonts.otf = fonts.otf or { } - +local fonts = fonts local otf = fonts.otf local fontdata = fonts.ids diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index 5e1117acb..9134f95be 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -62,26 +62,26 @@ involved is not that large. This only makes sense when we have many fonts in a l and don't change to frequently.</p> --ldx]]-- -fonts = fonts or { } -fonts.otf = fonts.otf or { } -fonts.tfm = fonts.tfm or { } +local fonts = fonts +fonts.otf = fonts.otf or { } local otf = fonts.otf local tfm = fonts.tfm local fontdata = fonts.ids -otf.tables = otf.tables or { } -- defined in font-ott.lua -otf.meanings = otf.meanings or { } -- defined in font-ott.lua -otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua -otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua -otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua +--~ otf.tables = otf.tables or { } -- defined in font-ott.lua +--~ otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua +--~ otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua +--~ otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua otf.features = otf.features or { } otf.features.list = otf.features.list or { } otf.features.default = otf.features.default or { } -otf.enhancers = otf.enhancers or { } +otf.enhancers = otf.enhancers or { } +local enhancers = otf.enhancers + otf.glists = { "gsub", "gpos" } otf.version = 2.653 -- beware: also sync font-mis.lua @@ -98,6 +98,8 @@ local default = "dflt" <p>We start with a lot of tables and related functions.</p> --ldx]]-- +-- we can have more local functions + otf.tables.global_fields = table.tohash { "lookups", "glyphs", @@ -192,8 +194,8 @@ local function load_featurefile(ff,featurefile) end end -function otf.enhance(name,data,filename,verbose) - local enhancer = otf.enhancers[name] +local function enhance(name,data,filename,verbose) + local enhancer = enhancers[name] if enhancer then if (verbose ~= nil and verbose) or trace_loading then report_otf("enhance: %s (%s)",name,filename) @@ -202,7 +204,7 @@ function otf.enhance(name,data,filename,verbose) end end -local enhancers = { +local ordered_enhancers = { -- implemented later -- pack and unpack are handled separately; they might even be moved -- away from the enhancers namespace "patch bugs", @@ -222,6 +224,8 @@ local enhancers = { "check math parameters", } +local add_dimensions, show_feature_order -- implemented later + function otf.load(filename,format,sub,featurefile) local name = file.basename(file.removesuffix(filename)) local attr = lfs.attributes(filename) @@ -262,12 +266,12 @@ function otf.load(filename,format,sub,featurefile) if data then report_otf("file size: %s", size) report_otf("enhancing ...") - for e=1,#enhancers do - otf.enhance(enhancers[e],data,filename) + for e=1,#ordered_enhancers do + enhance(ordered_enhancers[e],data,filename) io.flush() -- we want instant messages end if otf.pack and not fonts.verbose then - otf.enhance("pack",data,filename) + enhance("pack",data,filename) end data.size = size data.time = time @@ -288,16 +292,16 @@ function otf.load(filename,format,sub,featurefile) if trace_defining then report_otf("loading from cache: %s",hash) end - otf.enhance("unpack",data,filename,false) -- no message here - otf.add_dimensions(data) + enhance("unpack",data,filename,false) -- no message here + add_dimensions(data) if trace_sequences then - otf.show_feature_order(data,filename) + show_feature_order(data,filename) end end return data end -function otf.add_dimensions(data) +add_dimensions = function(data) -- todo: forget about the width if it's the defaultwidth (saves mem) -- we could also build the marks hash here (instead of storing it) if data then @@ -333,7 +337,7 @@ function otf.add_dimensions(data) end end -function otf.show_feature_order(otfdata,filename) +local function show_feature_order(otfdata,filename) local sequences = otfdata.luatex.sequences if sequences and #sequences > 0 then if trace_loading then @@ -375,7 +379,7 @@ end -- todo: normalize, design_size => designsize -otf.enhancers["reorganize mark classes"] = function(data,filename) +enhancers["reorganize mark classes"] = function(data,filename) if data.mark_classes then local unicodes = data.luatex.unicodes local reverse = { } @@ -398,7 +402,7 @@ otf.enhancers["reorganize mark classes"] = function(data,filename) end end -otf.enhancers["prepare luatex tables"] = function(data,filename) +enhancers["prepare luatex tables"] = function(data,filename) data.luatex = data.luatex or { } local luatex = data.luatex luatex.filename = filename @@ -406,7 +410,7 @@ otf.enhancers["prepare luatex tables"] = function(data,filename) luatex.creator = "context mkiv" end -otf.enhancers["cleanup aat"] = function(data,filename) +enhancers["cleanup aat"] = function(data,filename) if otf.cleanup_aat then end end @@ -434,13 +438,13 @@ local function analyze_features(g, features) return nil end -otf.enhancers["analyse features"] = function(data,filename) +enhancers["analyse features"] = function(data,filename) -- local luatex = data.luatex -- luatex.gposfeatures = analyze_features(data.gpos) -- luatex.gsubfeatures = analyze_features(data.gsub) end -otf.enhancers["rehash features"] = function(data,filename) +enhancers["rehash features"] = function(data,filename) local features = { } data.luatex.features = features for k, what in next, otf.glists do @@ -471,7 +475,7 @@ otf.enhancers["rehash features"] = function(data,filename) end end -otf.enhancers["analyse anchors"] = function(data,filename) +enhancers["analyse anchors"] = function(data,filename) local classes = data.anchor_classes local luatex = data.luatex local anchor_to_lookup, lookup_to_anchor = { }, { } @@ -497,7 +501,7 @@ otf.enhancers["analyse anchors"] = function(data,filename) end end -otf.enhancers["analyse marks"] = function(data,filename) +enhancers["analyse marks"] = function(data,filename) local glyphs = data.glyphs local marks = { } data.luatex.marks = marks @@ -509,9 +513,9 @@ otf.enhancers["analyse marks"] = function(data,filename) end end -otf.enhancers["analyse unicodes"] = fonts.map.add_to_unicode +enhancers["analyse unicodes"] = fonts.map.add_to_unicode -otf.enhancers["analyse subtables"] = function(data,filename) +enhancers["analyse subtables"] = function(data,filename) data.luatex = data.luatex or { } local luatex = data.luatex local sequences = { } @@ -579,7 +583,7 @@ otf.enhancers["analyse subtables"] = function(data,filename) end end -otf.enhancers["merge cid fonts"] = function(data,filename) +enhancers["merge cid fonts"] = function(data,filename) -- we can also move the names to data.luatex.names which might -- save us some more memory (at the cost of harder tracing) if data.subfonts then @@ -633,7 +637,7 @@ otf.enhancers["merge cid fonts"] = function(data,filename) end end -otf.enhancers["prepare unicode"] = function(data,filename) +enhancers["prepare unicode"] = function(data,filename) local luatex = data.luatex if not luatex then luatex = { } data.luatex = luatex end local indices, unicodes, multiples, internals = { }, { }, { }, { } @@ -716,7 +720,7 @@ otf.enhancers["prepare unicode"] = function(data,filename) luatex.private = private end -otf.enhancers["cleanup ttf tables"] = function(data,filename) +enhancers["cleanup ttf tables"] = function(data,filename) local ttf_tables = data.ttf_tables if ttf_tables then for k=1,#ttf_tables do @@ -726,7 +730,7 @@ otf.enhancers["cleanup ttf tables"] = function(data,filename) data.ttf_tab_saved = nil end -otf.enhancers["compact glyphs"] = function(data,filename) +enhancers["compact glyphs"] = function(data,filename) table.compact(data.glyphs) -- needed? if data.subfonts then for _, subfont in next, data.subfonts do @@ -735,7 +739,7 @@ otf.enhancers["compact glyphs"] = function(data,filename) end end -otf.enhancers["reverse coverage"] = function(data,filename) +enhancers["reverse coverage"] = function(data,filename) -- we prefer the before lookups in a normal order if data.lookups then for _, v in next, data.lookups do @@ -751,7 +755,7 @@ otf.enhancers["reverse coverage"] = function(data,filename) end end -otf.enhancers["check italic correction"] = function(data,filename) +enhancers["check italic correction"] = function(data,filename) local glyphs = data.glyphs local ok = false for index, glyph in next, glyphs do @@ -769,7 +773,7 @@ otf.enhancers["check italic correction"] = function(data,filename) data.has_italic = true end -otf.enhancers["check math"] = function(data,filename) +enhancers["check math"] = function(data,filename) if data.math then -- we move the math stuff into a math subtable because we then can -- test faster in the tfm copy @@ -836,7 +840,7 @@ otf.enhancers["check math"] = function(data,filename) end end -otf.enhancers["share widths"] = function(data,filename) +enhancers["share widths"] = function(data,filename) local glyphs = data.glyphs local widths = { } for index, glyph in next, glyphs do @@ -870,7 +874,7 @@ end -- unpredictable alternatively we could force an [1] if not set (maybe I will do that -- anyway). ---~ otf.enhancers["reorganize kerns"] = function(data,filename) +--~ enhancers["reorganize kerns"] = function(data,filename) --~ local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes --~ local mkdone = false --~ for index, glyph in next, glyphs do @@ -1010,7 +1014,7 @@ end --~ end --~ end -otf.enhancers["reorganize kerns"] = function(data,filename) +enhancers["reorganize kerns"] = function(data,filename) local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes local mkdone = false local function do_it(lookup,first_unicode,kerns) @@ -1154,15 +1158,7 @@ otf.enhancers["reorganize kerns"] = function(data,filename) end end - - - - - - - - -otf.enhancers["strip not needed data"] = function(data,filename) +enhancers["strip not needed data"] = function(data,filename) local verbose = fonts.verbose local int_to_uni = data.luatex.unicodes for k, v in next, data.glyphs do @@ -1204,7 +1200,7 @@ otf.enhancers["strip not needed data"] = function(data,filename) end end -otf.enhancers["migrate metadata"] = function(data,filename) +enhancers["migrate metadata"] = function(data,filename) local global_fields = otf.tables.global_fields local metadata = { } for k,v in next, data do @@ -1225,7 +1221,7 @@ local private_math_parameters = { "FractionDelimiterDisplayStyleSize", } -otf.enhancers["check math parameters"] = function(data,filename) +enhancers["check math parameters"] = function(data,filename) local mathdata = data.metadata.math if mathdata then for m=1,#private_math_parameters do @@ -1240,7 +1236,7 @@ otf.enhancers["check math parameters"] = function(data,filename) end end -otf.enhancers["flatten glyph lookups"] = function(data,filename) +enhancers["flatten glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do local lookups = v.lookups if lookups then @@ -1294,7 +1290,7 @@ otf.enhancers["flatten glyph lookups"] = function(data,filename) end end -otf.enhancers["simplify glyph lookups"] = function(data,filename) +enhancers["simplify glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do local lookups = v.lookups if lookups then @@ -1319,7 +1315,7 @@ otf.enhancers["simplify glyph lookups"] = function(data,filename) end end -otf.enhancers["flatten anchor tables"] = function(data,filename) +enhancers["flatten anchor tables"] = function(data,filename) for k, v in next, data.glyphs do if v.anchors then for kk, vv in next, v.anchors do @@ -1338,7 +1334,7 @@ otf.enhancers["flatten anchor tables"] = function(data,filename) end end -otf.enhancers["flatten feature tables"] = function(data,filename) +enhancers["flatten feature tables"] = function(data,filename) -- is this needed? do we still use them at all? for _, tag in next, otf.glists do if data[tag] then @@ -1364,11 +1360,11 @@ otf.enhancers["flatten feature tables"] = function(data,filename) end end -otf.enhancers.patches = otf.enhancers.patches or { } +enhancers.patches = enhancers.patches or { } -otf.enhancers["patch bugs"] = function(data,filename) +enhancers["patch bugs"] = function(data,filename) local basename = file.basename(lower(filename)) - for pattern, action in next, otf.enhancers.patches do + for pattern, action in next, enhancers.patches do if find(basename,pattern) then action(data,filename) end @@ -1377,7 +1373,7 @@ end -- tex features -fonts.otf.enhancers["enrich with features"] = function(data,filename) +enhancers["enrich with features"] = function(data,filename) -- later, ctx only end diff --git a/tex/context/base/font-oti.lua b/tex/context/base/font-oti.lua index 4cb270626..a5bbabf5c 100644 --- a/tex/context/base/font-oti.lua +++ b/tex/context/base/font-oti.lua @@ -6,11 +6,12 @@ if not modules then modules = { } end modules ['font-oti'] = { license = "see context related readme files" } --- i need to check features=yes|no also in relation to hashing - local lower = string.lower -local otf = fonts.otf +local fonts = fonts + +local otf = fonts.otf +local initializers = fonts.initializers otf.default_language = 'latn' otf.default_script = 'dflt' @@ -18,7 +19,7 @@ otf.default_script = 'dflt' local languages = otf.tables.languages local scripts = otf.tables.scripts -function otf.features.language(tfmdata,value) +local function set_language(tfmdata,value) if value then value = lower(value) if languages[value] then @@ -27,7 +28,7 @@ function otf.features.language(tfmdata,value) end end -function otf.features.script(tfmdata,value) +local function set_script(tfmdata,value) if value then value = lower(value) if scripts[value] then @@ -36,21 +37,24 @@ function otf.features.script(tfmdata,value) end end -function otf.features.mode(tfmdata,value) +local function set_mode(tfmdata,value) if value then tfmdata.mode = lower(value) end end -fonts.initializers.base.otf.language = otf.features.language -fonts.initializers.base.otf.script = otf.features.script -fonts.initializers.base.otf.mode = otf.features.mode -fonts.initializers.base.otf.method = otf.features.mode +local base_initializers = initializers.base.otf +local node_initializers = initializers.node.otf + +base_initializers.language = set_language +base_initializers.script = set_script +base_initializers.mode = set_mode +base_initializers.method = set_mode -fonts.initializers.node.otf.language = otf.features.language -fonts.initializers.node.otf.script = otf.features.script -fonts.initializers.node.otf.mode = otf.features.mode -fonts.initializers.node.otf.method = otf.features.mode +node_initializers.language = set_language +node_initializers.script = set_script +node_initializers.mode = set_mode +node_initializers.method = set_mode otf.features.register("features",true) -- we always do features table.insert(fonts.processors,"features") -- we need a proper function for doing this diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 6dcadddd8..a04d13758 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -125,6 +125,8 @@ local format, gmatch, gsub, find, match, lower, strip = string.format, string.gm local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match +local logs, trackers, fonts, nodes, attributes = logs, trackers, fonts, nodes, attributes + local otf = fonts.otf local tfm = fonts.tfm @@ -175,11 +177,19 @@ local default = "dflt" local split_at_space = lpeg.splitters[" "] or lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway -local glyph = node.id('glyph') -local glue = node.id('glue') -local kern = node.id('kern') -local disc = node.id('disc') -local whatsit = node.id('whatsit') +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local glyphcodes = nodes.glyphcodes + +local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue +local disc_code = nodecodes.disc +local whatsit_code = nodecodes.whatsit + +local dir_code = whatcodes.dir +local localpar_code = whatcodes.localpar + +local ligature_code = glyphcodes.ligature local state = attributes.private('state') local markbase = attributes.private('markbase') @@ -309,7 +319,7 @@ local function markstoligature(kind,lookupname,start,stop,char) snext.prev = current end start.prev, stop.next = nil, nil - current.char, current.subtype, current.components = char, 2, start + current.char, current.subtype, current.components = char, ligature_code, start return keep end @@ -319,16 +329,16 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- --~ local lignode = copy_node(start) --~ lignode.font = start.font --~ lignode.char = char ---~ lignode.subtype = 2 +--~ lignode.subtype = ligature_code --~ start = node.do_ligature_n(start, stop, lignode) ---~ if start.id == disc then +--~ if start.id == disc_code then --~ local prev = start.prev --~ start = start.next --~ end if discfound then -- print("start->stop",nodes.tosequence(start,stop)) local lignode = copy_node(start) - lignode.font, lignode.char, lignode.subtype = start.font, char, 2 + lignode.font, lignode.char, lignode.subtype = start.font, char, ligature_code local next, prev = stop.next, start.prev stop.next = nil lignode = node.do_ligature_n(start, stop, lignode) @@ -350,7 +360,7 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- snext.prev = current end start.prev, stop.next = nil, nil - current.char, current.subtype, current.components = char, 2, start + current.char, current.subtype, current.components = char, ligature_code, start local head = current if deletemarks then if trace_marks then @@ -376,7 +386,7 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- start = start.next end start = current.next - while start and start.id == glyph do + while start and start.id == glyph_code do if marks[start.char] then set_attribute(start,markdone,i) if trace_marks then @@ -471,7 +481,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma if marks[startchar] then while s do local id = s.id - if id == glyph and s.subtype<256 then + if id == glyph_code and s.subtype<256 then if s.font == currentfont then local char = s.char local lg = ligature[1][char] @@ -503,7 +513,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma local skipmark = sequence.flags[1] while s do local id = s.id - if id == glyph and s.subtype<256 then + if id == glyph_code and s.subtype<256 then if s.font == currentfont then local char = s.char if skipmark and marks[char] then @@ -521,7 +531,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma else break end - elseif id == disc then + elseif id == disc_code then discfound = true s = s.next else @@ -551,12 +561,12 @@ function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence) local markchar = start.char if marks[markchar] then local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if not marks[basechar] then break @@ -613,13 +623,13 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence) if marks[markchar] then local base = start.prev -- [glyph] [optional marks] [start=mark] local index = 1 - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then index = index + 1 while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if marks[basechar] then index = index + 1 @@ -683,7 +693,7 @@ function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence) --~ local alreadydone = markonce and has_attribute(start,markmark) --~ if not alreadydone then local base = start.prev -- [glyph] [basemark] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go local basechar = base.char local baseanchors = descriptions[basechar] if baseanchors then @@ -737,7 +747,7 @@ function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to end else local nxt = start.next - while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + while not done and nxt and nxt.id == glyph_code and nxt.subtype<256 and nxt.font == currentfont do local nextchar = nxt.char if marks[nextchar] then -- should not happen (maybe warning) @@ -800,9 +810,9 @@ function handlers.gpos_pair(start,kind,lookupname,kerns,sequence) else local prev, done = start, false local factor = tfmdata.factor - while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do + while snext and snext.id == glyph_code and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char -local krn = kerns[nextchar] + local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext snext = snext.next @@ -980,7 +990,7 @@ function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,c local current = start local subtables = currentlookup.subtables while current do - if current.id == glyph then + if current.id == glyph_code then local currentchar = current.char local lookupname = subtables[1] local replacement = cache.gsub_single[lookupname] @@ -1068,7 +1078,7 @@ function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,cach local current = start local subtables = currentlookup.subtables while current do - if current.id == glyph then + if current.id == glyph_code then local currentchar = current.char local lookupname = subtables[1] local alternatives = cache.gsub_alternate[lookupname] @@ -1125,7 +1135,7 @@ function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache local s, discfound, last, nofreplacements = start.next, false, stop, 0 while s do local id = s.id - if id == disc then + if id == disc_code then s = s.next discfound = true else @@ -1186,12 +1196,12 @@ function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,cach end if markanchors then local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if not marks[basechar] then break @@ -1251,13 +1261,13 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext, if markanchors then local base = start.prev -- [glyph] [optional marks] [start=mark] local index = 1 - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then index = index + 1 while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if marks[basechar] then index = index + 1 @@ -1327,7 +1337,7 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,cach end if markanchors then local base = start.prev -- [glyph] [basemark] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go local basechar = base.char local baseanchors = descriptions[basechar].anchors if baseanchors then @@ -1387,7 +1397,7 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache, end else local nxt = start.next - while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + while not done and nxt and nxt.id == glyph_code and nxt.subtype<256 and nxt.font == currentfont do local nextchar = nxt.char if marks[nextchar] then -- should not happen (maybe warning) @@ -1467,7 +1477,7 @@ function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,cur if kerns then local prev, done = start, false local factor = tfmdata.factor - while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do + while snext and snext.id == glyph_code and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char local krn = kerns[nextchar] if not krn and marks[nextchar] then @@ -1555,7 +1565,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- f..l = mid string if s == 1 then -- never happens - match = current.id == glyph and current.subtype<256 and current.font == currentfont and seq[1][current.char] + match = current.id == glyph_code and current.subtype<256 and current.font == currentfont and seq[1][current.char] else -- todo: better space check (maybe check for glue) local f, l = ck[4], ck[5] @@ -1569,12 +1579,12 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- we cannot optimize for n=2 because there can be disc nodes -- if not someskip and n == l then -- -- n=2 and no skips then faster loop - -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and seq[n][last.char] + -- match = last and last.id == glyph_code and last.subtype<256 and last.font == currentfont and seq[n][last.char] -- else while n <= l do if last then local id = last.id - if id == glyph then + if id == glyph_code then if last.subtype<256 and last.font == currentfont then local char = last.char local ccd = descriptions[char] @@ -1600,7 +1610,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then -- what to do with kerns? + elseif id == disc_code then -- what to do with kerns? last = last.next else match = false break @@ -1619,7 +1629,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence while n >= 1 do if prev then local id = prev.id - if id == glyph then + if id == glyph_code then if prev.subtype<256 and prev.font == currentfont then -- normal char local char = prev.char local ccd = descriptions[char] @@ -1641,7 +1651,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then + elseif id == disc_code then -- skip 'm elseif seq[n][32] then n = n -1 @@ -1674,7 +1684,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence while n <= s do if current then local id = current.id - if id == glyph then + if id == glyph_code then if current.subtype<256 and current.font == currentfont then -- normal char local char = current.char local ccd = descriptions[char] @@ -1696,7 +1706,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then + elseif id == disc_code then -- skip 'm elseif seq[n][32] then -- brrr n = n + 1 @@ -1998,7 +2008,7 @@ function fonts.methods.node.otf.features(head,font,attr) local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -2047,7 +2057,7 @@ function fonts.methods.node.otf.features(head,font,attr) else while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -2072,7 +2082,7 @@ function fonts.methods.node.otf.features(head,font,attr) else start = start.next end - -- elseif id == glue then + -- elseif id == glue_code then -- if p[5] then -- chain -- local pc = pp[32] -- if pc then @@ -2087,9 +2097,9 @@ function fonts.methods.node.otf.features(head,font,attr) -- else -- start = start.next -- end - elseif id == whatsit then + elseif id == whatsit_code then local subtype = start.subtype - if subtype == 7 then + if subtype == dir_code then local dir = start.dir if dir == "+TRT" or dir == "+TLT" then insert(txtdir,dir) @@ -2107,7 +2117,7 @@ function fonts.methods.node.otf.features(head,font,attr) if trace_directions then report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) end - elseif subtype == 6 then + elseif subtype == localpar_code then local dir = start.dir if dir == "TRT" then pardir = -1 @@ -2131,7 +2141,7 @@ function fonts.methods.node.otf.features(head,font,attr) else while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -2165,7 +2175,7 @@ function fonts.methods.node.otf.features(head,font,attr) else start = start.next end - -- elseif id == glue then + -- elseif id == glue_code then -- if p[5] then -- chain -- local pc = pp[32] -- if pc then @@ -2180,9 +2190,9 @@ function fonts.methods.node.otf.features(head,font,attr) -- else -- start = start.next -- end - elseif id == whatsit then + elseif id == whatsit_code then local subtype = start.subtype - if subtype == 7 then + if subtype == dir_code then local dir = start.dir if dir == "+TRT" or dir == "+TLT" then insert(txtdir,dir) @@ -2200,7 +2210,7 @@ function fonts.methods.node.otf.features(head,font,attr) if trace_directions then report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) end - elseif subtype == 6 then + elseif subtype == localpar_code then local dir = start.dir if dir == "TRT" then pardir = -1 diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua index f01468bf2..8df02e135 100644 --- a/tex/context/base/font-otp.lua +++ b/tex/context/base/font-otp.lua @@ -15,10 +15,14 @@ local trace_loading = false trackers.register("otf.loading", function(v) trace_ local report_otf = logs.new("load otf") -fonts = fonts or { } -fonts.otf = fonts.otf or { } -fonts.otf.enhancers = fonts.otf.enhancers or { } -fonts.otf.glists = fonts.otf.glists or { "gsub", "gpos" } +fonts = fonts or { } -- this module is also used in mtxrun +local fonts = fonts +fonts.otf = fonts.otf or { } -- this module is also used in mtxrun +local otf = fonts.otf + +otf.enhancers = otf.enhancers or { } +local enhancers = otf.enhancers +otf.glists = otf.glists or { "gsub", "gpos" } -- these can be extended so no local here local criterium, threshold, tabstr = 1, 0, table.serialize @@ -26,16 +30,16 @@ local function tabstr(t) -- hashed from core-uti / experiment local s = { } for k, v in next, t do if type(v) == "table" then - s[#s+1] = k.."={"..tabstr(v).."}" + s[#s+1] = k .. "={" .. tabstr(v) .. "}" else - s[#s+1] = k.."="..tostring(v) + s[#s+1] = k .. "=" .. tostring(v) end end sort(s) return concat(s,",") end -function fonts.otf.enhancers.pack(data) +function enhancers.pack(data) if data then local h, t, c = { }, { }, { } local hh, tt, cc = { }, { }, { } @@ -245,7 +249,7 @@ function fonts.otf.enhancers.pack(data) end local lf = data.luatex.features if lf then - for _, g in next, fonts.otf.glists do + for _, g in next, otf.glists do local gl = lf[g] if gl then for feature, spec in next, gl do @@ -301,7 +305,7 @@ function fonts.otf.enhancers.pack(data) end end -function fonts.otf.enhancers.unpack(data) +function enhancers.unpack(data) if data then local t = data.tables if t then @@ -490,7 +494,7 @@ function fonts.otf.enhancers.unpack(data) end local lf = luatex.features if lf then - for _, g in next, fonts.otf.glists do + for _, g in next, otf.glists do local gl = lf[g] if gl then for feature, spec in next, gl do diff --git a/tex/context/base/font-ott.lua b/tex/context/base/font-ott.lua index 638fd8efc..34802de9f 100644 --- a/tex/context/base/font-ott.lua +++ b/tex/context/base/font-ott.lua @@ -7,17 +7,20 @@ if not modules then modules = { } end modules ['font-otf'] = { } local type, next, tonumber, tostring = type, next, tonumber, tostring -local gsub, lower = string.gsub, string.lower +local gsub, lower, format = string.gsub, string.lower, string.format +local is_boolean = string.is_boolean -fonts = fonts or { } -fonts.otf = fonts.otf or { } +local fonts = fonts +fonts.otf = fonts.otf or { } +local otf = fonts.otf -local otf = fonts.otf +otf.tables = otf.tables or { } +local tables = otf.tables -otf.tables = otf.tables or { } -otf.meanings = otf.meanings or { } +otf.meanings = otf.meanings or { } +local meanings = otf.meanings -otf.tables.scripts = { +local scripts = { ['dflt'] = 'Default', ['arab'] = 'Arabic', @@ -90,7 +93,7 @@ otf.tables.scripts = { ['yi' ] = 'Yi', } -otf.tables.languages = { +local languages = { ['dflt'] = 'Default', ['aba'] = 'Abaza', @@ -484,7 +487,7 @@ otf.tables.languages = { ['zul'] = 'Zulu' } -otf.tables.features = { +local features = { ['aalt'] = 'Access All Alternates', ['abvf'] = 'Above-Base Forms', ['abvm'] = 'Above-Base Mark Positioning', @@ -622,7 +625,7 @@ otf.tables.features = { ['tlig'] = 'Traditional TeX Ligatures', } -otf.tables.baselines = { +local baselines = { ['hang'] = 'Hanging baseline', ['icfb'] = 'Ideographic character face bottom edge baseline', ['icft'] = 'Ideographic character face tope edige baseline', @@ -632,10 +635,33 @@ otf.tables.baselines = { ['romn'] = 'Roman baseline' } +local to_scripts = table.reverse_hash(scripts ) +local to_languages = table.reverse_hash(languages) +local to_features = table.reverse_hash(features ) + +tables.scripts = scripts +tables.languages = languages +tables.features = features +tables.baselines = baselines + +tables.to_scripts = to_scripts +tables.to_languages = to_languages +tables.to_features = to_features + +for k, v in next, to_features do + local stripped = gsub(k,"%-"," ") + to_features[stripped] = v + local stripped = gsub(k,"[^a-zA-Z0-9]","") + to_features[stripped] = v +end +for k, v in next, to_features do + to_features[lower(k)] = v +end + -- can be sped up by local tables -function otf.tables.to_tag(id) - return stringformat("%4s",lower(id)) +function tables.to_tag(id) + return format("%4s",lower(id)) end local function resolve(tab,id) @@ -647,50 +673,20 @@ local function resolve(tab,id) end end -function otf.meanings.script(id) - return resolve(otf.tables.scripts,id) -end -function otf.meanings.language(id) - return resolve(otf.tables.languages,id) -end -function otf.meanings.feature(id) - return resolve(otf.tables.features,id) -end -function otf.meanings.baseline(id) - return resolve(otf.tables.baselines,id) -end - -otf.tables.to_scripts = table.reverse_hash(otf.tables.scripts ) -otf.tables.to_languages = table.reverse_hash(otf.tables.languages) -otf.tables.to_features = table.reverse_hash(otf.tables.features ) - -local scripts = otf.tables.scripts -local languages = otf.tables.languages -local features = otf.tables.features - -local to_scripts = otf.tables.to_scripts -local to_languages = otf.tables.to_languages -local to_features = otf.tables.to_features - -for k, v in next, to_features do - local stripped = gsub(k,"%-"," ") - to_features[stripped] = v - local stripped = gsub(k,"[^a-zA-Z0-9]","") - to_features[stripped] = v -end -for k, v in next, to_features do - to_features[lower(k)] = v -end +function meanings.script (id) return resolve(scripts, id) end +function meanings.language(id) return resolve(languages,id) end +function meanings.feature (id) return resolve(features, id) end +function meanings.baseline(id) return resolve(baselines,id) end -otf.meanings.checkers = { +local checkers = { rand = function(v) return v and "random" end } -local checkers = otf.meanings.checkers +meanings.checkers = checkers -function otf.meanings.normalize(features) +function meanings.normalize(features) if features then local h = { } for k,v in next, features do @@ -711,7 +707,7 @@ function otf.meanings.normalize(features) end else if type(v) == "string" then - local b = v:is_boolean() + local b = is_boolean(v) if type(b) == "nil" then v = tonumber(v) or lower(v) else @@ -729,7 +725,7 @@ end -- When I feel the need ... ---~ otf.tables.aat = { +--~ tables.aat = { --~ [ 0] = { --~ name = "allTypographicFeaturesType", --~ [ 0] = "allTypeFeaturesOnSelector", diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index 23030588e..8a18f07b7 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -29,16 +29,15 @@ using a table that has keys filtered from the font related files.</p> local texsprint = (tex and tex.sprint) or print -fonts = fonts or { } -input = input or { } -texmf = texmf or { } +local fonts = fonts -fonts.names = fonts.names or { } -fonts.names.filters = fonts.names.filters or { } -fonts.names.data = fonts.names.data or { } +fonts.names = fonts.names or { } +local names = fonts.names -local names = fonts.names -local filters = fonts.names.filters +names.filters = names.filters or { } +local filters = names.filters + +names.data = names.data or { } names.version = 1.103 names.basename = "names" diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua index 57e10f3b1..d51bcc3b8 100644 --- a/tex/context/base/font-tfm.lua +++ b/tex/context/base/font-tfm.lua @@ -25,23 +25,23 @@ local report_define = logs.new("define fonts") <p>Here we only implement a few helper functions.</p> --ldx]]-- -fonts = fonts or { } -fonts.tfm = fonts.tfm or { } -fonts.ids = fonts.ids or { } +local fonts = fonts +local tfm = fonts.tfm -local tfm = fonts.tfm - -fonts.loaded = fonts.loaded or { } +fonts.loaded = fonts.loaded or { } fonts.dontembed = fonts.dontembed or { } -fonts.triggers = fonts.triggers or { } -- brrr -fonts.initializers = fonts.initializers or { } +fonts.triggers = fonts.triggers or { } -- brrr +fonts.initializers = fonts.initializers or { } fonts.initializers.common = fonts.initializers.common or { } -local fontdata = fonts.ids -local disc = node.id('disc') -local glyph = node.id('glyph') local set_attribute = node.set_attribute +local fontdata = fonts.ids +local nodecodes = nodes.nodecodes + +local disc_code = nodecodes.disc +local glyph_code = nodecodes.glyph + --[[ldx-- <p>The next function encapsulates the standard <l n='tfm'/> loader as supplied by <l n='luatex'/>.</p> @@ -664,7 +664,7 @@ function fonts.analyzers.aux.setstate(head,font) local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean while current do local id = current.id - if id == glyph and current.font == font then + if id == glyph_code and current.font == font then local d = descriptions[current.char] if d then if d.class == "mark" then @@ -685,7 +685,7 @@ function fonts.analyzers.aux.setstate(head,font) end first, last, n = nil, nil, 0 end - elseif id == disc then + elseif id == disc_code then -- always in the middle set_attribute(current,state,2) -- midi last = current diff --git a/tex/context/base/font-vf.lua b/tex/context/base/font-vf.lua index 4f99c47b9..d803636a2 100644 --- a/tex/context/base/font-vf.lua +++ b/tex/context/base/font-vf.lua @@ -13,28 +13,35 @@ changes. This will change.</p> -- define.methods elsewhere ! -fonts = fonts or { } -fonts.vf = fonts.vf or { } +local next = next +local fastcopy = table.fastcopy -local vf = fonts.vf -local tfm = fonts.tfm +local fonts = fonts +local vf = fonts.vf +local tfm = fonts.tfm -fonts.define = fonts.define or { } -fonts.define.methods = fonts.define.methods or { } +fonts.define = fonts.define or { } +local define = fonts.define +define.methods = define.methods or { } vf.combinations = vf.combinations or { } vf.aux = vf.aux or { } vf.aux.combine = vf.aux.combine or { } +local combine = vf.aux.combine -function fonts.define.methods.install(tag, rules) +function define.methods.install(tag, rules) vf.combinations[tag] = rules - fonts.define.methods[tag] = function(specification) + define.methods[tag] = function(specification) return vf.combine(specification,tag) end end -function vf.aux.combine.assign(g, name, from, to, start, force) - local f, id = vf.aux.combine.load(g,name) +local function combine_load(g,name) + return tfm.read_and_define(name or g.specification.name,g.specification.size) +end + +local function combine_assign(g, name, from, to, start, force) + local f, id = combine_load(g,name) if f and id then -- optimize for whole range, then just g = f if not from then from, to = 0, 0xFF00 end @@ -46,35 +53,31 @@ function vf.aux.combine.assign(g, name, from, to, start, force) g.fonts[hn] = { id = id } -- no need to be sparse for i=from,to do if fc[i] and (force or not gc[i]) then - gc[i] = table.fastcopy(fc[i]) -- can be optimized + gc[i] = fastcopy(fc[i]) -- can be optimized gc[i].commands = { { 'slot', hn, start } } gd[i] = fd[i] end start = start + 1 end if not g.parameters and #g.fonts > 0 then -- share this code ! - g.parameters = table.fastcopy(f.parameters) - g.italicangle = f.italicangle - g.ascender = f.ascender - g.descender = f.descender - g.factor = f.factor -- brrr + g.parameters = fastcopy(f.parameters) + g.italicangle = f.italicangle + g.ascender = f.ascender + g.descender = f.descender + g.factor = f.factor -- brrr end end end -function vf.aux.combine.process(g,list) +local function combine_process(g,list) if list then for _,v in next, list do - (vf.aux.combine.commands[v[1]] or nop)(g,v) + (combine.commands[v[1]] or nop)(g,v) end end end -function vf.aux.combine.load(g,name) - return tfm.read_and_define(name or g.specification.name,g.specification.size) -end - -function vf.aux.combine.names(g,name,force) +local function combine_names(g,name,force) local f, id = tfm.read_and_define(name,g.specification.size) if f and id then local fc, gc = f.characters, g.characters @@ -83,62 +86,73 @@ function vf.aux.combine.names(g,name,force) local hn = #g.fonts for k, v in next, fc do if force or not gc[k] then - gc[k] = table.fastcopy(v) + gc[k] = fastcopy(v) gc[k].commands = { { 'slot', hn, k } } gd[i] = fd[i] end end if not g.parameters and #g.fonts > 0 then -- share this code ! - g.parameters = table.fastcopy(f.parameters) - g.italicangle = f.italicangle - g.ascender = f.ascender - g.descender = f.descender - g.factor = f.factor -- brrr + g.parameters = fastcopy(f.parameters) + g.italicangle = f.italicangle + g.ascender = f.ascender + g.descender = f.descender + g.factor = f.factor -- brrr end end end -vf.aux.combine.commands = { - ["initialize"] = function(g,v) vf.aux.combine.assign (g,g.name) end, - ["include-method"] = function(g,v) vf.aux.combine.process (g,vf.combinations[v[2]]) end, -- name - ["copy-parameters"] = function(g,v) vf.aux.combine.parameters(g,v[2]) end, -- name - ["copy-range"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[4],v[5],true) end, -- name, from-start, from-end, to-start - ["copy-char"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[3],v[4],true) end, -- name, from, to - ["fallback-range"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[4],v[5],false) end, -- name, from-start, from-end, to-start - ["fallback-char"] = function(g,v) vf.aux.combine.assign (g,v[2],v[3],v[3],v[4],false) end, -- name, from, to - ["copy_names"] = function(g,v) vf.aux.combine.names (g,v[2],true) end, - ["fallback_names"] = function(g,v) vf.aux.combine.names (g,v[2],false) end, -} - -function vf.combine(specification,tag) - local g = { - name = specification.name, - -- type = 'virtual', - virtualized = true, - fonts = { }, - characters = { }, - descriptions = { }, - specification = table.fastcopy(specification) - } - vf.aux.combine.process(g,vf.combinations[tag]) - return g -end - -vf.aux.combine.commands["feature"] = function(g,v) +local combine_feature = function(g,v) local key, value = v[2], v[3] if key then if value == nil then value = true end - if g.specification and g.specification.features.normal then - g.specification.features.normal[key] = value -- otf? + local specification = g.specification + if specification then + local normalfeatures = specification.features.normal + if normalfeatures then + normalfeatures[key] = value -- otf? + end end end end +--~ combine.load = combine_load +--~ combine.assign = combine_assign +--~ combine.process = combine_process +--~ combine.names = combine_names +--~ combine.feature = combine_feature + +combine.commands = { + ["initialize"] = function(g,v) combine_assign (g,g.name) end, + ["include-method"] = function(g,v) combine_process (g,vf.combinations[v[2]]) end, -- name + -- ["copy-parameters"] = function(g,v) combine_parameters(g,v[2]) end, -- name + ["copy-range"] = function(g,v) combine_assign (g,v[2],v[3],v[4],v[5],true) end, -- name, from-start, from-end, to-start + ["copy-char"] = function(g,v) combine_assign (g,v[2],v[3],v[3],v[4],true) end, -- name, from, to + ["fallback-range"] = function(g,v) combine_assign (g,v[2],v[3],v[4],v[5],false) end, -- name, from-start, from-end, to-start + ["fallback-char"] = function(g,v) combine_assign (g,v[2],v[3],v[3],v[4],false) end, -- name, from, to + ["copy-names"] = function(g,v) combine_names (g,v[2],true) end, + ["fallback_names"] = function(g,v) combine_names (g,v[2],false) end, + ["feature"] = combine_feature, +} + +function vf.combine(specification,tag) + local g = { + name = specification.name, + -- type = 'virtual', + virtualized = true, + fonts = { }, + characters = { }, + descriptions = { }, + specification = fastcopy(specification), + } + combine_process(g,vf.combinations[tag]) + return g +end + -- simple example with features -fonts.define.methods.install( +define.methods.install( "ligatures", { { "feature", "liga" } , { "feature", "dlig" } , @@ -146,7 +160,7 @@ fonts.define.methods.install( } ) ---~ fonts.define.methods.install ( +--~ define.methods.install ( --~ "ligatures-x", { --~ { "feature", "liga" } , --~ { "feature", "dlig" } , @@ -155,7 +169,7 @@ fonts.define.methods.install( --~ } --~ ) ---~ fonts.define.methods.install( +--~ define.methods.install( --~ "lmsymbol10", { --~ { "fallback_names", "lmsy10.afm" } , --~ { "fallback_names", "msam10.afm" } , @@ -166,7 +180,7 @@ fonts.define.methods.install( -- docu case ---~ fonts.define.methods.install( +--~ define.methods.install( --~ "weird", { --~ { "copy-range", "lmroman10-regular" } , --~ { "copy-char", "lmroman10-regular", 65, 66 } , @@ -178,7 +192,9 @@ fonts.define.methods.install( -- demo case -> move to module -fonts.define.methods["demo-1"] = function(specification) +-- todo: interface tables in back-ini + +define.methods["demo-1"] = function(specification) local name = specification.name -- symbolic name local size = specification.size -- given size local f, id = tfm.read_and_define('lmroman10-regular',size) @@ -193,19 +209,17 @@ fonts.define.methods["demo-1"] = function(specification) } local i_is_of_category = characters.i_is_of_category local characters, descriptions = f.characters, f.descriptions - local red = {'special','pdf: 1 0 0 rg'} - local green = {'special','pdf: 0 1 0 rg'} - local blue = {'special','pdf: 0 0 1 rg'} - local black = {'special','pdf: 0 g'} + local vfspecials = backends.tables.vfspecials + local red, green, blue, black = vfspecials.red, vfspecials.green, vfspecials.blue, vfspecials.black for u,v in next, characters do if u and i_is_of_category(u,'lu') then v.width = capscale*v.width - v.commands = { red, {'slot',2,u}, black } + v.commands = { red, { 'slot', 2, u }, black } elseif u and i_is_of_category(u,'nd') then v.width = digscale*v.width - v.commands = { blue, {'slot',3,u}, black } + v.commands = { blue, { 'slot', 3, u }, black } else - v.commands = { green, {'slot',1,u}, black } + v.commands = { green, { 'slot', 1, u }, black } end end end diff --git a/tex/context/base/font-xtx.lua b/tex/context/base/font-xtx.lua index eac75dd29..aa0c3bca3 100644 --- a/tex/context/base/font-xtx.lua +++ b/tex/context/base/font-xtx.lua @@ -31,38 +31,16 @@ well and that does not work too well with the general design of the specifier.</p> --ldx]]-- ---~ function fonts.define.specify.colonized(specification) -- xetex mode ---~ local list = { } ---~ if specification.detail and specification.detail ~= "" then ---~ for v in gmatch(specification.detail,"%s*([^;]+)%s*") do ---~ local a, b = match(v,"^(%S*)%s*=%s*(%S*)$") ---~ if a and b then ---~ list[a] = b:is_boolean() ---~ if type(list[a]) == "nil" then ---~ list[a] = b ---~ end ---~ else ---~ local a, b = match(v,"^([%+%-]?)%s*(%S+)$") ---~ if a and b then ---~ list[b] = a ~= "-" ---~ end ---~ end ---~ end ---~ end ---~ specification.features.normal = list ---~ return specification ---~ end - ---~ check("oeps/BI:+a;-b;c=d") ---~ check("[oeps]/BI:+a;-b;c=d") ---~ check("file:oeps/BI:+a;-b;c=d") ---~ check("name:oeps/BI:+a;-b;c=d") +local fonts = fonts +local define = fonts.define +local specify = define.specify +local normalize_meanings = fonts.otf.meanings.normalize local list = { } -fonts.define.specify.colonized_default_lookup = "file" +specify.colonized_default_lookup = "file" -local function issome () list.lookup = fonts.define.specify.colonized_default_lookup end +local function issome () list.lookup = specify.colonized_default_lookup end local function isfile () list.lookup = 'file' end local function isname () list.lookup = 'name' end local function thename(s) list.name = s end @@ -75,32 +53,32 @@ local function iskey (k,v) list[k] = v end local function istrue (s) list[s] = true end local function isfalse(s) list[s] = false end -local spaces = lpeg.P(" ")^0 -local namespec = (1-lpeg.S("/:("))^0 -- was: (1-lpeg.S("/: ("))^0 -local crapspec = spaces * lpeg.P("/") * (((1-lpeg.P(":"))^0)/iscrap) * spaces -local filename = (lpeg.P("file:")/isfile * (namespec/thename)) + (lpeg.P("[") * lpeg.P(true)/isname * (((1-lpeg.P("]"))^0)/thename) * lpeg.P("]")) -local fontname = (lpeg.P("name:")/isname * (namespec/thename)) + lpeg.P(true)/issome * (namespec/thename) -local sometext = (lpeg.R("az","AZ","09") + lpeg.S("+-."))^1 -local truevalue = lpeg.P("+") * spaces * (sometext/istrue) -local falsevalue = lpeg.P("-") * spaces * (sometext/isfalse) -local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(sometext))/iskey +local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C + +local spaces = P(" ")^0 +local namespec = (1-S("/:("))^0 -- was: (1-S("/: ("))^0 +local crapspec = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces +local filename = (P("file:")/isfile * (namespec/thename)) + (P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]")) +local fontname = (P("name:")/isname * (namespec/thename)) + P(true)/issome * (namespec/thename) +local sometext = (R("az","AZ","09") + S("+-."))^1 +local truevalue = P("+") * spaces * (sometext/istrue) +local falsevalue = P("-") * spaces * (sometext/isfalse) +local keyvalue = (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey local somevalue = sometext/istrue -local subvalue = lpeg.P("(") * (lpeg.C(lpeg.P(1-lpeg.S("()"))^1)/issub) * lpeg.P(")") -- for Kim +local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces -local options = lpeg.P(":") * spaces * (lpeg.P(";")^0 * option)^0 +local options = P(":") * spaces * (P(";")^0 * option)^0 local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0 -local normalize_meanings = fonts.otf.meanings.normalize - -function fonts.define.specify.colonized(specification) -- xetex mode +local function colonized(specification) -- xetex mode list = { } lpegmatch(pattern,specification.specification) ---~ for k, v in next, list do ---~ list[k] = v:is_boolean() ---~ if type(list[a]) == "nil" then ---~ list[k] = v ---~ end ---~ end + -- for k, v in next, list do + -- list[k] = v:is_boolean() + -- if type(list[a]) == "nil" then + -- list[k] = v + -- end + -- end list.crap = nil -- style not supported, maybe some day if list.name then specification.name = list.name @@ -114,9 +92,11 @@ function fonts.define.specify.colonized(specification) -- xetex mode specification.sub = list.sub list.sub = nil end --- specification.features.normal = list + -- specification.features.normal = list specification.features.normal = normalize_meanings(list) return specification end -fonts.define.register_split(":", fonts.define.specify.colonized) +specify.colonized = colonized + +define.register_split(":",colonized) diff --git a/tex/context/base/grph-epd.lua b/tex/context/base/grph-epd.lua index c687e40a8..130907d4e 100644 --- a/tex/context/base/grph-epd.lua +++ b/tex/context/base/grph-epd.lua @@ -7,17 +7,20 @@ if not modules then modules = { } end modules ['grph-epd'] = { } local variables = interfaces.variables +local settings_to_hash = utilities.parsers.settings_to_hash -- todo: page, name, file, url +local codeinjections = backends.codeinjections + function figures.mergegoodies(optionlist) - local options = aux.settings_to_hash(optionlist) + local options = settings_to_hash(optionlist) local all = options[variables.all] or options[variables.yes] if all or options[variables.reference] then - backends.codeinjections.mergereferences() + codeinjections.mergereferences() end if all or options[variables.layer] then - backends.codeinjections.mergelayers() + codeinjections.mergeviewerlayers() end end diff --git a/tex/context/base/grph-epd.mkiv b/tex/context/base/grph-epd.mkiv index b23631b79..b066e1adc 100644 --- a/tex/context/base/grph-epd.mkiv +++ b/tex/context/base/grph-epd.mkiv @@ -15,8 +15,6 @@ \unprotect -\registerctxluafile{lpdf-epd}{1.001} -\registerctxluafile{lpdf-epa}{1.001} \registerctxluafile{grph-epd}{1.001} \def\figurereference {\ctxlua{figures.tprint("status","reference")}} diff --git a/tex/context/base/grph-fig.mkiv b/tex/context/base/grph-fig.mkiv index 0cf9bea2b..634a8733a 100644 --- a/tex/context/base/grph-fig.mkiv +++ b/tex/context/base/grph-fig.mkiv @@ -572,7 +572,7 @@ \fi\fi\fi} \def\dodotypesetfile#1#2#3#4% options settings-a filename settings-b - {\edef\typesetfilename{\ctxlua{tex.write(jobfiles.run("#3","#1"))}}% + {\edef\typesetfilename{\ctxlua{tex.write(job.files.run("#3","#1"))}}% \expanded{\externalfigure[\typesetfilename]}[#2,#4]} \setupexternalfigures diff --git a/tex/context/base/grph-fil.lua b/tex/context/base/grph-fil.lua index 2e32c7a60..4832ac3bc 100644 --- a/tex/context/base/grph-fil.lua +++ b/tex/context/base/grph-fil.lua @@ -12,9 +12,12 @@ local trace_run = false trackers.register("files.run",function(v) trace_run = v local command = "context %s" -jobfiles = jobfiles or { } -jobfiles.collected = jobfiles.collected or { } -jobfiles.tobesaved = jobfiles.tobesaved or { } +local jobfiles = { + collected = { }, + tobesaved = { }, +} + +job.files = jobfiles local tobesaved, collected = jobfiles.tobesaved, jobfiles.collected @@ -22,7 +25,7 @@ local function initializer() tobesaved, collected = jobfiles.tobesaved, jobfiles.collected end -job.register('jobfiles.collected', jobfiles.tobesaved, initializer) +job.register('job.files.collected', jobfiles.tobesaved, initializer) jobfiles.forcerun = false diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index 8b81099a5..c8ad5995e 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['grph-inc'] = { license = "see context related readme files" } +-- figures -> managers.figures + -- lowercase types -- mps tex tmp svg -- partly qualified @@ -42,9 +44,11 @@ local texsprint, texbox = tex.sprint, tex.box local contains = table.contains local concat = table.concat local todimen = string.todimen +local settings_to_array = utilities.parsers.settings_to_array -local ctxcatcodes = tex.ctxcatcodes -local variables = interfaces.variables +local ctxcatcodes = tex.ctxcatcodes +local variables = interfaces.variables +local codeinjections = backends.codeinjections local trace_figures = false trackers.register("figures.locating", function(v) trace_figures = v end) local trace_bases = false trackers.register("figures.bases", function(v) trace_bases = v end) @@ -56,6 +60,8 @@ local report_graphics = logs.new("graphics") --- some extra img functions --- +local img = img + local imgkeys = img.keys() function img.totable(imgtable) @@ -90,14 +96,17 @@ function img.check_size(size) end end ---- +--- we can consider an grph-ini file figures = figures or { } +local figures = figures + figures.loaded = figures.loaded or { } figures.used = figures.used or { } figures.found = figures.found or { } figures.suffixes = figures.suffixes or { } figures.patterns = figures.patterns or { } + figures.boxnumber = figures.boxnumber or 0 figures.defaultsearch = true figures.defaultwidth = 0 @@ -200,7 +209,7 @@ function figures.setpaths(locationset,pathlist) end if h[iv["global"]] then -- for s in gmatch(pathlist,",* *([^,]+)") do - local list = aux.settings_to_array(pathlist) + local list = settings_to_array(pathlist) for i=1,#list do local s = list[i] if not contains(t,s) then @@ -340,7 +349,7 @@ local function register(askedname,specification) if not newformat or newformat == "" then newformat = defaultformat end - local converter = (newformat ~= format) and figures.converters[format] + local converter = (newformat ~= format) and converters[format] if trace_conversion then report_graphics("checking conversion of '%s': old format '%s', new format '%s', conversion '%s'", askedname,format,newformat,conversion or "default") @@ -641,18 +650,25 @@ end -- -- -- plugins -- -- -- -figures.existers = figures.existers or { } -figures.checkers = figures.checkers or { } -figures.includers = figures.includers or { } -figures.converters = figures.converters or { } +figures.existers = figures.existers or { } +local existers = figures.existers + +figures.checkers = figures.checkers or { } +local checkers = figures.checkers + +figures.includers = figures.includers or { } +local includers = figures.includers + +figures.converters = figures.converters or { } +local converters = figures.converters + figures.identifiers = figures.identifiers or { } -figures.programs = figures.programs or { } +local identifiers = figures.identifiers -figures.identifiers.list = { - figures.identifiers.default -} +figures.programs = figures.programs or { } +programs = figures.programs -function figures.identifiers.default(data) +function identifiers.default(data) local dr, du, ds = data.request, data.used, data.status local l = locate(dr) local foundname = l.foundname @@ -669,7 +685,7 @@ end function figures.identify(data) data = data or figures.current() - local list = figures.identifiers.list + local list = identifiers.list -- defined at the end for i=1,#list do local identifier = list[i] data = identifier(data) @@ -680,17 +696,17 @@ function figures.identify(data) return data end function figures.exists(askedname,format,resolve) - return (figures.existers[format] or figures.existers.generic)(askedname,resolve) + return (existers[format] or existers.generic)(askedname,resolve) end function figures.check(data) data = data or figures.current() local dr, du, ds = data.request, data.used, data.status - return (figures.checkers[ds.format] or figures.checkers.generic)(data) + return (checkers[ds.format] or checkers.generic)(data) end function figures.include(data) data = data or figures.current() local dr, du, ds = data.request, data.used, data.status - return (figures.includers[ds.format] or figures.includers.generic)(data) + return (includers[ds.format] or includers.generic)(data) end function figures.scale(data) -- will become lua code texsprint(ctxcatcodes,"\\doscalefigure") @@ -727,7 +743,7 @@ end -- -- -- generic -- -- -- -function figures.existers.generic(askedname,resolve) +function existers.generic(askedname,resolve) -- not findbinfile local result if lfs.isfile(askedname) then @@ -745,7 +761,7 @@ function figures.existers.generic(askedname,resolve) end return result end -function figures.checkers.generic(data) +function checkers.generic(data) local dr, du, ds = data.request, data.used, data.status local name, page, size, color = du.fullname or "unknown generic", du.page or dr.page, dr.size or "crop", dr.color or "natural" local conversion = dr.conversion @@ -756,9 +772,9 @@ function figures.checkers.generic(data) local figure = figures.loaded[hash] if figure == nil then figure = img.new { filename = name, page = page, pagebox = dr.size } - backends.codeinjections.setfigurecolorspace(data,figure) + codeinjections.setfigurecolorspace(data,figure) figure = (figure and img.scan(figure)) or false - local f, d = backends.codeinjections.setfigurealternative(data,figure) + local f, d = codeinjections.setfigurealternative(data,figure) figure, data = f or figure, d or data figures.loaded[hash] = figure if trace_conversion then @@ -778,7 +794,7 @@ function figures.checkers.generic(data) end return data end -function figures.includers.generic(data) +function includers.generic(data) local dr, du, ds = data.request, data.used, data.status -- here we set the 'natural dimensions' dr.width = du.width @@ -807,13 +823,13 @@ end -- -- -- nongeneric -- -- -- -function figures.checkers.nongeneric(data,command) +function checkers.nongeneric(data,command) local dr, du, ds = data.request, data.used, data.status local name = du.fullname or "unknown nongeneric" local hash = name if dr.object then -- hm, bugged - if not jobobjects.get("FIG::"..hash) then + if not job.objects.get("FIG::"..hash) then texsprint(ctxcatcodes,command) texsprint(ctxcatcodes,format("\\setobject{FIG}{%s}\\vbox{\\box\\foundexternalfigure}",hash)) end @@ -823,13 +839,13 @@ function figures.checkers.nongeneric(data,command) end return data end -function figures.includers.nongeneric(data) +function includers.nongeneric(data) return data end -- -- -- mov -- -- -- -function figures.checkers.mov(data) +function checkers.mov(data) local dr, du, ds = data.request, data.used, data.status local width = todimen(dr.width or figures.defaultwidth) local height = todimen(dr.height or figures.defaultheight) @@ -842,7 +858,7 @@ function figures.checkers.mov(data) -- we need to push the node.write in between ... we could make a shared helper for this context.startfoundexternalfigure(width .. "sp",height .. "sp") context(function() - backends.codeinjections.insertmovie { + nodeinjections.insertmovie { width = width, height = height, factor = number.dimenfactors.bp, @@ -857,7 +873,7 @@ function figures.checkers.mov(data) return data end -figures.includers.mov = figures.includers.nongeneric +includers.mov = includers.nongeneric -- -- -- mps -- -- -- @@ -870,45 +886,45 @@ local function internal(askedname) end end -function figures.existers.mps(askedname) +function existers.mps(askedname) local mprun, mpnum = internal(askedname) if mpnum then return askedname else - return figures.existers.generic(askedname) + return existers.generic(askedname) end end -function figures.checkers.mps(data) +function checkers.mps(data) local mprun, mpnum = internal(data.used.fullname) if mpnum then - return figures.checkers.nongeneric(data,format("\\docheckfiguremprun{%s}{%s}",mprun,mpnum)) + return checkers.nongeneric(data,format("\\docheckfiguremprun{%s}{%s}",mprun,mpnum)) else - return figures.checkers.nongeneric(data,format("\\docheckfiguremps{%s}",data.used.fullname)) + return checkers.nongeneric(data,format("\\docheckfiguremps{%s}",data.used.fullname)) end end -figures.includers.mps = figures.includers.nongeneric +includers.mps = includers.nongeneric -- -- -- buffer -- -- -- -function figures.existers.buffer(askedname) +function existers.buffer(askedname) askedname = file.nameonly(askedname) return buffers.exists(askedname) and askedname end -function figures.checkers.buffer(data) - return figures.checkers.nongeneric(data,format("\\docheckfigurebuffer{%s}", file.nameonly(data.used.fullname))) +function checkers.buffer(data) + return checkers.nongeneric(data,format("\\docheckfigurebuffer{%s}", file.nameonly(data.used.fullname))) end -figures.includers.buffers = figures.includers.nongeneric +includers.buffers = includers.nongeneric -- -- -- tex -- -- -- -function figures.existers.tex(askedname) +function existers.tex(askedname) askedname = resolvers.find_file(askedname) return (askedname ~= "" and askedname) or false end -function figures.checkers.tex(data) - return figures.checkers.nongeneric(data,format("\\docheckfiguretex{%s}", data.used.fullname)) +function checkers.tex(data) + return checkers.nongeneric(data,format("\\docheckfiguretex{%s}", data.used.fullname)) end -figures.includers.tex = figures.includers.nongeneric +includers.tex = includers.nongeneric -- -- -- converters -- -- -- @@ -928,9 +944,9 @@ end -- -- -- eps -- -- -- local epsconverter = { } -figures.converters.eps = epsconverter +converters.eps = epsconverter -figures.programs.gs = { +programs.gs = { options = { "-dAutoRotatePages=/None", "-dPDFSETTINGS=/prepress", @@ -940,7 +956,7 @@ figures.programs.gs = { } function epsconverter.pdf(oldname,newname) - local gs = figures.programs.gs + local gs = programs.gs runprogram ( '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH %s -sOutputFile="%s" "%s" -c quit', gs.command, makeoptions(gs.options), newname, oldname @@ -952,12 +968,12 @@ epsconverter.default = epsconverter.pdf -- -- -- svg -- -- -- local svgconverter = { } -figures.converters.svg = svgconverter -figures.converters.svgz = svgconverter +converters.svg = svgconverter +converters.svgz = svgconverter -- inkscape on windows only works with complete paths -figures.programs.inkscape = { +programs.inkscape = { options = { "--export-dpi=600" }, @@ -965,7 +981,7 @@ figures.programs.inkscape = { } function svgconverter.pdf(oldname,newname) - local inkscape = figures.programs.inkscape + local inkscape = programs.inkscape runprogram ( '%s "%s" --export-pdf="%s" %s', inkscape.command, oldname, newname, makeoptions(inkscape.options) @@ -973,7 +989,7 @@ function svgconverter.pdf(oldname,newname) end function svgconverter.png(oldname,newname) - local inkscape = figures.programs.inkscape + local inkscape = programs.inkscape runprogram ( '%s "%s" --export-png="%s" %s', inkscape.command, oldname, newname, makeoptions(inkscape.options) @@ -985,15 +1001,15 @@ svgconverter.default = svgconverter.pdf -- -- -- gif -- -- -- local gifconverter = { } -figures.converters.gif = gifconverter +converters.gif = gifconverter -figures.programs.convert = { +programs.convert = { command = "convert" -- imagemagick -- command = "gm convert" -- graphicmagick } function gifconverter.pdf(oldname,newname) - local convert = figures.programs.convert + local convert = programs.convert runprogram ( "%s %s %s %s", convert.command, makeoptions(convert.options), oldname, newname @@ -1099,7 +1115,7 @@ function bases.locate(askedlabel) return false end -function figures.identifiers.base(data) +function identifiers.base(data) if bases.enabled then local dr, du, ds = data.request, data.used, data.status local fbl = bases.locate(dr.name or dr.label) @@ -1116,9 +1132,9 @@ function figures.identifiers.base(data) return data end -figures.identifiers.list = { - figures.identifiers.base, - figures.identifiers.default +identifiers.list = { + identifiers.base, + identifiers.default } -- tracing diff --git a/tex/context/base/grph-swf.lua b/tex/context/base/grph-swf.lua index e55454b52..dc36afa0e 100644 --- a/tex/context/base/grph-swf.lua +++ b/tex/context/base/grph-swf.lua @@ -8,9 +8,12 @@ if not modules then modules = { } end modules ['grph-swf'] = { local format = string.format -local texsprint = tex.sprint -local ctxcatcodes = tex.ctxcatcodes -local pdfannotation = nodes.pdfannotation +local texsprint = tex.sprint +local ctxcatcodes = tex.ctxcatcodes +local nodeinjections = backends.nodeinjections +local pdfannotation = nodes.pool.pdfannotation + +local figures = figures function figures.checkers.swf(data) local dr, du, ds = data.request, data.used, data.status @@ -20,7 +23,7 @@ function figures.checkers.swf(data) dr.width, dr.height = width, height du.width, du.height, du.foundname = width, height, foundname texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}",width,height)) - local annot, preview, ref = backends.pdf.helpers.insertswf { + nodeinjections.insertswf { foundname = foundname, width = width, height = height, @@ -29,11 +32,6 @@ function figures.checkers.swf(data) -- controls = dr.controls, -- label = dr.label, } - -- node.write(pdfannotation(width,-height,0,annot())) - texsprint(ctxcatcodes,format("\\pdfannot width %ssp height %ssp {%s}",width,height,annot())) -- brrrr ---~ if ref then -- wrong ! a direct ref should work ---~ texsprint(ctxcatcodes,format("\\smash{\\pdfrefximage%s\\relax}",ref)) -- brrrr ---~ end texsprint(ctxcatcodes,"\\stopfoundexternalfigure") return data end diff --git a/tex/context/base/grph-u3d.lua b/tex/context/base/grph-u3d.lua index 04ddd1f4e..75bfda287 100644 --- a/tex/context/base/grph-u3d.lua +++ b/tex/context/base/grph-u3d.lua @@ -12,7 +12,10 @@ local trace_inclusion = false trackers.register("figures.inclusion", function( local report_graphics = logs.new("graphics") -local pdfannotation = nodes.pdfannotation +local figures = figures + +local nodeinjections = backends.nodeinjections +local pdfannotation = nodepool.pdfannotation local todimen = string.todimen -- maybe todo: backends.codeinjections.insertu3d @@ -29,17 +32,15 @@ function figures.checkers.u3d(data) end context.startfoundexternalfigure(width .. "sp",height .. "sp") context(function() - local annotation, preview, ref = backends.pdf.helpers.insert3d { - foundname = foundname, - width = width, - height = height, - factor = number.dimenfactors.bp, - display = dr.display, - controls = dr.controls, - label = dr.label, + nodeinjections.insertu3d { + foundname = foundname, + width = width, + height = height, + factor = number.dimenfactors.bp, + display = dr.display, + controls = dr.controls, + label = dr.label, } ---~ print(annotation, preview, ref) - node.write(pdfannotation(width,height,0,annotation())) end) context.stopfoundexternalfigure() return data diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua index 61b57cbc5..98c7145af 100644 --- a/tex/context/base/java-ini.lua +++ b/tex/context/base/java-ini.lua @@ -10,10 +10,11 @@ local format = string.format local concat = table.concat local lpegmatch, lpegP, lpegR, lpegS, lpegC = lpeg.match, lpeg.P, lpeg.R, lpeg.S, lpeg.C -javascripts = javascripts or { } -javascripts.codes = javascripts.codes or { } -javascripts.preambles = javascripts.preambles or { } -javascripts.functions = javascripts.functions or { } +interactions.javascripts = interactions.javascripts or { } +local javascripts = interactions.javascripts +javascripts.codes = javascripts.codes or { } +javascripts.preambles = javascripts.preambles or { } +javascripts.functions = javascripts.functions or { } local codes, preambles, functions = javascripts.codes, javascripts.preambles, javascripts.functions diff --git a/tex/context/base/java-ini.mkiv b/tex/context/base/java-ini.mkiv index 6536ced48..23379c357 100644 --- a/tex/context/base/java-ini.mkiv +++ b/tex/context/base/java-ini.mkiv @@ -109,7 +109,7 @@ {\begingroup\obeylualines\obeyluatokens\dostartJScode} \long\def\dostartJScode#1\stopJScode - {\normalexpanded{\endgroup\ctxlua{javascripts.storecode(\!!bs#1\!!es)}}} + {\normalexpanded{\endgroup\ctxlua{interactions.javascripts.storecode(\!!bs#1\!!es)}}} \let\stopJScode\relax @@ -117,14 +117,13 @@ {\begingroup\obeylualines\obeyluatokens\dostartJSpreamble} \long\def\dostartJSpreamble#1\stopJSpreamble - {\normalexpanded{\endgroup\ctxlua{javascripts.storepreamble(\!!bs#1\!!es)}}} + {\normalexpanded{\endgroup\ctxlua{interactions.javascripts.storepreamble(\!!bs#1\!!es)}}} \let\stopJSpreamble\relax -\def\setJSpreamble #1#2{\ctxlua{javascripts.storepreamble ("#1",\!!bs#2\!!es)}} -\def\addtoJSpreamble #1#2{\ctxlua{javascripts.addtopreamble ("#1",\!!bs#2\!!es)}} -\def\useJSpreamblenow #1{\ctxlua{javascripts.usepreamblenow("#1")}} -\def\finalflushJSpreamble{\iflocation\ctxlua{javascripts.flushpreambles()}\fi} +\def\setJSpreamble #1#2{\ctxlua{interactions.javascripts.storepreamble ("#1",\!!bs#2\!!es)}} +\def\addtoJSpreamble #1#2{\ctxlua{interactions.javascripts.addtopreamble ("#1",\!!bs#2\!!es)}} +\def\useJSpreamblenow #1{\ctxlua{interactions.javascripts.usepreamblenow("#1")}} %D \macros %D {useJSscripts} diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua index 28d4f88b2..aa04951bf 100644 --- a/tex/context/base/l-aux.lua +++ b/tex/context/base/l-aux.lua @@ -6,316 +6,8 @@ if not modules then modules = { } end modules ['l-aux'] = { license = "see context related readme files" } --- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end - aux = aux or { } -local concat, format, gmatch = table.concat, string.format, string.gmatch -local tostring, type = tostring, type -local lpegmatch = lpeg.match - -local P, R, V = lpeg.P, lpeg.R, lpeg.V - -local escape, left, right = P("\\"), P('{'), P('}') - -lpeg.patterns.balanced = P { - [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0, - [2] = left * V(1) * right -} - -local space = lpeg.P(' ') -local equal = lpeg.P("=") -local comma = lpeg.P(",") -local lbrace = lpeg.P("{") -local rbrace = lpeg.P("}") -local nobrace = 1 - (lbrace+rbrace) -local nested = lpeg.P { lbrace * (nobrace + lpeg.V(1))^0 * rbrace } -local spaces = space^0 - -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) - -local key = lpeg.C((1-equal-comma)^1) -local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C("")) -local pattern_c = (space+comma)^0 * (key * equal * value) - -local key = lpeg.C((1-space-equal-comma)^1) -local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + lpeg.C(""))) - --- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored - -local hash = { } - -local function set(key,value) -- using Carg is slower here - hash[key] = value -end - -local pattern_a_s = (pattern_a/set)^1 -local pattern_b_s = (pattern_b/set)^1 -local pattern_c_s = (pattern_c/set)^1 - -aux.settings_to_hash_pattern_a = pattern_a_s -aux.settings_to_hash_pattern_b = pattern_b_s -aux.settings_to_hash_pattern_c = pattern_c_s - -function aux.make_settings_to_hash_pattern(set,how) - if how == "strict" then - return (pattern_c/set)^1 - elseif how == "tolerant" then - return (pattern_b/set)^1 - else - return (pattern_a/set)^1 - end -end - -function aux.settings_to_hash(str,existing) - if str and str ~= "" then - hash = existing or { } - lpegmatch(pattern_a_s,str) - return hash - else - return { } - end -end - -function aux.settings_to_hash_tolerant(str,existing) - if str and str ~= "" then - hash = existing or { } - lpegmatch(pattern_b_s,str) - return hash - else - return { } - end -end - -function aux.settings_to_hash_strict(str,existing) - if str and str ~= "" then - hash = existing or { } - lpegmatch(pattern_c_s,str) - return next(hash) and hash - else - return nil - end -end - -local separator = comma * space^0 -local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(separator*value)^0) - --- "aap, {noot}, mies" : outer {} removes, leading spaces ignored - -aux.settings_to_array_pattern = pattern - --- we could use a weak table as cache - -function aux.settings_to_array(str) - if not str or str == "" then - return { } - else - return lpegmatch(pattern,str) - end -end - -local function set(t,v) - t[#t+1] = v -end - -local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(separator*value)^0 * lpeg.Carg(1) - -function aux.add_settings_to_array(t,str) - return lpegmatch(pattern,str,nil,t) -end - -function aux.hash_to_string(h,separator,yes,no,strict,omit) - if h then - local t, s = { }, table.sortedkeys(h) - omit = omit and table.tohash(omit) - for i=1,#s do - local key = s[i] - if not omit or not omit[key] then - local value = h[key] - if type(value) == "boolean" then - if yes and no then - if value then - t[#t+1] = key .. '=' .. yes - elseif not strict then - t[#t+1] = key .. '=' .. no - end - elseif value or not strict then - t[#t+1] = key .. '=' .. tostring(value) - end - else - t[#t+1] = key .. '=' .. value - end - end - end - return concat(t,separator or ",") - else - return "" - end -end - -function aux.array_to_string(a,separator) - if a then - return concat(a,separator or ",") - else - return "" - end -end - -function aux.settings_to_set(str,t) -- tohash? - t = t or { } - for s in gmatch(str,"%s*([^, ]+)") do -- space added - t[s] = true - end - return t -end - -function aux.simple_hash_to_string(h, separator) - local t = { } - for k, v in table.sortedhash(h) do - if v then - t[#t+1] = k - end - end - return concat(t,separator or ",") -end - -local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace -local pattern = lpeg.Ct((space + value)^0) - -function aux.arguments_to_table(str) - return lpegmatch(pattern,str) -end - --- temporary here - -function aux.getparameters(self,class,parentclass,settings) - local sc = self[class] - if not sc then - sc = table.clone(self[parent]) - self[class] = sc - end - aux.settings_to_hash(settings,sc) -end - --- temporary here - -local digit = lpeg.R("09") -local period = lpeg.P(".") -local zero = lpeg.P("0") -local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") -local number = digit^1 * (case_1 + case_2) -local stripper = lpeg.Cs((number + 1)^0) - ---~ local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100" ---~ collectgarbage("collect") ---~ str = string.rep(sample,10000) ---~ local ts = os.clock() ---~ lpegmatch(stripper,str) ---~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) - -lpeg.patterns.strip_zeros = stripper - -function aux.strip_zeros(str) - return lpegmatch(stripper,str) -end - -function aux.definetable(target) -- defines undefined tables - local composed, t = nil, { } - for name in gmatch(target,"([^%.]+)") do - if composed then - composed = composed .. "." .. name - else - composed = name - end - t[#t+1] = format("%s = %s or { }",composed,composed) - end - return concat(t,"\n") -end - -function aux.accesstable(target) - local t = _G - for name in gmatch(target,"([^%.]+)") do - t = t[name] - end - return t -end - ---~ function string.commaseparated(str) ---~ return gmatch(str,"([^,%s]+)") ---~ end - --- as we use this a lot ... - ---~ function aux.cachefunction(action,weak) ---~ local cache = { } ---~ if weak then ---~ setmetatable(cache, { __mode = "kv" } ) ---~ end ---~ local function reminder(str) ---~ local found = cache[str] ---~ if not found then ---~ found = action(str) ---~ cache[str] = found ---~ end ---~ return found ---~ end ---~ return reminder, cache ---~ end - -function aux.formatcolumns(result,between) - if result and #result > 0 then - between = between or " " - local widths, numbers = { }, { } - local first = result[1] - local n = #first - for i=1,n do - widths[i] = 0 - end - for i=1,#result do - local r = result[i] - for j=1,n do - local rj = r[j] - local tj = type(rj) - if tj == "number" then - numbers[j] = true - end - if tj ~= "string" then - rj = tostring(rj) - r[j] = rj - end - local w = #rj - if w > widths[j] then - widths[j] = w - end - end - end - for i=1,n do - local w = widths[i] - if numbers[i] then - if w > 80 then - widths[i] = "%s" .. between - else - widths[i] = "%0" .. w .. "i" .. between - end - else - if w > 80 then - widths[i] = "%s" .. between - elseif w > 0 then - widths[i] = "%-" .. w .. "s" .. between - else - widths[i] = "%s" - end - end - end - local template = string.strip(concat(widths)) - for i=1,#result do - local str = format(template,unpack(result[i])) - result[i] = string.strip(str) - end - end - return result -end +require("util-int") for k, v in next, utilities.interfaces do aux[k] = v end +require("util-tab") for k, v in next, utilities.tables do aux[k] = v end +require("util-fmt") for k, v in next, utilities.formatters do aux[k] = v end diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua index cf8dc0ac8..cf92d2f41 100644 --- a/tex/context/base/l-boolean.lua +++ b/tex/context/base/l-boolean.lua @@ -6,10 +6,11 @@ if not modules then modules = { } end modules ['l-boolean'] = { license = "see context related readme files" } -boolean = boolean or { } - local type, tonumber = type, tonumber +boolean = boolean or { } +local boolean = boolean + function boolean.tonumber(b) if b then return 1 else return 0 end end diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua index 5b8a5c3df..35fca56da 100644 --- a/tex/context/base/l-dimen.lua +++ b/tex/context/base/l-dimen.lua @@ -19,6 +19,7 @@ local format, match, gsub, type, setmetatable = string.format, string.match, str local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match number = number or { } +local number = number number.tonumberf = function(n) return match(format("%.20f",n),"(.-0?)0*$") end -- one zero too much but alas number.tonumberg = function(n) return format("%.20g",n) end diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua index 64ebbeafc..04b3925e7 100644 --- a/tex/context/base/l-dir.lua +++ b/tex/context/base/l-dir.lua @@ -10,20 +10,30 @@ if not modules then modules = { } end modules ['l-dir'] = { local type = type local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local concat = table.concat local lpegmatch = lpeg.match +local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V + dir = dir or { } +local dir = dir +local lfs = lfs + +local attributes = lfs.attributes +local walkdir = lfs.dir +local isdir = lfs.isdir +local isfile = lfs.isfile +local mkdir = lfs.mkdir +local chdir = lfs.chdir +local currentdir = lfs.currentdir -- handy function dir.current() - return (gsub(lfs.currentdir(),"\\","/")) + return (gsub(currentdir(),"\\","/")) end --- optimizing for no string.find (*) does not save time - -local attributes = lfs.attributes -local walkdir = lfs.dir +-- optimizing for no find (*) does not save time local function glob_pattern(path,patt,recurse,action) local ok, scanner @@ -79,8 +89,6 @@ end dir.collect_pattern = collect_pattern -local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V - local pattern = Ct { [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3), [2] = C(((1-S("*?/"))^0 * P("/"))^0), @@ -103,7 +111,7 @@ local function glob(str,t) for s=1,#str do glob(str[s],t) end - elseif lfs.isfile(str) then + elseif isfile(str) then t(str) else local split = lpegmatch(pattern,str) @@ -122,7 +130,7 @@ local function glob(str,t) glob(str[s],t) end return t - elseif lfs.isfile(str) then + elseif isfile(str) then local t = t or { } t[#t+1] = str return t @@ -191,7 +199,7 @@ dir.globfiles = globfiles -- print(dir.ls("*.tex")) function dir.ls(pattern) - return table.concat(glob(pattern),"\n") + return concat(glob(pattern),"\n") end --~ mkdirs("temp") @@ -201,7 +209,7 @@ end local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then -- os.type == "windows" +if find(os.getenv("PATH"),";") then -- os.type == "windows" function dir.mkdirs(...) local str, pth, t = "", "", { ... } @@ -250,11 +258,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" else pth = pth .. "/" .. s end - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end --~ print(dir.mkdirs("","","a","c")) @@ -280,11 +288,11 @@ if string.find(os.getenv("PATH"),";") then -- os.type == "windows" if not first then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then - local d = lfs.currentdir() - if lfs.chdir(first) then + local d = currentdir() + if chdir(first) then first = dir.current() end - lfs.chdir(d) + chdir(d) end end if not first then @@ -325,20 +333,20 @@ else else pth = pth .. "/" .. s end - if make_indeed and not first and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not first and not isdir(pth) then + mkdir(pth) end end else pth = "." for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s - if make_indeed and not lfs.isdir(pth) then - lfs.mkdir(pth) + if make_indeed and not isdir(pth) then + mkdir(pth) end end end - return pth, (lfs.isdir(pth) == true) + return pth, (isdir(pth) == true) end --~ print(dir.mkdirs("","","a","c")) @@ -351,7 +359,7 @@ else function dir.expand_name(str) -- will be merged with cleanpath and collapsepath if not find(str,"^/") then - str = lfs.currentdir() .. "/" .. str + str = currentdir() .. "/" .. str end str = gsub(str,"//","/") str = gsub(str,"/%./","/") diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua index b528d9a7d..1b4e91f77 100644 --- a/tex/context/base/l-file.lua +++ b/tex/context/base/l-file.lua @@ -9,12 +9,15 @@ if not modules then modules = { } end modules ['l-file'] = { -- needs a cleanup file = file or { } +local file = file local insert, concat = table.insert, table.concat local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char local lpegmatch = lpeg.match local getcurrentdir = lfs.currentdir +local P, R, S, C, Cs, Cp, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc + local function dirname(name,default) return match(name,"^(.+)[/\\].-$") or (default or "") end @@ -285,31 +288,31 @@ end -- lpeg variants, slightly faster, not always ---~ local period = lpeg.P(".") ---~ local slashes = lpeg.S("\\/") +--~ local period = P(".") +--~ local slashes = S("\\/") --~ local noperiod = 1-period --~ local noslashes = 1-slashes --~ local name = noperiod^1 ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * C(noperiod^1) * -1 --~ function file.extname(name) --~ return lpegmatch(pattern,name) or "" --~ end ---~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) +--~ local pattern = Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) --~ return lpegmatch(pattern,name) --~ end ---~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 +--~ local pattern = (noslashes^0 * slashes)^1 * C(noslashes^1) * -1 --~ function file.basename(name) --~ return lpegmatch(pattern,name) or name --~ end ---~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^1 * Cp() * noslashes^1 * -1 --~ function file.dirname(name) --~ local p = lpegmatch(pattern,name) @@ -320,7 +323,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) --~ local p = lpegmatch(pattern,name) @@ -331,7 +334,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) --~ local p = lpegmatch(pattern,name) @@ -342,7 +345,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * Cp() * ((noperiod^1 * period)^1 * Cp() + P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) --~ local a, b = lpegmatch(pattern,name) @@ -374,11 +377,11 @@ end -- also rewrite previous -local letter = lpeg.R("az","AZ") + lpeg.S("_-+") -local separator = lpeg.P("://") +local letter = R("az","AZ") + S("_-+") +local separator = P("://") -local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/") -local rootbased = lpeg.P("/") + letter*lpeg.P(":") +local qualified = P(".")^0 * P("/") + letter*P(":") + letter^1*separator + letter^1 * P("/") +local rootbased = P("/") + letter*P(":") -- ./name ../name /name c: :// name/name @@ -390,14 +393,16 @@ function file.is_rootbased_path(filename) return lpegmatch(rootbased,filename) ~= nil end -local slash = lpeg.S("\\/") -local period = lpeg.P(".") -local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":") -local path = lpeg.C(((1-slash)^0 * slash)^0) -local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1)) -local base = lpeg.C((1-suffix)^0) +-- actually these are schemes + +local slash = S("\\/") +local period = P(".") +local drive = C(R("az","AZ")) * P(":") +local path = C(((1-slash)^0 * slash)^0) +local suffix = period * C(P(1-period)^0 * P(-1)) +local base = C((1-suffix)^0) -local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) function file.splitname(str) -- returns drive, path, base, suffix return lpegmatch(pattern,str) diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua index 89227a63f..cf8852fd6 100644 --- a/tex/context/base/l-io.lua +++ b/tex/context/base/l-io.lua @@ -6,7 +6,9 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte, find, gsub = string.byte, string.find, string.gsub +local io = io +local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format +local concat = table.concat if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -17,9 +19,7 @@ end function io.loaddata(filename,textmode) local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- collectgarbage("step") -- sometimes makes a big difference in mem consumption local data = f:read('*all') - -- garbagecollector.check(data) f:close() return data else @@ -31,7 +31,7 @@ function io.savedata(filename,data,joiner) local f = io.open(filename,"wb") if f then if type(data) == "table" then - f:write(table.join(data,joiner or "")) + f:write(concat(data,joiner or "")) elseif type(data) == "function" then data(f) else @@ -157,12 +157,12 @@ function io.ask(question,default,options) while true do io.write(question) if options then - io.write(string.format(" [%s]",table.concat(options,"|"))) + io.write(format(" [%s]",concat(options,"|"))) end if default then - io.write(string.format(" [%s]",default)) + io.write(format(" [%s]",default)) end - io.write(string.format(" ")) + io.write(format(" ")) local answer = io.read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then diff --git a/tex/context/base/l-md5.lua b/tex/context/base/l-md5.lua index 27955ef9b..f9197c56e 100644 --- a/tex/context/base/l-md5.lua +++ b/tex/context/base/l-md5.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['l-md5'] = { -- This also provides file checksums and checkers. +local md5, file = md5, file local gsub, format, byte = string.gsub, string.format, string.byte local function convert(str,fmt) diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua index 7a59e1b2a..8a7340905 100644 --- a/tex/context/base/l-number.lua +++ b/tex/context/base/l-number.lua @@ -10,7 +10,8 @@ local tostring = tostring local format, floor, insert, match = string.format, math.floor, table.insert, string.match local lpegmatch = lpeg.match -number = number or { } +number = number or { } +local number = number -- a,b,c,d,e,f = number.toset(100101) diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua index 0d06c4673..c58983cfc 100644 --- a/tex/context/base/l-os.lua +++ b/tex/context/base/l-os.lua @@ -8,10 +8,10 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute +local os = os local find, format, gsub, upper = string.find, string.format, string.gsub, string.upper local random, ceil = math.random, math.ceil local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber -- The following code permits traversing the environment table, at least -- in luatex. Internally all environment names are uppercase. diff --git a/tex/context/base/l-set.lua b/tex/context/base/l-set.lua index f844d0b40..e78b67876 100644 --- a/tex/context/base/l-set.lua +++ b/tex/context/base/l-set.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['l-set'] = { license = "see context related readme files" } +-- This will become obsolete when we have the bitset library embedded. + set = set or { } local nums = { } diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua index 9856d5212..cc04168e9 100644 --- a/tex/context/base/l-string.lua +++ b/tex/context/base/l-string.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } +local string = string local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower local lpegmatch = lpeg.match @@ -165,18 +166,6 @@ end string.padd = string.rpadd -function is_number(str) -- tonumber - return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1 -end - ---~ print(is_number("1")) ---~ print(is_number("1.1")) ---~ print(is_number(".1")) ---~ print(is_number("-0.1")) ---~ print(is_number("+0.1")) ---~ print(is_number("-.1")) ---~ print(is_number("+.1")) - function string:split_settings() -- no {} handling, see l-aux for lpeg variant if find(self,"=") then local t = { } diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua index c3ef364a5..67216d1f5 100644 --- a/tex/context/base/l-table.lua +++ b/tex/context/base/l-table.lua @@ -6,12 +6,10 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -table.join = table.concat - +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match local getmetatable, setmetatable = getmetatable, setmetatable -local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs -- Starting with version 5.2 Lua no longer provide ipairs, which makes -- sense. As we already used the for loop and # in most places the diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua index dc78f7325..10f21e325 100644 --- a/tex/context/base/l-unicode.lua +++ b/tex/context/base/l-unicode.lua @@ -29,6 +29,8 @@ if not unicode then end +local unicode = unicode + utf = utf or unicode.utf8 local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub @@ -200,7 +202,7 @@ end function unicode.utfcodes(str) local t = { } - for k,v in string.utfvalues(str) do + for k,v in utfvalues(str) do t[#t+1] = format("0x%04X",k) end return concat(t,separator or " ") diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua index 43fe73d2b..a161d2265 100644 --- a/tex/context/base/l-url.lua +++ b/tex/context/base/l-url.lua @@ -21,7 +21,8 @@ local lpegmatch, lpegP, lpegC, lpegR, lpegS, lpegCs, lpegCc = lpeg.match, lpeg.P -- / \ / \ -- urn:example:animal:ferret:nose -url = url or { } +url = url or { } +local url = url local function tochar(s) return char(tonumber(s,16)) diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua index d03426812..30df04694 100644 --- a/tex/context/base/l-utils.lua +++ b/tex/context/base/l-utils.lua @@ -1,156 +1,12 @@ if not modules then modules = { } end modules ['l-utils'] = { version = 1.001, - comment = "companion to luat-lib.mkiv", + comment = "this module is replaced by the util-* ones", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } --- hm, quite unreadable - -local gsub, format = string.gsub, string.format -local concat = table.concat -local type, next = type, next - -if not utils then utils = { } end -if not utils.merger then utils.merger = { } end -if not utils.lua then utils.lua = { } end - -utils.report = utils.report or print - -local merger = utils.merger - -merger.strip_comment = true - -local m_begin_merge = "begin library merge" -local m_end_merge = "end library merge" -local m_begin_closure = "do -- create closure to overcome 200 locals limit" -local m_end_closure = "end -- of closure" - -local m_pattern = - "%c+" .. - "%-%-%s+" .. m_begin_merge .. - "%c+(.-)%c+" .. - "%-%-%s+" .. m_end_merge .. - "%c+" - -local m_format = - "\n\n-- " .. m_begin_merge .. - "\n%s\n" .. - "-- " .. m_end_merge .. "\n\n" - -local m_faked = - "-- " .. "created merged file" .. "\n\n" .. - "-- " .. m_begin_merge .. "\n\n" .. - "-- " .. m_end_merge .. "\n\n" - -local function self_fake() - return m_faked -end - -local function self_nothing() - return "" -end - -local function self_load(name) - local data = io.loaddata(name) or "" - if data == "" then - utils.report("merge: unknown file %s",name) - else - utils.report("merge: inserting %s",name) - end - return data or "" -end - -local function self_save(name, data) - if data ~= "" then - if merger.strip_comment then - -- saves some 20K - local n = #data - data = gsub(data,"%-%-~[^\n\r]*[\r\n]","") - utils.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) - end - io.savedata(name,data) - utils.report("merge: saving %s",name) - end -end - -local function self_swap(data,code) - return data ~= "" and (gsub(data,m_pattern, function() return format(m_format,code) end, 1)) or "" -end - -local function self_libs(libs,list) - local result, f, frozen, foundpath = { }, nil, false, nil - result[#result+1] = "\n" - if type(libs) == 'string' then libs = { libs } end - if type(list) == 'string' then list = { list } end - for i=1,#libs do - local lib = libs[i] - for j=1,#list do - local pth = gsub(list[j],"\\","/") -- file.clean_path - utils.report("merge: checking library path %s",pth) - local name = pth .. "/" .. lib - if lfs.isfile(name) then - foundpath = pth - end - end - if foundpath then break end - end - if foundpath then - utils.report("merge: using library path %s",foundpath) - local right, wrong = { }, { } - for i=1,#libs do - local lib = libs[i] - local fullname = foundpath .. "/" .. lib - if lfs.isfile(fullname) then - utils.report("merge: using library %s",fullname) - right[#right+1] = lib - result[#result+1] = m_begin_closure - result[#result+1] = io.loaddata(fullname,true) - result[#result+1] = m_end_closure - else - utils.report("merge: skipping library %s",fullname) - wrong[#wrong+1] = lib - end - end - if #right > 0 then - utils.report("merge: used libraries: %s",concat(right," ")) - end - if #wrong > 0 then - utils.report("merge: skipped libraries: %s",concat(wrong," ")) - end - else - utils.report("merge: no valid library path found") - end - return concat(result, "\n\n") -end - -function merger.selfcreate(libs,list,target) - if target then - self_save(target,self_swap(self_fake(),self_libs(libs,list))) - end -end - -function merger.selfmerge(name,libs,list,target) - self_save(target or name,self_swap(self_load(name),self_libs(libs,list))) -end - -function merger.selfclean(name) - self_save(name,self_swap(self_load(name),self_nothing())) -end - -function utils.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true - utils.report("lua: compiling %s into %s",luafile,lucfile) - os.remove(lucfile) - local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) - if strip ~= false then - command = "-s " .. command - end - local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 - if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - utils.report("lua: removing %s",luafile) - os.remove(luafile) - end - return done -end +utils = utils or { } +require("util-mrg") for k, v in next, utilities.merger do utils[k] = v end +require("util-lua") for k, v in next, utilities.lua do utils[k] = v end diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua index 0bea12e46..afb933276 100644 --- a/tex/context/base/lang-ini.lua +++ b/tex/context/base/lang-ini.lua @@ -22,6 +22,7 @@ local format, gsub = string.format, string.gsub local concat = table.concat local lpegmatch = lpeg.match local texwrite = tex.write +local settings_to_array = utilities.parsers.settings_to_array local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end) @@ -33,18 +34,23 @@ local lefthyphenmin, righthyphenmin = lang.lefthyphenmin, lang.righthyphenmin lang.exceptions = lang.hyphenation languages = languages or {} +local languages = languages + languages.version = 1.010 + languages.registered = languages.registered or { } +local registered = languages.registered + languages.associated = languages.associated or { } +local associated = languages.associated + languages.numbers = languages.numbers or { } +local numbers = languages.numbers -storage.register("languages/numbers", languages.numbers, "languages.numbers") -storage.register("languages/registered",languages.registered,"languages.registered") -storage.register("languages/associated",languages.associated,"languages.associated") +storage.register("languages/numbers", numbers, "languages.numbers") +storage.register("languages/registered",registered,"languages.registered") +storage.register("languages/associated",associated,"languages.associated") -local numbers = languages.numbers -local registered = languages.registered -local associated = languages.associated local nofloaded = 0 local function resolve(tag) @@ -77,7 +83,7 @@ end local function loaddefinitions(tag,specification) statistics.starttiming(languages) local data, instance = resolve(tag) - local definitions = aux.settings_to_array(specification.patterns or "") + local definitions = settings_to_array(specification.patterns or "") if #definitions > 0 then local dataused, ok = data.used, false for i=1,#definitions do diff --git a/tex/context/base/lang-url.lua b/tex/context/base/lang-url.lua index b0a71ec67..d8723db78 100644 --- a/tex/context/base/lang-url.lua +++ b/tex/context/base/lang-url.lua @@ -13,7 +13,8 @@ local utfbyte, utfgsub = utf.byte, utf.gsub local ctxcatcodes, texsprint = tex.ctxcatcodes, tex.sprint -commands = commands or { } +commands = commands or { } +local commands = commands --[[ <p>Hyphenating <l n='url'/>'s is somewhat tricky and a matter of taste. I did @@ -23,8 +24,7 @@ dealing with <l n='ascii'/> characters.</p> ]]-- commands.hyphenatedurl = commands.hyphenatedurl or { } - -local hyphenatedurl = commands.hyphenatedurl +local hyphenatedurl = commands.hyphenatedurl hyphenatedurl.characters = { ["!"] = 1, diff --git a/tex/context/base/lang-wrd.lua b/tex/context/base/lang-wrd.lua index 6e3caed12..43e91f09d 100644 --- a/tex/context/base/lang-wrd.lua +++ b/tex/context/base/lang-wrd.lua @@ -9,40 +9,46 @@ if not modules then modules = { } end modules ['lang-ini'] = { local utf = unicode.utf8 local lower, utfchar = string.lower, utf.char local lpegmatch = lpeg.match +local P, S, Cs = lpeg.P, lpeg.S, lpeg.Cs local report_languages = logs.new("languages") -languages.words = languages.words or { } +local nodes, node, languages = nodes, node, languages -local words = languages.words +languages.words = languages.words or { } +local words = languages.words -words.data = words.data or { } -words.enables = false -words.threshold = 4 +words.data = words.data or { } +words.enables = false +words.threshold = 4 local set_attribute = node.set_attribute local unset_attribute = node.unset_attribute local traverse_nodes = node.traverse local wordsdata = words.data local chardata = characters.data +local tasks = nodes.tasks -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes -local glyph_node = nodecodes.glyph -local disc_node = nodecodes.disc -local kern_node = nodecodes.kern +local glyph_node = nodecodes.glyph +local disc_node = nodecodes.disc +local kern_no de = nodecodes.kern + +local kerning_code = kerncodes.kerning words.colors = { ["known"] = "green", ["unknown"] = "red", } -local spacing = lpeg.S(" \n\r\t") -local markup = lpeg.S("-=") -local lbrace = lpeg.P("{") -local rbrace = lpeg.P("}") +local spacing = S(" \n\r\t") +local markup = S("-=") +local lbrace = P("{") +local rbrace = P("}") local disc = (lbrace * (1-rbrace)^0 * rbrace)^1 -- or just 3 times, time this -local word = lpeg.Cs((markup/"" + disc/"" + (1-spacing))^1) +local word = Cs((markup/"" + disc/"" + (1-spacing))^1) local loaded = { } -- we share lists @@ -115,7 +121,8 @@ local function mark_words(head,whenfound) -- can be optimized end else local code = current.char - if chardata[code].uccode or chardata[code].lccode then + local data = chardata[code] + if data.uccode or data.lccode then start = start or current n = n + 1 str = str .. utfchar(code) @@ -127,7 +134,7 @@ local function mark_words(head,whenfound) -- can be optimized if n > 0 then n = n + 1 end - elseif id == kern_node and current.subtype == 0 and start then + elseif id == kern_node and current.subtype == kerning_code and start then -- ok elseif start then action() @@ -141,10 +148,10 @@ local function mark_words(head,whenfound) -- can be optimized end words.methods = { } -words.method = 1 - local methods = words.methods +local wordmethod = 1 + methods[1] = function(head, attribute, yes, nop) local right, wrong = false, false if yes then right = function(n) set_attribute(n,attribute,yes) end end @@ -169,13 +176,13 @@ end local list, dump = { }, false -- todo: per language -local lower = characters.lower +local lowerchar = characters.lower methods[2] = function(head, attribute) dump = true mark_words(head, function(language,str) if #str >= words.threshold then - str = lower(str) + str = lowerchar(str) list[str] = (list[str] or 0) + 1 end end) @@ -193,11 +200,13 @@ end local color = attributes.private('color') +local enabled = false + function words.check(head) - if words.enabled and head.next then + if enabled and head.next then local colors = words.colors local alc = attributes.list[color] - return methods[words.method](head, color, alc[colors.known], alc[colors.unknown]) + return methods[wordmethod](head, color, alc[colors.known], alc[colors.unknown]) else return head, false end @@ -205,12 +214,12 @@ end function words.enable(method) tasks.enableaction("processors","languages.words.check") - words.method = method or words.method or 1 - words.enabled = true + wordmethod = method or wordmethod or 1 + enabled = true end function words.disable() - words.enabled = false + enabled = false end -- for the moment we hook it into the attribute handler diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua index 89ccb2235..a57372ea1 100644 --- a/tex/context/base/lpdf-ano.lua +++ b/tex/context/base/lpdf-ano.lua @@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['lpdf-ano'] = { local tostring, format, rep = tostring, string.rep, string.format local texcount = tex.count +local backends, lpdf = backends, lpdf + local trace_references = false trackers.register("references.references", function(v) trace_references = v end) local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end) local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) @@ -20,20 +22,26 @@ local report_bookmarks = logs.new("bookmarks") local variables = interfaces.variables local constants = interfaces.constants +local settings_to_array = utilities.parsers.settings_to_array + local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations -jobreferences = jobreferences or { } -jobreferences.runners = jobreferences.runners or { } -jobreferences.specials = jobreferences.specials or { } -jobreferences.handlers = jobreferences.handlers or { } -jobreferences.executers = jobreferences.executers or { } +local javascriptcode = interactions.javascripts.code + +local references = structures.references +local bookmarks = structures.bookmarks -local runners = jobreferences.runners -local specials = jobreferences.specials -local handlers = jobreferences.handlers -local executers = jobreferences.executers +references.runners = references.runners or { } +references.specials = references.specials or { } +references.handlers = references.handlers or { } +references.executers = references.executers or { } + +local runners = references.runners +local specials = references.specials +local handlers = references.handlers +local executers = references.executers local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -44,8 +52,10 @@ local pdfflushobject = lpdf.flushobject local pdfreserveobject = lpdf.reserveobject local pdfpagereference = lpdf.pagereference -local pdfannotation_node = nodes.pdfannotation -local pdfdestination_node = nodes.pdfdestination +local nodepool = nodes.pool + +local pdfannotation_node = nodepool.pdfannotation +local pdfdestination_node = nodepool.pdfdestination local pdf_uri = pdfconstant("URI") local pdf_gotor = pdfconstant("GoToR") @@ -59,7 +69,7 @@ local pdf_border = pdfarray { 0, 0, 0 } local cache = { } -local function pagedest(n) +local function pagedestination(n) -- only cache fit if n > 0 then local pd = cache[n] if not pd then @@ -74,7 +84,26 @@ local function pagedest(n) end end -lpdf.pagedest = pagedest +lpdf.pagedestination = pagedestination + +--~ local cache = { } + +--~ local function gotopagedestination(n) -- could be reference instead +--~ if n > 0 then +--~ local pd = cache[n] +--~ if not pd then +--~ local d = pdfdictionary { -- can be cached +--~ S = pdf_goto, +--~ D = pagedestination(p), +--~ } +--~ pd = pdfreference(pdfflushobject(d)) +--~ cache[n] = pd +--~ end +--~ return pd +--~ end +--~ end + +--~ lpdf.gotopagedestination = gotopagedestination local defaultdestination = pdfarray { 0, pdfconstant("Fit") } @@ -123,7 +152,7 @@ local function link(url,filename,destination,page,actions) else texcount.referencepagestate = 1 end - return pdfdictionary { + return pdfdictionary { -- can be cached S = pdf_goto, D = destination, } @@ -137,9 +166,10 @@ local function link(url,filename,destination,page,actions) else texcount.referencepagestate = 1 end - return pdfdictionary { + --~ return gotopagedestination(p) + return pdfdictionary { -- can be cached S = pdf_goto, - D = pagedest(p), + D = pagedestination(p), } else commands.writestatus("references","invalid page reference: %s",page or "?") @@ -165,7 +195,7 @@ function lpdf.launch(program,parameters) end function lpdf.javascript(name,arguments) - local script = javascripts.code(name,arguments) -- make into object (hash) + local script = javascriptcode(name,arguments) -- make into object (hash) if script then return pdfdictionary { S = pdf_javascript, @@ -280,12 +310,12 @@ runners["inner with arguments"] = function(var,actions) end runners["outer"] = function(var,actions) - local file, url = jobreferences.checkedfileorurl(var.outer,var.outer) + local file, url = references.checkedfileorurl(var.outer,var.outer) return link(url,file,var.arguments,nil,actions) end runners["outer with inner"] = function(var,actions) - local file = jobreferences.checkedfile(var.f) + local file = references.checkedfile(var.f) return link(nil,file,var.inner,var.r,actions) end @@ -329,7 +359,7 @@ runners["special operation with arguments"] = runners["special"] function specials.internal(var,actions) -- better resolve in strc-ref local i = tonumber(var.operation) - local v = jobreferences.internals[i] + local v = references.internals[i] if not v then -- error elseif method == "internal" then @@ -346,10 +376,10 @@ specials.i = specials.internal function specials.page(var,actions) -- better resolve in strc-ref local file = var.f if file then - file = jobreferences.checkedfile(file) + file = references.checkedfile(file) return link(nil,file,nil,var.operation,actions) else - local p = jobreferences.pages[var.operation] + local p = references.pages[var.operation] if type(p) == "function" then p = p() end @@ -361,7 +391,7 @@ end local splitter = lpeg.splitat(":") -function specials.order(var,actions) -- jobreferences.specials ! +function specials.order(var,actions) -- references.specials ! local operation = var.operation if operation then local kind, name, n = lpegmatch(splitter,operation) @@ -377,22 +407,22 @@ function specials.order(var,actions) -- jobreferences.specials ! end function specials.url(var,actions) - local url = jobreferences.checkedurl(var.operation) + local url = references.checkedurl(var.operation) return link(url,nil,var.arguments,nil,actions) end function specials.file(var,actions) - local file = jobreferences.checkedfile(var.operation) + local file = references.checkedfile(var.operation) return link(nil,file,var.arguments,nil,actions) end function specials.fileorurl(var,actions) - local file, url = jobreferences.checkedfileorurl(var.operation,var.operation) + local file, url = references.checkedfileorurl(var.operation,var.operation) return link(url,file,var.arguments,nil,actions) end function specials.program(var,content) - local program = jobreferences.checkedprogram(var.operation) + local program = references.checkedprogram(var.operation) return lpdf.launch(program,var.arguments) end @@ -434,7 +464,7 @@ local function fieldset(arguments) end function executers.resetform(arguments) - arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + arguments = (type(arguments) == "table" and arguments) or settings_to_array(arguments) return pdfdictionary { S = pdfconstant("ResetForm"), Field = fieldset(arguments[1]) @@ -456,7 +486,7 @@ local flags = { } function executers.submitform(arguments) - arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + arguments = (type(arguments) == "table" and arguments) or settings_to_array(arguments) local flag = flags[formmethod] or flags.post flag = (flag and (flag[formformat] or flag.xml)) or 32 -- default: post, xml return pdfdictionary { @@ -491,7 +521,7 @@ local pdf_resume = pdfconstant("Resume") local pdf_pause = pdfconstant("Pause") local function movie_or_sound(operation,arguments) - arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + arguments = (type(arguments) == "table" and arguments) or settings_to_array(arguments) return pdfdictionary { S = pdf_movie, T = format("movie %s",arguments[1] or "noname"), @@ -530,11 +560,13 @@ local function build(levels,start,parent,method) local startlevel = levels[start][1] local i, n = start, 0 local child, entry, m, prev, first, last, f, l --- to be tested: i can be nil while i and i <= #levels do local li = levels[i] local level, title, reference, open = li[1], li[2], li[3], li[4] - if level == startlevel then + if level < startlevel then + pdfflushobject(child,entry) + return i, n, first, last + elseif level == startlevel then if trace_bookmarks then report_bookmarks("%3i %s%s %s",reference.realpage,rep(" ",level-1),(open and "+") or "-",title) end @@ -552,16 +584,13 @@ local function build(levels,start,parent,method) if method == "internal" then entry.Dest = "aut:" .. reference.internal else -- if method == "page" then - entry.Dest = pagedest(reference.realpage) + entry.Dest = pagedestination(reference.realpage) end if not first then first, last = child, child end prev = child last = prev n = n + 1 i = i + 1 - elseif level < startlevel then - pdfflushobject(child,entry) - return i, n, first, last elseif i < #levels and level > startlevel then i, m, f, l = build(levels,i,pdfreference(child),method) entry.Count = (open and m) or -m @@ -584,14 +613,21 @@ local function build(levels,start,parent,method) end function codeinjections.addbookmarks(levels,method) - local parent = pdfreserveobject() - local _, m, first, last = build(levels,1,pdfreference(parent),method or "internal") - local dict = pdfdictionary { - Type = pdfconstant("Outlines"), - First = pdfreference(first), - Last = pdfreference(last), - Count = m, - } - pdfflushobject(parent,dict) - lpdf.addtocatalog("Outlines",lpdf.reference(parent)) + if #levels > 0 then + structures.bookmarks.flatten(levels) -- dirty trick for lack of structure + local parent = pdfreserveobject() + local _, m, first, last = build(levels,1,pdfreference(parent),method or "internal") + local dict = pdfdictionary { + Type = pdfconstant("Outlines"), + First = pdfreference(first), + Last = pdfreference(last), + Count = m, + } + pdfflushobject(parent,dict) + lpdf.addtocatalog("Outlines",lpdf.reference(parent)) + end end + +-- this could also be hooked into the frontend finalizer + +lpdf.registerdocumentfinalizer(function() bookmarks.place() end,1,"bookmarks") diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua index fc2b9cabc..f5612a32b 100644 --- a/tex/context/base/lpdf-col.lua +++ b/tex/context/base/lpdf-col.lua @@ -9,11 +9,12 @@ if not modules then modules = { } end modules ['lpdf-mis'] = { local type = type local format, gsub = string.format, string.gsub --- colors = colors or { } --- transparencies = transparencies or { } +local backends, lpdf = backends, lpdf -local registercolor = colors.register +local colors = attributes.colors +local transparencies = attributes.transparencies local registertransparancy = transparencies.register +local registercolor = colors.register local colorsvalue = colors.value local transparenciesvalue = transparencies.value local forcedmodel = colors.forcedmodel @@ -185,3 +186,17 @@ function lpdf.finishtransparencycode() return "" end end + +-- this will move to lpdf-spe.lua + +backends.pdf.tables.vfspecials = { -- todo: distinguish between glyph and rule color + + red = { "special", 'pdf: 1 0 0 rg 1 0 0 RG' }, + green = { "special", 'pdf: 0 1 0 rg 0 1 0 RG' }, + blue = { "special", 'pdf: 0 0 1 rg 0 0 1 RG' }, + black = { "special", 'pdf: 0 g 0 G' }, + + startslant = function(a) return { "special", format("pdf: q 1 0 %s 1 0 0 cm",a) } end, + stopslant = { "special", "pdf: Q" }, + +} diff --git a/tex/context/base/lpdf-epa.lua b/tex/context/base/lpdf-epa.lua index 35c0c086b..5709ced3f 100644 --- a/tex/context/base/lpdf-epa.lua +++ b/tex/context/base/lpdf-epa.lua @@ -16,7 +16,10 @@ local trace_links = false trackers.register("figures.links", function(v) trace_ local report_link = logs.new("links") -local variables = interfaces.variables +local backends, lpdf = backends, lpdf + +local variables = interfaces.variables +local codeinjections = backends.pdf.codeinjections local function add_link(x,y,w,h,destination,what) if trace_links then @@ -89,7 +92,7 @@ local function link_file(x,y,w,h,document,annotation) end end -function backends.codeinjections.mergereferences(specification) +function codeinjections.mergereferences(specification) if figures and not specification then specification = figures and figures.current() specification = specification and specification.status @@ -142,7 +145,7 @@ function backends.codeinjections.mergereferences(specification) return ""-- no namespace, empty, not nil end -function backends.codeinjections.mergelayers(specification) +function codeinjections.mergeviewerlayers(specification) if not specification then specification = figures and figures.current() specification = specification and specification.status diff --git a/tex/context/base/lpdf-epd.lua b/tex/context/base/lpdf-epd.lua index 680c39e18..8a17aeb6b 100644 --- a/tex/context/base/lpdf-epd.lua +++ b/tex/context/base/lpdf-epd.lua @@ -26,7 +26,7 @@ local setmetatable, rawset = setmetatable, rawset -- add accessor methods to the resource dict -- a function to mark objects as to be included -lpdf = lpdf or { } +local lpdf = lpdf -- -- -- helpers -- -- -- diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua index 455ddcf5f..f05dcaa85 100644 --- a/tex/context/base/lpdf-fld.lua +++ b/tex/context/base/lpdf-fld.lua @@ -12,20 +12,24 @@ if not modules then modules = { } end modules ['lpdf-fld'] = { local gmatch, lower, format = string.gmatch, string.lower, string.format local lpegmatch = lpeg.match +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local trace_fields = false trackers.register("widgets.fields", function(v) trace_fields = v end) local report_fields = logs.new("fields") -local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local backends, lpdf = backends, lpdf -local variables = interfaces.variables +local variables = interfaces.variables -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections -local registrations = backends.pdf.registrations +local references = structures.references +local settings_to_array = utilities.parsers.settings_to_array -local registeredsymbol = codeinjections.registeredsymbol +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local registeredsymbol = codeinjections.registeredsymbol local pdfstream = lpdf.stream local pdfdictionary = lpdf.dictionary @@ -38,7 +42,9 @@ local pdftoeight = lpdf.toeight local pdfflushobject = lpdf.flushobject local pdfreserveobject = lpdf.reserveobject -local pdfannotation_node = nodes.pdfannotation +local nodepool = nodes.pool + +local pdfannotation_node = nodepool.pdfannotation local submitoutputformat = 0 -- 0=unknown 1=HTML 2=FDF 3=XML => not yet used, needs to be checked @@ -116,10 +122,9 @@ local function fieldplus(specification) return n end - local function checked(what) if what and what ~= "" then - local set, bug = jobreferences.identify("",what) + local set, bug = references.identify("",what) return not bug and #set > 0 and lpdf.action(set) end end @@ -235,7 +240,7 @@ local function fieldappearances(specification) -- error return end - local v = aux.settings_to_array(values) + local v = settings_to_array(values) local n, r, d if #v == 1 then n, r, d = v[1], v[1], v[1] @@ -257,7 +262,7 @@ local function fieldstates(specification,forceyes,values,default) -- error return end - local v = aux.settings_to_array(values) + local v = settings_to_array(values) local yes, off, yesn, yesr, yesd, offn, offr, offd if #v == 1 then yes, off = v[1], v[1] @@ -268,12 +273,12 @@ local function fieldstates(specification,forceyes,values,default) if not (yesshown and yesvalue) then yesshown = yes, yes end - yes = aux.settings_to_array(yesshown) + yes = settings_to_array(yesshown) local offshown, offvalue = lpegmatch(splitter,off) if not (offshown and offvalue) then offshown = off, off end - off = aux.settings_to_array(offshown) + off = settings_to_array(offshown) if #yes == 1 then yesn, yesr, yesd = yes[1], yes[1], yes[1] elseif #yes == 2 then @@ -317,7 +322,7 @@ local function fieldoptions(specification) local values = specification.values local default = specification.default if values then - local v = aux.settings_to_array(values) + local v = settings_to_array(values) for i=1,#v do local vi = v[i] local shown, value = lpegmatch(splitter,vi) @@ -334,11 +339,11 @@ end local function radiodefault(parent,field,forceyes) local default, values = parent.default, parent.values if not default or default == "" then - values = aux.settings_to_array(values) + values = settings_to_array(values) default = values[1] end local name = field.name - local fieldvalues = aux.settings_to_array(field.values) + local fieldvalues = settings_to_array(field.values) local yes, off = fieldvalues[1], fieldvalues[2] or fieldvalues[1] if not default then return pdfconstant((forceyes and "On") or yes) @@ -391,7 +396,7 @@ end local function predefinesymbols(specification) local values = specification.values if values then - local symbols = aux.settings_to_array(values) + local symbols = settings_to_array(values) for i=1,#symbols do local symbol = symbols[i] local a, b = lpegmatch(splitter,symbol) @@ -406,7 +411,7 @@ function codeinjections.getdefaultfieldvalue(name) local values = f.values local default = f.default if not default or default == "" then - local symbols = aux.settings_to_array(values) + local symbols = settings_to_array(values) local symbol = symbols[1] if symbol then local a, b = lpegmatch(splitter,symbol) -- splits at => @@ -431,7 +436,7 @@ function codeinjections.definefield(specification) elseif kind == "radio" then local values = specification.values if values and values ~= "" then - values = aux.settings_to_array(values) + values = settings_to_array(values) for v=1,#values do radios[values[v]] = { parent = n } end @@ -526,7 +531,12 @@ end -- -function codeinjections.doiffieldset(tag) +function codeinjections.doiffieldgroupelse(name) + local f = fields[name] or radios[name] or clones[name] + commands.testcase(f and f.group) +end + +function codeinjections.doiffieldsetelse(tag) commands.testcase(fieldsets[tag]) end diff --git a/tex/context/base/lpdf-grp.lua b/tex/context/base/lpdf-grp.lua index ad01e4d4f..36362ce69 100644 --- a/tex/context/base/lpdf-grp.lua +++ b/tex/context/base/lpdf-grp.lua @@ -8,6 +8,10 @@ if not modules then modules = { } end modules ['lpdf-grp'] = { local format = string.format +local backends, lpdf = backends, lpdf + +local colors = attributes.colors + local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index 09fb1d096..55da04da4 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -23,7 +23,18 @@ local trace_detail = false trackers.register("backend.detail", function local report_backends = logs.new("backends") -lpdf = lpdf or { } +local backends = backends + +backends.pdf = backends.pdf or { + comment = "backend for directly generating pdf output", + nodeinjections = { }, + codeinjections = { }, + registrations = { }, + tables = { }, +} + +lpdf = lpdf or { } +local lpdf = lpdf local function tosixteen(str) if not str or str == "" then @@ -176,7 +187,7 @@ local tostring_c = function(t) return t[1] end -- already prefixed (h local tostring_z = function() return "null" end local tostring_t = function() return "true" end local tostring_f = function() return "false" end -local tostring_r = function(t) return t[1] .. " 0 R" end +local tostring_r = function(t) local n = t[1] return n and n > 0 and (n .. " 0 R") or "NULL" end local tostring_v = function(t) local s = t[1] @@ -197,7 +208,7 @@ local function value_a(t) return tostring_a(t,true) end -- the call is exper local function value_z() return nil end -- the call is experimental local function value_t(t) return t.value or true end -- the call is experimental local function value_f(t) return t.value or false end -- the call is experimental -local function value_r() return t[1] end -- the call is experimental +local function value_r() return t[1] or 0 end -- the call is experimental -- NULL local function value_v() return t[1] end -- the call is experimental local function add_x(t,k,v) rawset(t,k,tostring(v)) end @@ -481,9 +492,13 @@ local function setpageproperties() pdf.pagesattributes = pagesattributes() end -function lpdf.addtopageresources (k,v) pageresources [k] = v end -function lpdf.addtopageattributes (k,v) pageattributes [k] = v end -function lpdf.addtopagesattributes(k,v) pagesattributes[k] = v end +local function addtopageresources (k,v) pageresources [k] = v end +local function addtopageattributes (k,v) pageattributes [k] = v end +local function addtopagesattributes(k,v) pagesattributes[k] = v end + +lpdf.addtopageresources = addtopageresources +lpdf.addtopageattributes = addtopageattributes +lpdf.addtopagesattributes = addtopagesattributes local function set(where,what,f,when,comment) if type(when) == "string" then @@ -511,14 +526,17 @@ local function run(where,what) end end -function lpdf.registerpagefinalizer(f,when,comment) +local function registerpagefinalizer(f,when,comment) set(pagefinalizers,"page",f,when,comment) end -function lpdf.registerdocumentfinalizer(f,when,comment) +local function registerdocumentfinalizer(f,when,comment) set(documentfinalizers,"document",f,when,comment) end +lpdf.registerpagefinalizer = registerpagefinalizer +lpdf.registerdocumentfinalizer = registerdocumentfinalizer + function lpdf.finalizepage() if not environment.initex then -- resetpageproperties() -- maybe better before @@ -538,7 +556,9 @@ function lpdf.finalizedocument() end end ---~ callbacks.register("finish_pdfoage", lpdf.finalizepage) +backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- will go when we have hook + +--~ callbacks.register("finish_pdfpage", lpdf.finalizepage) callbacks.register("finish_pdffile", lpdf.finalizedocument) -- some minimal tracing, handy for checking the order @@ -573,10 +593,10 @@ local r_colorspaces, d_colorspaces = pdfreserveobject(), pdfdictionary() local local r_patterns, d_patterns = pdfreserveobject(), pdfdictionary() local p_patterns = pdfreference(r_patterns) local r_shades, d_shades = pdfreserveobject(), pdfdictionary() local p_shades = pdfreference(r_shades) -local function checkextgstates () if next(d_extgstates ) then lpdf.addtopageresources("ExtGState", p_extgstates ) end end -local function checkcolorspaces() if next(d_colorspaces) then lpdf.addtopageresources("ColorSpace",p_colorspaces) end end -local function checkpatterns () if next(d_patterns ) then lpdf.addtopageresources("Pattern", p_patterns ) end end -local function checkshades () if next(d_shades ) then lpdf.addtopageresources("Shading", p_shades ) end end +local function checkextgstates () if next(d_extgstates ) then addtopageresources("ExtGState", p_extgstates ) end end +local function checkcolorspaces() if next(d_colorspaces) then addtopageresources("ColorSpace",p_colorspaces) end end +local function checkpatterns () if next(d_patterns ) then addtopageresources("Pattern", p_patterns ) end end +local function checkshades () if next(d_shades ) then addtopageresources("Shading", p_shades ) end end local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end @@ -599,21 +619,21 @@ function lpdf.adddocumentcolorspace(k,v) d_colorspaces[k] = v end function lpdf.adddocumentpattern (k,v) d_patterns [k] = v end function lpdf.adddocumentshade (k,v) d_shades [k] = v end -lpdf.registerdocumentfinalizer(flushextgstates,3,"extended graphic states") -lpdf.registerdocumentfinalizer(flushcolorspaces,3,"color spaces") -lpdf.registerdocumentfinalizer(flushpatterns,3,"patterns") -lpdf.registerdocumentfinalizer(flushshades,3,"shades") +registerdocumentfinalizer(flushextgstates,3,"extended graphic states") +registerdocumentfinalizer(flushcolorspaces,3,"color spaces") +registerdocumentfinalizer(flushpatterns,3,"patterns") +registerdocumentfinalizer(flushshades,3,"shades") -lpdf.registerdocumentfinalizer(flushcatalog,3,"catalog") -lpdf.registerdocumentfinalizer(flushinfo,3,"info") -lpdf.registerdocumentfinalizer(flushnames,3,"names") +registerdocumentfinalizer(flushcatalog,3,"catalog") +registerdocumentfinalizer(flushinfo,3,"info") +registerdocumentfinalizer(flushnames,3,"names") -lpdf.registerpagefinalizer(checkextgstates,3,"extended graphic states") -lpdf.registerpagefinalizer(checkcolorspaces,3,"color spaces") -lpdf.registerpagefinalizer(checkpatterns,3,"patterns") -lpdf.registerpagefinalizer(checkshades,3,"shades") +registerpagefinalizer(checkextgstates,3,"extended graphic states") +registerpagefinalizer(checkcolorspaces,3,"color spaces") +registerpagefinalizer(checkpatterns,3,"patterns") +registerpagefinalizer(checkshades,3,"shades") --- in strc-bkm: lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) +-- in strc-bkm: lpdf.registerdocumentfinalizer(function() structures.bookmarks.place() end,1) function lpdf.rotationcm(a) local s, c = sind(a), cosd(a) @@ -693,14 +713,3 @@ end -- lpdf.addtoinfo("ConTeXt.Time", os.date("%Y.%m.%d %H:%M")) -- :%S -- lpdf.addtoinfo("ConTeXt.Jobname", tex.jobname) -- lpdf.addtoinfo("ConTeXt.Url", "www.pragma-ade.com") - --- saves definitions later on - -backends = backends or { } -backends.pdf = backends.pdf or { - comment = "backend for directly generating pdf output", - nodeinjections = { }, - codeinjections = { }, - registrations = { }, - helpers = { }, -} diff --git a/tex/context/base/lpdf-ini.mkiv b/tex/context/base/lpdf-ini.mkiv deleted file mode 100644 index 64ce6eb43..000000000 --- a/tex/context/base/lpdf-ini.mkiv +++ /dev/null @@ -1,272 +0,0 @@ -%D \module -%D [ file=lpdf-ini, -%D version=2009.04.15, -%D title=\CONTEXT\ Backend Macros, -%D subtitle=PDF, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Backend Macros / PDF} - -\registerctxluafile{lpdf-ini}{1.001} -\registerctxluafile{lpdf-xmp}{1.001} -\registerctxluafile{lpdf-nod}{1.001} -%registerctxluafile{lpdf-col}{1.001} % will be loaded later -\registerctxluafile{lpdf-mis}{1.001} -\registerctxluafile{lpdf-ano}{1.001} -\registerctxluafile{lpdf-ren}{1.001} -\registerctxluafile{lpdf-grp}{1.001} -\registerctxluafile{lpdf-wid}{1.001} -\registerctxluafile{lpdf-fld}{1.001} -\registerctxluafile{lpdf-u3d}{1.001} -\registerctxluafile{lpdf-swf}{1.001} -\registerctxluafile{lpdf-tag}{1.001} - -\unprotect - -% for the moment here - -%D \macros -%D {doovalbox} -%D -%D Drawing frames with round corners is inherited from the -%D main module. -%D -%D For drawing ovals we use quite raw \PDF\ code. The next -%D implementation does not differ that much from the one -%D implemented in the \POSTSCRIPT\ driver. This code is -%D somewhat obsolete as we now have metapost embedded. - -\def\doPDFovalcalc#1#2#3% - {\PointsToBigPoints{\dimexpr#1+#2\relax}#3} - -\def\doovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox - {\forcecolorhack - \bgroup - \dimen0=#4\divide\dimen0 \plustwo - \doPDFovalcalc{0pt}{+\dimen0}\xmin - \doPDFovalcalc{#1}{-\dimen0}\xmax - \doPDFovalcalc{#2}{-\dimen0}\ymax - \doPDFovalcalc{-#3}{+\dimen0}\ymin - \advance\dimen0 by #5% - \doPDFovalcalc{0pt}{+\dimen0}\xxmin - \doPDFovalcalc{#1}{-\dimen0}\xxmax - \doPDFovalcalc{#2}{-\dimen0}\yymax - \doPDFovalcalc{-#3}{+\dimen0}\yymin - \doPDFovalcalc{#4}{\zeropoint}\stroke - \doPDFovalcalc{#5}{\zeropoint}\radius - \edef\dostroke{#6}% - \edef\dofill{#7}% - \edef\mode{\number#8 \space}% - % no \ifcase, else \relax in pdfcode - \setbox\scratchbox\hbox - {\ifnum\dostroke\dofill>\zerocount - \pdfliteral - {q - \stroke\space w - \ifcase\mode - \xxmin\space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 1 - \xxmin\space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 2 - \xxmin\space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or % 3 - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - h - \or % 4 - \xmin \space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xmin \space \ymax \space l - \xmin \space \ymin\space l - h - \or % 5 - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax\space \ymax \space y - \xmin \space \ymax \space l - \xmin \space \ymin \space l - h - \or % 6 - \xmin \space \ymin \space m - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \ymin \space l - h - \or - \xxmin\space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xmin \space \ymax \space l - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - h - \or - \xmin \space \ymin \space m - \xmax \space \ymin \space l - \xmax \space \ymax \space l - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - h - \or % 9 top open - \xmin \space \ymax \space m - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - \xxmax\space \ymin \space l - \xmax \space \ymin \space \xmax \space \yymin\space y - \xmax \space \ymax \space l - \or % 10 right open - \xmax \space \ymax \space m - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \yymin\space l - \xmin \space \ymin \space \xxmin\space \ymin \space y - \xmax\space \ymin \space l - \or % 11 bottom open - \xmax \space \ymin \space m - \xmax \space \yymax\space l - \xmax \space \ymax \space \xxmax \space \ymax\space y - \xxmin\space \ymax \space l - \xmin \space \ymax \space \xmin \space \yymax\space y - \xmin \space \ymin \space l - \or % 12 left open - \xmin \space \ymax \space m - \xxmax\space \ymax \space l - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space l - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \ymin \space l - \or % 13 - \xmin \space \ymax \space m - \xxmax\space \ymax \space l - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax\space \ymin \space l - \or % 14 - \xmax \space \ymax \space m - \xmax \space \yymin\space l - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \ymin \space l - \or % 15 - \xmax \space \ymin \space m - \xxmin\space \ymin \space l - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \ymax \space l - \or % 16 - \xmin \space \ymin \space m - \xmin \space \yymax\space l - \xmin \space \ymax \space \xxmin\space \ymax \space y - \xmax \space \ymax \space l - \or % 17 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \or % 18 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \or % 19 - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 20 - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 21 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 22 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \or % 23 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 24 - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 25 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 26 - \xmax \space \yymin\space m - \xmax \space \ymin \space \xxmax\space \ymin \space y - \xmin \space \yymax\space m - \xmin \space \ymax \space \xxmin\space \ymax \space y - \or % 27 - \xxmax\space \ymax \space m - \xmax \space \ymax \space \xmax \space \yymax\space y - \xxmin\space \ymin \space m - \xmin \space \ymin \space \xmin \space \yymin\space y - \or % 28 - \fi - \ifnum\mode>8 - S - \else - \ifnum\dostroke=\plusone S \fi - \ifnum\dofill =\plusone f \fi - \fi - Q}% - \fi}% - \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox - \egroup} - -\unexpanded\def\pdfactualtext#1#2% - {\pdfliteral direct{/Span <</ActualText \ctxlua{tex.write(lpdf.tosixteen("#2"))} >> BDC}% - #1% - \pdfliteral direct{EMC}} - -% \starttext -% text \pdfactualtext{Meier}{Müller} text -% \stoptext - -\protect \endinput diff --git a/tex/context/base/lpdf-mis.lua b/tex/context/base/lpdf-mis.lua index 0d9061daa..bdc9147a7 100644 --- a/tex/context/base/lpdf-mis.lua +++ b/tex/context/base/lpdf-mis.lua @@ -20,13 +20,17 @@ local format = string.format local texsprint, texset = tex.sprint, tex.set local ctxcatcodes = tex.ctxcatcodes +local backends, lpdf, nodes = backends, lpdf, nodes + local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations local copy_node = node.copy -local pdfliteral, register = nodes.pdfliteral, nodes.register +local nodepool = nodes.pool + +local pdfliteral, register = nodepool.pdfliteral, nodepool.register local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -180,7 +184,7 @@ function codeinjections.setupidentity(specification) end local function flushjavascripts() - local t = javascripts.flushpreambles() + local t = interactions.javascripts.flushpreambles() if #t > 0 then local a = pdfarray() local pdf_javascript = pdfconstant("JavaScript") @@ -306,26 +310,30 @@ local map = { } local function featurecreep() - local pages, lastconversion, list = jobpages.tobesaved, nil, pdfarray() - local getstructureset = structure.sets.get + local pages, lastconversion, list = structures.pages.tobesaved, nil, pdfarray() + local getstructureset = structures.sets.get for i=1,#pages do local p = pages[i] - local numberdata = p.numberdata - if numberdata then - local conversionset = numberdata.conversionset - if conversionset then - local conversion = getstructureset("structure:conversions",p.block,conversionset,1,"numbers") - if conversion ~= lastconversion then - lastconversion = conversion - list[#list+1] = i - 1 -- pdf starts numbering at 0 - list[#list+1] = pdfdictionary { S = pdfconstant(map[conversion] or map.numbers) } + if not p then + return -- fatal error + else + local numberdata = p.numberdata + if numberdata then + local conversionset = numberdata.conversionset + if conversionset then + local conversion = getstructureset("structure:conversions",p.block,conversionset,1,"numbers") + if conversion ~= lastconversion then + lastconversion = conversion + list[#list+1] = i - 1 -- pdf starts numbering at 0 + list[#list+1] = pdfdictionary { S = pdfconstant(map[conversion] or map.numbers) } + end end end - end - if not lastconversion then - lastconversion = "numbers" - list[#list+1] = i - 1 -- pdf starts numbering at 0 - list[#list+1] = pdfdictionary { S = pdfconstant(map.numbers) } + if not lastconversion then + lastconversion = "numbers" + list[#list+1] = i - 1 -- pdf starts numbering at 0 + list[#list+1] = pdfdictionary { S = pdfconstant(map.numbers) } + end end end lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list }) diff --git a/tex/context/base/lpdf-nod.lua b/tex/context/base/lpdf-nod.lua index 0ae900123..e2da39889 100644 --- a/tex/context/base/lpdf-nod.lua +++ b/tex/context/base/lpdf-nod.lua @@ -8,9 +8,13 @@ if not modules then modules = { } end modules ['lpdf-nod'] = { local copy_node, new_node = node.copy, node.new -local pdfliteral = nodes.register(new_node("whatsit", 8)) pdfliteral.mode = 1 -local pdfdest = nodes.register(new_node("whatsit",19)) pdfdest.named_id = 1 -- xyz_zoom untouched -local pdfannot = nodes.register(new_node("whatsit",15)) +local nodepool = nodes.pool + +local register = nodepool.register + +local pdfliteral = register(new_node("whatsit", 8)) pdfliteral.mode = 1 +local pdfdest = register(new_node("whatsit",19)) pdfdest.named_id = 1 -- xyz_zoom untouched +local pdfannot = register(new_node("whatsit",15)) local variables = interfaces.variables @@ -25,13 +29,13 @@ local views = { -- beware, we do support the pdf keys but this is *not* official fitr = 7, } -function nodes.pdfliteral(str) +function nodepool.pdfliteral(str) local t = copy_node(pdfliteral) t.data = str return t end -function nodes.pdfannotation(w,h,d,data,n) +function nodepool.pdfannotation(w,h,d,data,n) local t = copy_node(pdfannot) if w and w ~= 0 then t.width = w end if h and h ~= 0 then t.height = h end @@ -41,7 +45,7 @@ function nodes.pdfannotation(w,h,d,data,n) return t end -function nodes.pdfdestination(w,h,d,name,view,n) +function nodepool.pdfdestination(w,h,d,name,view,n) local t = copy_node(pdfdest) if w and w ~= 0 then t.width = w end if h and h ~= 0 then t.height = h end diff --git a/tex/context/base/lpdf-pdx.lua b/tex/context/base/lpdf-pdx.lua index dbf8eadf2..34461c43d 100644 --- a/tex/context/base/lpdf-pdx.lua +++ b/tex/context/base/lpdf-pdx.lua @@ -13,8 +13,13 @@ local trace_format = false trackers.register("backend.format", function(v) trac local report_backends = logs.new("backends") -local codeinjections = backends.codeinjections -- normally it is registered +local backends, lpdf = backends, lpdf + +local codeinjections = backends.pdf.codeinjections -- normally it is registered local variables = interfaces.variables +local viewerlayers = attributes.viewerlayers +local colors = attributes.colors +local transparencies = attributes.transparencies local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -29,6 +34,7 @@ local addtoinfo, injectxmpinfo, insertxmpinfo = lpdf.addtoinfo, lpdf.injectxmpin local lower, gmatch, format, find = string.lower, string.gmatch, string.format, string.find local concat, serialize = table.concat, table.serialize +local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash local channels = { gray = 1, @@ -154,6 +160,7 @@ local pdfx = { transparency = true, jbig2_compression = true, jpeg2000_compression = true, + object_compression = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false) insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) @@ -177,7 +184,7 @@ local pdfx = { transparency = true, jbig2_compression = true, jpeg2000_compression = true, - nchannel_colorspace = false, + object_compression = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false) insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) @@ -201,6 +208,7 @@ local pdfx = { transparency = true, jbig2_compression = true, jpeg2000_compression = true, + object_compression = true, inject_metadata = function() -- todo end @@ -223,6 +231,7 @@ local pdfx = { transparency = true, jbig2_compression = true, jpeg2000_compression = true, + object_compression = true, inject_metadata = function() -- todo end @@ -244,6 +253,7 @@ local pdfx = { jbig2_compression = true, jpeg2000_compression = true, nchannel_colorspace = true, + object_compression = true, inject_metadata = function() -- todo end @@ -267,7 +277,7 @@ end local function loadprofile(name,filename) local profile = false - local databases = filename and filename ~= "" and aux.settings_to_array(filename) or filenames + local databases = filename and filename ~= "" and settings_to_array(filename) or filenames for i=1,#databases do local filename = locatefile(databases[i]) if filename and filename ~= "" then @@ -482,7 +492,7 @@ end local function handleiccprofile(message,name,filename,how,options,alwaysinclude) if name and name ~= "" then - local list = aux.settings_to_array(name) + local list = settings_to_array(name) for i=1,#list do local name = list[i] local profile = loadprofile(name,filename) @@ -555,16 +565,25 @@ function codeinjections.setformat(s) local spec = pdfx[lower(format)] if spec then pdfxspecification, pdfxformat = spec, spec.format_name + level = level and tonumber(level) report_backends("setting format to '%s'",pdfxformat) local pdf_version, inject_metadata = spec.pdf_version * 10, spec.inject_metadata local majorversion, minorversion = math.div(pdf_version,10), math.mod(pdf_version,10) - local objectcompression = pdf_version >= 15 - tex.pdfcompresslevel = level and tonumber(level) or tex.pdfobjcompresslevel -- keep default - tex.pdfobjcompresslevel = objectcompression and tex.pdfobjcompresslevel or 0 -- keep default - tex.pdfmajorversion = majorversion - tex.pdfminorversion = minorversion - report_backends("forcing pdf version %s.%s, compression level %s, object compression %sabled", - majorversion,minorversion,tex.pdfcompresslevel,compression and "en" or "dis") + local objectcompression = spec.object_compression and pdf_version >= 15 + local compresslevel = level or tex.pdfcompresslevel -- keep default + local objectcompresslevel = (objectcompression and level or tex.pdfobjcompresslevel) or 0 + tex.pdfcompresslevel, tex.pdfobjcompresslevel = compresslevel, objectcompresslevel + tex.pdfmajorversion, tex.pdfminorversion = majorversion, minorversion + if objectcompression then + report_backends("forcing pdf version %s.%s, compression level %s, object compression level %s", + majorversion,minorversion,compresslevel,objectcompresslevel) + elseif compresslevel > 0 then + report_backends("forcing pdf version %s.%s, compression level %s, object compression disabled", + majorversion,minorversion,compresslevel) + else + report_backends("forcing pdf version %s.%s, compression disabled", + majorversion,minorversion) + end -- -- context.setupcolors { -- not this way -- cmyk = spec.cmyk_colors and variables.yes or variables.no, @@ -594,7 +613,7 @@ function codeinjections.setformat(s) if type(inject_metadata) == "function" then inject_metadata() end - local options = aux.settings_to_hash(option) + local options = settings_to_hash(option) handleiccprofile("color profile",profile,filename,handledefaultprofile,options,true) handleiccprofile("output intent",intent,filename,handleoutputintent,options,false) if trace_format then @@ -606,7 +625,7 @@ function codeinjections.setformat(s) end end function codeinjections.setformat(noname) - report_backends("error, format is already set to '%s', ignoring '%s'",pdfxformat,noname) + report_backends("error, format is already set to '%s', ignoring '%s'",pdfxformat,noname.format) end else report_backends("error, format '%s' is not supported",format) @@ -618,6 +637,16 @@ function codeinjections.getformatoption(key) return pdfxspecification and pdfxspecification[key] end +function codeinjections.supportedformats() + local t = { } + for k, v in table.sortedhash(pdfx) do + if find(k,"pdf") then + t[#t+1] = k + end + end + return t +end + --~ The following is somewhat cleaner but then we need to flag that there are --~ color spaces set so that the page flusher does not optimize the (at that --~ moment) still empty array away. So, next(d_colorspaces) should then become diff --git a/tex/context/base/lpdf-pdx.mkiv b/tex/context/base/lpdf-pdx.mkiv deleted file mode 100644 index cd13ba24c..000000000 --- a/tex/context/base/lpdf-pdx.mkiv +++ /dev/null @@ -1,31 +0,0 @@ -%D \module -%D [ file=lpdf-pdx, -%D version=2010.02.11, -%D title=\CONTEXT\ Backend Macros, -%D subtitle=PDF-X, -%D author=Peter Rolf \& Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] % and peter -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -\writestatus{loading}{ConTeXt Backend Macros / PDF-X} - -\registerctxluafile{lpdf-pdx}{1.001} - -\unprotect - -\appendtoks - \doifsomething{\backendparameter\c!format} - {\ctxlua{backends.codeinjections.setformat { - format = "\backendparameter\c!format", - level = "\backendparameter\c!level", - option = "\backendparameter\c!option", - profile = "\backendparameter\c!profile", - intent = "\backendparameter\c!intent", - }}}% -\to \everysetupbackend - -\protect \endinput diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua index f942ec2c9..8f9bc02e0 100644 --- a/tex/context/base/lpdf-ren.lua +++ b/tex/context/base/lpdf-ren.lua @@ -11,23 +11,21 @@ if not modules then modules = { } end modules ['lpdf-ren'] = { local tostring, tonumber, next = tostring, tonumber, next local format = string.format local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local settings_to_array = utilities.parsers.settings_to_array + +local backends, lpdf = backends, lpdf local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations +local viewerlayers = attributes.viewerlayers -jobreferences = jobreferences or { } ---~ jobreferences.runners = jobreferences.runners or { } ---~ jobreferences.specials = jobreferences.specials or { } ---~ jobreferences.handlers = jobreferences.handlers or { } -jobreferences.executers = jobreferences.executers or { } +local references = structures.references ---~ local runners = jobreferences.runners ---~ local specials = jobreferences.specials ---~ local handlers = jobreferences.handlers -local executers = jobreferences.executers +references.executers = references.executers or { } +local executers = references.executers -local variables = interfaces.variables +local variables = interfaces.variables local pdfconstant = lpdf.constant local pdfdictionary = lpdf.dictionary @@ -181,7 +179,7 @@ lpdf.registerdocumentfinalizer(flushtextlayers,"layers") local function setlayer(what,arguments) -- maybe just a gmatch of even better, earlier in lpeg - arguments = (type(arguments) == "table" and arguments) or aux.settings_to_array(arguments) + arguments = (type(arguments) == "table" and arguments) or settings_to_array(arguments) local state = pdfarray { what } for i=1,#arguments do local p = pdfln[arguments[i]] @@ -263,7 +261,7 @@ function codeinjections.setpagetransition(specification) end local t = n and pagetransitions[n] or pagetransitions[1] if not t then - t = aux.settings_to_array(n) + t = settings_to_array(n) end if t and #t > 0 then local d = pdfdictionary() diff --git a/tex/context/base/lpdf-swf.lua b/tex/context/base/lpdf-swf.lua index 34e72f1ec..fc06c9699 100644 --- a/tex/context/base/lpdf-swf.lua +++ b/tex/context/base/lpdf-swf.lua @@ -11,6 +11,8 @@ if not modules then modules = { } end modules ['lpdf-swf'] = { local format = string.format +local backends, lpdf = backends, lpdf + local pdfconstant = lpdf.constant local pdfboolean = lpdf.boolean local pdfstring = lpdf.string @@ -21,11 +23,14 @@ local pdfnull = lpdf.null local pdfreference = lpdf.reference local pdfimmediateobject = lpdf.immediateobject -function backends.pdf.helpers.insertswf(spec) +local codeinjections = backends.pdf.codeinjections +local nodeinjections = backends.pdf.nodeinjections + +local function insertswf(spec) local width, height, filename = spec.width, spec.height, spec.foundname - local eref = backends.codeinjections.embedfile(filename) + local eref = codeinjections.embedfile(filename) local flash = pdfdictionary { Subtype = pdfconstant("Flash"), @@ -108,3 +113,17 @@ function backends.pdf.helpers.insertswf(spec) return annotation, nil, nil end + +function backends.pdf.nodeinjections.insertswf(spec) + local annot, preview, ref = insertswf { + foundname = spec.foundname, + width = spec.width, + height = spec.height, + -- factor = spec.factor, + -- display = spec.display, + -- controls = spec.controls, + -- label = spec.label, + } + -- texsprint(ctxcatcodes,format("\\pdfannot width %ssp height %ssp {%s}",spec.width,spec.height,annot())) -- brrrr + node.write(pdfannotation(spec.width,spec.height,0,annotation())) +end diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua index c5c480458..48140f53d 100644 --- a/tex/context/base/lpdf-tag.lua +++ b/tex/context/base/lpdf-tag.lua @@ -10,10 +10,17 @@ local format, match, concat = string.format, string.match, table.concat local lpegmatch = lpeg.match local utfchar = utf.char -local trace_tags = false trackers.register("structure.tags", function(v) trace_tags = v end) +local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) local report_tags = logs.new("tags") +local backends, lpdf, nodes = backends, lpdf, nodes + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections + +local tasks = nodes.tasks + local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array local pdfboolean = lpdf.boolean @@ -25,16 +32,15 @@ local pdfflushobject = lpdf.flushobject local pdfreserveobject = lpdf.reserveobject local pdfpagereference = lpdf.pagereference -local new_pdfliteral = nodes.pdfliteral +local nodepool = nodes.pool + +local pdfliteral = nodepool.pdfliteral -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local glyph = nodecodes.glyph -local glue = nodecodes.glue -local disc = nodecodes.disc -local whatsit = nodecodes.whatsit +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph local a_tagged = attributes.private('tagged') local a_image = attributes.private('image') @@ -148,11 +154,11 @@ local mapping = { local usedmapping = { } local usedlabels = { } -function backends.codeinjections.mapping() +function codeinjections.mapping() return mapping -- future versions may provide a copy end -function backends.codeinjections.maptag(original,target) +function codeinjections.maptag(original,target) mapping[original] = target end @@ -277,7 +283,7 @@ local function makecontent(parent,start,stop,slist,id) kids[#kids+1] = d end -- - local bliteral = new_pdfliteral(format("/%s <</MCID %s>>BDC",tag,last)) + local bliteral = pdfliteral(format("/%s <</MCID %s>>BDC",tag,last)) local prev = start.prev if prev then prev.next, bliteral.prev = bliteral, prev @@ -289,7 +295,7 @@ local function makecontent(parent,start,stop,slist,id) report_tags("this can't happen: injection in front of nothing") end -- - local eliteral = new_pdfliteral("EMC") + local eliteral = pdfliteral("EMC") local next = stop.next if next then next.prev, eliteral.next = eliteral, next @@ -308,7 +314,7 @@ local level, last, ranges, range = 0, nil, { }, { } local function collectranges(head,list) for n in traverse_nodes(head) do local id = n.id -- 14: image, 8: literal (mp) - if id == glyph then + if id == glyph_code then local at = has_attribute(n,a_tagged) if not at then range = nil @@ -319,7 +325,7 @@ local function collectranges(head,list) elseif range then range[4] = n -- stop end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then local at = has_attribute(n,a_image) if at then local at = has_attribute(n,a_tagged) @@ -337,7 +343,7 @@ local function collectranges(head,list) end end -function backends.nodeinjections.addtags(head) +function nodeinjections.addtags(head) -- no need to adapt head, as we always operate on lists level, last, ranges, range = 0, nil, { }, { } initializepage() @@ -379,13 +385,13 @@ function backends.nodeinjections.addtags(head) return head, true end -function backends.codeinjections.enabletags(tg,lb) +function codeinjections.enabletags(tg,lb) taglist = tg usedlabels = lb - structure.tags.handler = backends.nodeinjections.addtags - tasks.enableaction("shipouts","structure.tags.handler") - tasks.enableaction("shipouts","nodes.accessibility.handler") - tasks.enableaction("math","noads.add_tags") + structures.tags.handler = nodeinjections.addtags + tasks.enableaction("shipouts","structures.tags.handler") + tasks.enableaction("shipouts","nodes.handlers.accessibility") + tasks.enableaction("math","noads.handlers.tags") if trace_tags then report_tags("enabling structure tags") end diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua index 1bb99dc21..dc0f6f43f 100644 --- a/tex/context/base/lpdf-u3d.lua +++ b/tex/context/base/lpdf-u3d.lua @@ -16,6 +16,10 @@ if not modules then modules = { } end modules ['lpdf-u3d'] = { local format, find = string.format, string.find local cos, sin, sqrt, pi, atan2, abs = math.cos, math.sin, math.sqrt, math.pi, math.atan2, math.abs +local backends, lpdf = backends, lpdf + +local nodeinjections = backends.pdf.nodeinjections + local pdfconstant = lpdf.constant local pdfboolean = lpdf.boolean local pdfnumber = lpdf.number @@ -337,7 +341,7 @@ end local stored_js, stored_3d, stored_pr, streams = { }, { }, { }, { } -function backends.pdf.helpers.insert3d(spec) -- width, height, factor, display, controls, label, foundname +local function insert3d(spec) -- width, height, factor, display, controls, label, foundname local width, height, factor = spec.width, spec.height, spec.factor or number.dimenfactors.bp local display, controls, label, foundname = spec.display, spec.controls, spec.label, spec.foundname @@ -471,3 +475,16 @@ function backends.pdf.helpers.insert3d(spec) -- width, height, factor, display, return annot, nil, nil end end + +function nodeinjections.insertu3d(spec) + local annotation, preview, ref = insert3d { + foundname = spec.foundname, + width = spec.width, + height = spec.height, + factor = spec.factor, + display = spec.display, + controls = spec.controls, + label = spec.label, + } + node.write(pdfannotation(spec.width,spec.height,0,annotation())) +end diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua index 323e3c79d..ccb1ee7f2 100644 --- a/tex/context/base/lpdf-wid.lua +++ b/tex/context/base/lpdf-wid.lua @@ -8,12 +8,15 @@ if not modules then modules = { } end modules ['lpdf-wid'] = { local format, gmatch, gsub, find = string.format, string.gmatch, string.gsub, string.find local texsprint, ctxcatcodes, texbox, texcount = tex.sprint, tex.ctxcatcodes, tex.box, tex.count +local settings_to_array = utilities.parsers.settings_to_array + +local backends, lpdf, nodes = backends, lpdf, nodes local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations -local executers = jobreferences.executers +local executers = structures.references.executers local variables = interfaces.variables local pdfconstant = lpdf.constant @@ -29,7 +32,9 @@ local pdfreserveannotation = lpdf.reserveobject local pdfimmediateobject = lpdf.immediateobject local pdfpagereference = lpdf.pagereference -local pdfannotation_node = nodes.pdfannotation +local nodepool = nodes.pool + +local pdfannotation_node = nodepool.pdfannotation local hpack_node, write_node = node.hpack, node.write @@ -88,7 +93,7 @@ local function analyzesymbol(symbol) elseif symbols[symbol] then return symbols[symbol], nil else - local set = aux.settings_to_array(symbol) + local set = settings_to_array(symbol) local normal, down = set[1], set[2] if normal then normal = codeinjections.registeredsymbol(down or normal) @@ -174,7 +179,7 @@ function codeinjections.embedfile(filename) end function codeinjections.attachfile(specification) - local attachment = interactions.attachment(specification.label) + local attachment = interactions.attachments.attachment(specification.label) if not attachment then -- todo: message return @@ -329,7 +334,7 @@ function codeinjections.insertrenderingwindow(specification) end function codeinjections.processrendering(label) - local specification = interactions.rendering(label) + local specification = interactions.renderings.rendering(label) if specification then if specification.kind == "external" then insertrendering(specification) diff --git a/tex/context/base/lpdf-xmp.lua b/tex/context/base/lpdf-xmp.lua index 79f732be0..294bf99e7 100644 --- a/tex/context/base/lpdf-xmp.lua +++ b/tex/context/base/lpdf-xmp.lua @@ -12,6 +12,8 @@ local xmlfillin = xml.fillin local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp = v end) +local lpdf = lpdf + local pdfdictionary = lpdf.dictionary local pdfconstant = lpdf.constant local pdfreference = lpdf.reference diff --git a/tex/context/base/lpdf-xmp.xml b/tex/context/base/lpdf-xmp.xml index 2947211bd..75657db69 100644 --- a/tex/context/base/lpdf-xmp.xml +++ b/tex/context/base/lpdf-xmp.xml @@ -1,6 +1,6 @@ <?xml version="1.0"?> -<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04"> +<x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:format>application/pdf</dc:format> diff --git a/tex/context/base/luat-bas.mkiv b/tex/context/base/luat-bas.mkiv index 9b5dcbc5b..d9c857211 100644 --- a/tex/context/base/luat-bas.mkiv +++ b/tex/context/base/luat-bas.mkiv @@ -19,14 +19,14 @@ \registerctxluafile{l-number} {1.001} \registerctxluafile{l-math} {1.001} \registerctxluafile{l-table} {1.001} -\registerctxluafile{l-aux} {1.001} +%registerctxluafile{l-aux} {1.001} \registerctxluafile{l-io} {1.001} \registerctxluafile{l-os} {1.001} \registerctxluafile{l-file} {1.001} \registerctxluafile{l-md5} {1.001} \registerctxluafile{l-dir} {1.001} \registerctxluafile{l-unicode}{1.001} -\registerctxluafile{l-utils} {1.001} +%registerctxluafile{l-utils} {1.001} \registerctxluafile{l-dimen} {1.001} \registerctxluafile{l-url} {1.001} \registerctxluafile{l-set} {1.001} diff --git a/tex/context/base/luat-bwc.lua b/tex/context/base/luat-bwc.lua index e41f241dc..138c0deba 100644 --- a/tex/context/base/luat-bwc.lua +++ b/tex/context/base/luat-bwc.lua @@ -10,18 +10,19 @@ if not modules then modules = { } end modules ['luat-bwc'] = { local box = tex.box -tex.wd = { } setmetatable(tex.wd, { +local wd = { } setmetatable(wd, { __index = function(t,k) local bk = box[k] return bk and bk.width or 0 end, __newindex = function(t,k,v) local bk = box[k] if bk then bk.width = v end end, } -tex.ht = { } setmetatable(tex.ht, { +local ht = { } setmetatable(ht, { __index = function(t,k) local bk = box[k] return bk and bk.height or 0 end, __newindex = function(t,k,v) local bk = box[k] if bk then bk.height = v end end, } -tex.dp = { } setmetatable(tex.dp, { +local dp = { } setmetatable(dp, { __index = function(t,k) local bk = box[k] return bk and bk.depth or 0 end, __newindex = function(t,k,v) local bk = box[k] if bk then bk.depth = v end end, } +tex.wd, tex.ht, tex.dp = wd, ht, dp diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua index adf90f2d4..9ecf64264 100644 --- a/tex/context/base/luat-cbk.lua +++ b/tex/context/base/luat-cbk.lua @@ -21,7 +21,8 @@ your own code into the <l n='tex'/> engine. Here we implement a few handy auxiliary functions.</p> --ldx]]-- -callbacks = callbacks or { } +callbacks = callbacks or { } +local callbacks = callbacks --[[ldx-- <p>When you (temporarily) want to install a callback function, and after a @@ -52,11 +53,11 @@ local delayed = table.tohash { } -if not callback.original_register_callback then +if not callback.original_register then - callback.original_register_callback = register_callback + callback.original_register = register_callback - local original_register_callback = register_callback + local original_register = register_callback if trace_calls then @@ -73,10 +74,10 @@ if not callback.original_register_callback then list[name] = list[name] + 1 return functions[name](...) end - return original_register_callback(name,cnuf) + return original_register(name,cnuf) end else - return original_register_callback(name,func) + return original_register(name,func) end end @@ -272,9 +273,13 @@ restart the collector. Okay, experimental code has been removed, because messing aroudn with the gc is too unpredictable.</p> --ldx]]-- -garbagecollector = garbagecollector or { } +-- For the moment we keep this here and not in util-gbc.lua or so. -garbagecollector.enabled = false +utilities = utilities or { } +utilities.garbagecollector = utilities.garbagecollector or { } +local garbagecollector = utilities.garbagecollector + +garbagecollector.enabled = false -- could become a directive garbagecollector.criterium = 4*1024*1024 -- Lua allocates up to 12 times the amount of memory needed for diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua index 8be5dc7c3..8d9c33739 100644 --- a/tex/context/base/luat-cnf.lua +++ b/tex/context/base/luat-cnf.lua @@ -6,12 +6,14 @@ if not modules then modules = { } end modules ['luat-cnf'] = { license = "see context related readme files" } +local type, next, tostring, tonumber = type, next, tostring, tonumber local format, concat, find = string.format, table.concat, string.find texconfig.kpse_init = false texconfig.shell_escape = 't' -luatex = luatex or { } +luatex = luatex or { } +local luatex = luatex luatex.variablenames = { 'buf_size', -- 3000 @@ -51,6 +53,7 @@ if not luatex.variables_set then end local stub = [[ + -- checking storage = storage or { } @@ -69,6 +72,56 @@ luatex.starttime = os.gettimeofday() function texconfig.init() + -- development + + local builtin, globals = { }, { } + + libraries = { -- we set it her as we want libraries also 'indexed' + basiclua = { + "string", "table", "coroutine", "debug", "file", "io", "lpeg", "math", "os", "package", + }, + basictex = { -- noad + "callback", "font", "img", "lang", "lua", "node", "pdf", "status", "tex", "texconfig", "texio", "token", + }, + extralua = { + "gzip", "zip", "zlib", "lfs", "ltn12", "mime", "socket", "md5", "profiler", "unicode", "utf", + }, + extratex = { + "epdf", "fontloader", "kpse", "mplib", + }, + obsolete = { + "fontforge", -- can be filled by luat-log + }, + builtin = builtin, -- to be filled + globals = globals, -- to be filled + } + + for k, v in next, _G do + globals[k] = tostring(v) + end + + local function collect(t) + local lib = { } + for k, v in next, t do + local keys = { } + local gv = _G[v] + if type(gv) == "table" then + for k, v in next, gv do + keys[k] = tostring(v) -- true -- by tostring we cannot call overloades functions (security) + end + end + lib[v] = keys + builtin[v] = keys + end + return lib + end + + libraries.basiclua = collect(libraries.basiclua) + libraries.basictex = collect(libraries.basictex) + libraries.extralua = collect(libraries.extralua) + libraries.extratex = collect(libraries.extratex) + libraries.obsolete = collect(libraries.obsolete) + -- shortcut and helper local function init(start) diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua index 8d61c269a..60a0b616f 100644 --- a/tex/context/base/luat-cod.lua +++ b/tex/context/base/luat-cod.lua @@ -8,6 +8,8 @@ if not modules then modules = { } end modules ['luat-cod'] = { local match, gsub, find = string.match, string.gsub, string.find +local texconfig, lua = texconfig, lua + -- some basic housekeeping texconfig.kpse_init = false @@ -52,7 +54,7 @@ end local finalizers = { } function lua.registerfinalizer(f,comment) - if type(f) == "function"then + if type(f) == "function" then finalizers[#finalizers+1] = { action = f, comment = comment } end end @@ -69,12 +71,13 @@ end -- A first start with environments. This will be overloaded later. +environment = environment or { } +local environment = environment + local sourcefile = arg and arg[1] or "" local sourcepath = find(sourcefile,"/") and gsub(sourcefile,"/[^/]+$","") or "" local targetpath = "." -environment = environment or { } - -- delayed (via metatable): -- -- environment.jobname = tex.jobname @@ -114,20 +117,22 @@ end -- a kpse error when disabled. Thi sis en angine issue that will -- be sorted out in due time. +local isfile = lfs.isfile + local function source_file(name) local fullname = sourcepath .. "/" .. name - if lfs.isfile(fullname) then + if isfile(fullname) then return fullname end fullname = fullname .. ".tex" - if lfs.isfile(fullname) then + if isfile(fullname) then return fullname end - if lfs.isfile(name) then + if isfile(name) then return name end name = name .. ".tex" - if lfs.isfile(name) then + if isfile(name) then return name end return nil diff --git a/tex/context/base/luat-dum.lua b/tex/context/base/luat-dum.lua index 680c1ba1e..614c7d8f8 100644 --- a/tex/context/base/luat-dum.lua +++ b/tex/context/base/luat-dum.lua @@ -37,12 +37,6 @@ logs = { report = dummyfunction, simple = dummyfunction, } -tasks = { -- no longer needed - new = dummyfunction, - actions = dummyfunction, - appendaction = dummyfunction, - prependaction = dummyfunction, -} callbacks = { register = function(n,f) return callback.register(n,f) end, } diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua index 9463eff55..975950118 100644 --- a/tex/context/base/luat-env.lua +++ b/tex/context/base/luat-env.lua @@ -18,6 +18,7 @@ local report_resolvers = logs.new("resolvers") local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find local unquote, quote = string.unquote, string.quote +local concat = table.concat -- precautions @@ -42,6 +43,8 @@ end -- environment environment = environment or { } +local environment = environment + environment.arguments = { } environment.files = { } environment.sortedflags = nil @@ -164,7 +167,7 @@ function environment.reconstruct_commandline(arg,noquote) result[#result+1] = a end end - return table.join(result," ") + return concat(result," ") else return "" end diff --git a/tex/context/base/luat-exe.lua b/tex/context/base/luat-exe.lua index 9aa5c78d0..e7f319e9c 100644 --- a/tex/context/base/luat-exe.lua +++ b/tex/context/base/luat-exe.lua @@ -6,28 +6,30 @@ if not modules then modules = { } end modules ['luat-exe'] = { license = "see context related readme files" } -local match, find = string.match, string.find +-- this module needs checking (very old and never really used, not even enabled) + +local match, find, gmatch = string.match, string.find, string.gmatch local concat = table.concat -local report_executer = logs.new("executer") +local report_executers = logs.new("executers") -if not executer then executer = { } end +resolvers.executers = resolver.executers or { } +local executers = resolvers.executers -executer.permitted = { } -executer.execute = os.execute +local permitted = { } +local osexecute = os.execute +local execute = osexecute -function executer.register(...) - local ep = executer.permitted +local function register(...) local t = { ... } for k=1,#t do local v = t[k] - ep[#ep+1] = (v == "*" and ".*") or v + permitted[#permitted+1] = (v == "*" and ".*") or v end end -function executer.finalize() -- todo: os.exec, todo: report ipv print - local execute = os.execute - function executer.execute(...) +local function finalize() -- todo: os.exec, todo: report ipv print + execute = function execute(...) -- todo: make more clever first split local t, name, arguments = { ... }, "", "" local one = t[1] @@ -43,48 +45,53 @@ function executer.finalize() -- todo: os.exec, todo: report ipv print else name, arguments = one, concat(t," ",2,#t) end - local permitted = executer.permitted for k=1,#permitted do local v = permitted[k] if find(name,v) then - execute(name .. " " .. arguments) + osexecute(name .. " " .. arguments) -- print("executed: " .. name .. " " .. arguments) else - report_executer("not permitted: %s %s",name,arguments) + report_executers("not permitted: %s %s",name,arguments) end end end - function executer.finalize() - report_executer("already finalized") + finalize = function() + report_executers("already finalized") + end + register = function() + report_executers("already finalized, no registration permitted") end - executer.register = executer.finalize - os.execute = executer.execute + os.execute = execute end ---~ executer.register('.*') ---~ executer.register('*') ---~ executer.register('dir','ls') ---~ executer.register('dir') - ---~ executer.finalize() ---~ executer.execute('dir',"*.tex") ---~ executer.execute("dir *.tex") ---~ executer.execute("ls *.tex") ---~ os.execute('ls') +executers.finalize = function(...) finalize(...) end +executers.register = function(...) register(...) end +executers.execute = function(...) execute (...) end -function executer.check() +function executers.check() local mode = resolvers.variable("command_mode") local list = resolvers.variable("command_list") if mode == "none" then - executer.finalize() + finalize() elseif mode == "list" and list ~= "" then - for s in string.gmatch("[^%s,]",list) do - executer.register(s) + for s in gmatch("[^%s,]",list) do + register(s) end - executer.finalize() + finalize() else -- all end end ---~ executer.check() +--~ resolvers.executers.register('.*') +--~ resolvers.executers.register('*') +--~ resolvers.executers.register('dir','ls') +--~ resolvers.executers.register('dir') + +--~ resolvers.executers.finalize() +--~ resolvers.executers.execute('dir',"*.tex") +--~ resolvers.executers.execute("dir *.tex") +--~ resolvers.executers.execute("ls *.tex") +--~ os.execute('ls') + +--~ resolvers.executers.check() diff --git a/tex/context/base/luat-fio.lua b/tex/context/base/luat-fio.lua index 090850331..db27e480d 100644 --- a/tex/context/base/luat-fio.lua +++ b/tex/context/base/luat-fio.lua @@ -24,54 +24,58 @@ if not resolvers.instance then resolvers.instance.engine = 'luatex' resolvers.instance.validfile = resolvers.validctxfile ---~ trackers.enable("resolvers.*") + -- trackers.enable("resolvers.*") resolvers.load() ---~ trackers.disable("resolvers.*") + -- trackers.disable("resolvers.*") + + local findbinfile, loadbinfile = resolvers.findbinfile, resolvers.loadbinfile if callback then - callbacks.register('find_read_file' , function(id,name) return resolvers.findtexfile(name) end, true) - callbacks.register('open_read_file' , function( name) return resolvers.opentexfile(name) end, true) - - callbacks.register('find_data_file' , function(name) return resolvers.findbinfile(name,"tex") end, true) - callbacks.register('find_enc_file' , function(name) return resolvers.findbinfile(name,"enc") end, true) - callbacks.register('find_font_file' , function(name) return resolvers.findbinfile(name,"tfm") end, true) - callbacks.register('find_format_file' , function(name) return resolvers.findbinfile(name,"fmt") end, true) - callbacks.register('find_image_file' , function(name) return resolvers.findbinfile(name,"tex") end, true) - callbacks.register('find_map_file' , function(name) return resolvers.findbinfile(name,"map") end, true) - callbacks.register('find_ocp_file' , function(name) return resolvers.findbinfile(name,"ocp") end, true) - callbacks.register('find_opentype_file' , function(name) return resolvers.findbinfile(name,"otf") end, true) - callbacks.register('find_output_file' , function(name) return name end, true) - callbacks.register('find_pk_file' , function(name) return resolvers.findbinfile(name,"pk") end, true) - callbacks.register('find_sfd_file' , function(name) return resolvers.findbinfile(name,"sfd") end, true) - callbacks.register('find_truetype_file' , function(name) return resolvers.findbinfile(name,"ttf") end, true) - callbacks.register('find_type1_file' , function(name) return resolvers.findbinfile(name,"pfb") end, true) - callbacks.register('find_vf_file' , function(name) return resolvers.findbinfile(name,"vf") end, true) - - callbacks.register('read_data_file' , function(file) return resolvers.loadbinfile(file,"tex") end, true) - callbacks.register('read_enc_file' , function(file) return resolvers.loadbinfile(file,"enc") end, true) - callbacks.register('read_font_file' , function(file) return resolvers.loadbinfile(file,"tfm") end, true) + local register = callbacks.register + + register('find_read_file' , function(id,name) return resolvers.findtexfile(name) end, true) + register('open_read_file' , function( name) return resolvers.opentexfile(name) end, true) + + register('find_data_file' , function(name) return findbinfile(name,"tex") end, true) + register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true) + register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true) + register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true) + register('find_image_file' , function(name) return findbinfile(name,"tex") end, true) + register('find_map_file' , function(name) return findbinfile(name,"map") end, true) + register('find_ocp_file' , function(name) return findbinfile(name,"ocp") end, true) + register('find_opentype_file' , function(name) return findbinfile(name,"otf") end, true) + register('find_output_file' , function(name) return name end, true) + register('find_pk_file' , function(name) return findbinfile(name,"pk") end, true) + register('find_sfd_file' , function(name) return findbinfile(name,"sfd") end, true) + register('find_truetype_file' , function(name) return findbinfile(name,"ttf") end, true) + register('find_type1_file' , function(name) return findbinfile(name,"pfb") end, true) + register('find_vf_file' , function(name) return findbinfile(name,"vf") end, true) + + register('read_data_file' , function(file) return loadbinfile(file,"tex") end, true) + register('read_enc_file' , function(file) return loadbinfile(file,"enc") end, true) + register('read_font_file' , function(file) return loadbinfile(file,"tfm") end, true) -- format -- image - callbacks.register('read_map_file' , function(file) return resolvers.loadbinfile(file,"map") end, true) - callbacks.register('read_ocp_file' , function(file) return resolvers.loadbinfile(file,"ocp") end, true) + register('read_map_file' , function(file) return loadbinfile(file,"map") end, true) + register('read_ocp_file' , function(file) return loadbinfile(file,"ocp") end, true) -- output - callbacks.register('read_pk_file' , function(file) return resolvers.loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk - callbacks.register('read_sfd_file' , function(file) return resolvers.loadbinfile(file,"sfd") end, true) - callbacks.register('read_vf_file' , function(file) return resolvers.loadbinfile(file,"vf" ) end, true) + register('read_pk_file' , function(file) return loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk + register('read_sfd_file' , function(file) return loadbinfile(file,"sfd") end, true) + register('read_vf_file' , function(file) return loadbinfile(file,"vf" ) end, true) - callbacks.register('find_font_file' , function(name) return resolvers.findbinfile(name,"ofm") end, true) - callbacks.register('find_vf_file' , function(name) return resolvers.findbinfile(name,"ovf") end, true) + register('find_font_file' , function(name) return findbinfile(name,"ofm") end, true) + register('find_vf_file' , function(name) return findbinfile(name,"ovf") end, true) - callbacks.register('read_font_file' , function(file) return resolvers.loadbinfile(file,"ofm") end, true) - callbacks.register('read_vf_file' , function(file) return resolvers.loadbinfile(file,"ovf") end, true) + register('read_font_file' , function(file) return loadbinfile(file,"ofm") end, true) + register('read_vf_file' , function(file) return loadbinfile(file,"ovf") end, true) - -- callbacks.register('read_opentype_file' , function(file) return resolvers.loadbinfile(file,"otf") end, true) - -- callbacks.register('read_truetype_file' , function(file) return resolvers.loadbinfile(file,"ttf") end, true) - -- callbacks.register('read_type1_file' , function(file) return resolvers.loadbinfile(file,"pfb") end, true) + -- register('read_opentype_file' , function(file) return loadbinfile(file,"otf") end, true) + -- register('read_truetype_file' , function(file) return loadbinfile(file,"ttf") end, true) + -- register('read_type1_file' , function(file) return loadbinfile(file,"pfb") end, true) - callbacks.register('find_write_file' , function(id,name) return name end, true) - callbacks.register('find_format_file' , function(name) return name end, true) + register('find_write_file' , function(id,name) return name end, true) + register('find_format_file' , function(name) return name end, true) end diff --git a/tex/context/base/luat-fmt.lua b/tex/context/base/luat-fmt.lua index 07a7a1490..14727d894 100644 --- a/tex/context/base/luat-fmt.lua +++ b/tex/context/base/luat-fmt.lua @@ -67,10 +67,10 @@ function environment.make_format(name) local lucstubname = file.addsuffix(texbasename,"luc") -- pack libraries in stub logs.simple("creating initialization file: %s",luastubname) - utils.merger.selfcreate(usedlualibs,specificationpath,luastubname) + utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname) -- compile stub file (does not save that much as we don't use this stub at startup any more) local strip = resolvers.boolean_variable("LUACSTRIP", true) - if utils.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then + if utilities.lua.compile(luastubname,lucstubname,false,strip) and lfs.isfile(lucstubname) then logs.simple("using compiled initialization file: %s",lucstubname) usedluastub = lucstubname else diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv index 3018d32e2..366578efb 100644 --- a/tex/context/base/luat-lib.mkiv +++ b/tex/context/base/luat-lib.mkiv @@ -13,11 +13,19 @@ \writestatus{loading}{ConTeXt Lua Macros / Libraries} +\registerctxluafile{util-pck}{1.001} +\registerctxluafile{util-seq}{1.001} +%registerctxluafile{util-mrg}{1.001} % not needed in context itself, only mtxrun +\registerctxluafile{util-lua}{1.001} +\registerctxluafile{util-prs}{1.001} +\registerctxluafile{util-tab}{1.001} +\registerctxluafile{util-fmt}{1.001} +\registerctxluafile{util-deb}{1.001} % could also be done in trac-deb.mkiv + \registerctxluafile{trac-inf}{1.001} \registerctxluafile{trac-set}{1.001} -\registerctxluafile{trac-tra}{1.001} \registerctxluafile{trac-log}{1.001} -\registerctxluafile{trac-pro}{1.001} +%registerctxluafile{trac-pro}{1.001} \registerctxluafile{data-ini}{1.001} \registerctxluafile{data-exp}{1.001} diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua index f40428d37..00ed54bfd 100644 --- a/tex/context/base/luat-run.lua +++ b/tex/context/base/luat-run.lua @@ -12,7 +12,8 @@ local trace_lua_dump = false trackers .register("system.dump", function(v) tra local report_lua_dump = logs.new("lua dump actions") -luatex = luatex or { } +luatex = luatex or { } +local luatex = luatex local start_actions = { } local stop_actions = { } @@ -23,7 +24,7 @@ function luatex.register_stop_actions (...) table.insert(stop_actions, ...) end luatex.show_tex_stat = luatex.show_tex_stat or function() end luatex.show_job_stat = luatex.show_job_stat or statistics.show_job_stat -function luatex.start_run() +local function start_run() if logs.start_run then logs.start_run() end @@ -32,7 +33,7 @@ function luatex.start_run() end end -function luatex.stop_run() +local function stop_run() for _, action in next, stop_actions do action() end @@ -49,36 +50,36 @@ function luatex.stop_run() end end -function luatex.start_shipout_page() +local function start_shipout_page() logs.start_page_number() end -function luatex.stop_shipout_page() +local function stop_shipout_page() logs.stop_page_number() end -function luatex.report_output_pages() +local function report_output_pages() end -function luatex.report_output_log() +local function report_output_log() end -function luatex.pre_dump_actions() +local function pre_dump_actions() lua.finalize(trace_lua_dump and report_lua_dump or nil) end -- this can be done later -callbacks.register('start_run', luatex.start_run, "actions performed at the beginning of a run") -callbacks.register('stop_run', luatex.stop_run, "actions performed at the end of a run") +callbacks.register('start_run', start_run, "actions performed at the beginning of a run") +callbacks.register('stop_run', stop_run, "actions performed at the end of a run") -callbacks.register('report_output_pages', luatex.report_output_pages, "actions performed when reporting pages") -callbacks.register('report_output_log', luatex.report_output_log, "actions performed when reporting log file") +callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages") +callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file") -callbacks.register('start_page_number', luatex.start_shipout_page, "actions performed at the beginning of a shipout") -callbacks.register('stop_page_number', luatex.stop_shipout_page, "actions performed at the end of a shipout") +callbacks.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout") +callbacks.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout") -callbacks.register('process_input_buffer', false, "actions performed when reading data") -callbacks.register('process_output_buffer', false, "actions performed when writing data") +callbacks.register('process_input_buffer', false, "actions performed when reading data") +callbacks.register('process_output_buffer', false, "actions performed when writing data") -callbacks.register("pre_dump", luatex.pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump +callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump diff --git a/tex/context/base/luat-sta.lua b/tex/context/base/luat-sta.lua index a81b0c206..7e87b90fb 100644 --- a/tex/context/base/luat-sta.lua +++ b/tex/context/base/luat-sta.lua @@ -10,9 +10,15 @@ if not modules then modules = { } end modules ['luat-sta'] = { local gmatch, match = string.gmatch, string.match local type = type -states = states or { } -states.data = states.data or { } -states.hash = states.hash or { } +states = states or { } +local states = states + +states.data = states.data or { } +local data = states.data + +states.hash = states.hash or { } +local hash = states.hash + states.tag = states.tag or "" states.filename = states.filename or "" @@ -22,7 +28,7 @@ function states.save(filename,tag) io.savedata(filename, "-- generator : luat-sta.lua\n" .. "-- state tag : " .. tag .. "\n\n" .. - table.serialize(states.data[tag or states.tag] or {},true) + table.serialize(data[tag or states.tag] or {},true) ) end @@ -30,11 +36,11 @@ function states.load(filename,tag) states.filename = filename states.tag = tag or "whatever" states.filename = file.addsuffix(states.filename,'lus') - states.data[states.tag], states.hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } + data[states.tag], hash[states.tag] = (io.exists(filename) and dofile(filename)) or { }, { } end -function states.set_by_tag(tag,key,value,default,persistent) - local d, h = states.data[tag], states.hash[tag] +local function set_by_tag(tag,key,value,default,persistent) + local d, h = data[tag], hash[tag] if d then if type(d) == "table" then local dkey, hkey = key, key @@ -64,17 +70,17 @@ function states.set_by_tag(tag,key,value,default,persistent) d[dkey], h[hkey] = value, value elseif type(d) == "string" then -- weird - states.data[tag], states.hash[tag] = value, value + data[tag], hash[tag] = value, value end end end -function states.get_by_tag(tag,key,default) - local h = states.hash[tag] +local function get_by_tag(tag,key,default) + local h = hash[tag] if h and h[key] then return h[key] else - local d = states.data[tag] + local d = data[tag] if d then for k in gmatch(key,"[^%.]+") do local dk = d[k] @@ -89,15 +95,18 @@ function states.get_by_tag(tag,key,default) end end +states.set_by_tag = set_by_tag +states.get_by_tag = get_by_tag + function states.set(key,value,default,persistent) - states.set_by_tag(states.tag,key,value,default,persistent) + set_by_tag(states.tag,key,value,default,persistent) end function states.get(key,default) - return states.get_by_tag(states.tag,key,default) + return get_by_tag(states.tag,key,default) end ---~ states.data.update = { +--~ data.update = { --~ ["version"] = { --~ ["major"] = 0, --~ ["minor"] = 1, diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua index 98a14e35f..f234a0628 100644 --- a/tex/context/base/luat-sto.lua +++ b/tex/context/base/luat-sto.lua @@ -9,18 +9,21 @@ if not modules then modules = { } end modules ['luat-sto'] = { local type, next = type, next local gmatch, format, write_nl = string.gmatch, string.format, texio.write_nl +local report_storage = logs.new("storage") + storage = storage or { } +local storage = storage + +local data = { } +storage.data = data + +local evaluators = { } +storage.evaluators = evaluators + storage.min = 0 -- 500 storage.max = storage.min - 1 storage.noftables = storage.noftables or 0 storage.nofmodules = storage.nofmodules or 0 -storage.data = { } -storage.evaluators = { } - -local report_storage = logs.new("storage") - -local evaluators = storage.evaluators -- (evaluate,message,names) -local data = storage.data function storage.register(...) data[#data+1] = { ... } diff --git a/tex/context/base/lxml-aux.lua b/tex/context/base/lxml-aux.lua index 523e7c544..4ac3f0359 100644 --- a/tex/context/base/lxml-aux.lua +++ b/tex/context/base/lxml-aux.lua @@ -13,6 +13,8 @@ local trace_manipulations = false trackers.register("lxml.manipulations", funct local report_xml = logs.new("xml") +local xml = xml + local xmlparseapply, xmlconvert, xmlcopy, xmlname = xml.parse_apply, xml.convert, xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert diff --git a/tex/context/base/lxml-ctx.lua b/tex/context/base/lxml-ctx.lua index 765754953..cbd3c6727 100644 --- a/tex/context/base/lxml-ctx.lua +++ b/tex/context/base/lxml-ctx.lua @@ -8,6 +8,8 @@ if not modules then modules = { } end modules ['lxml-ctx'] = { -- is this still used? +local xml = xml + xml.ctx = { } xml.ctx.enhancers = { } diff --git a/tex/context/base/lxml-dir.lua b/tex/context/base/lxml-dir.lua index 617ce3e20..0bc79877b 100644 --- a/tex/context/base/lxml-dir.lua +++ b/tex/context/base/lxml-dir.lua @@ -26,10 +26,9 @@ local xmlparseapply = xml.parse_apply --~ <directive attribute='cdx' value="*" element="cals:table" setup="cdx:cals:table:*"/> --~ </directives> +local lxml = lxml - -lxml.directives = lxml.directives or { } - +lxml.directives = lxml.directives or { } local directives = lxml.directives local data = { diff --git a/tex/context/base/lxml-ent.lua b/tex/context/base/lxml-ent.lua index a58b1d493..d92e48365 100644 --- a/tex/context/base/lxml-ent.lua +++ b/tex/context/base/lxml-ent.lua @@ -26,6 +26,8 @@ local trace_entities = false trackers.register("xml.entities", function(v) trac local report_xml = logs.new("xml") +local xml = xml + xml.entities = xml.entities or { } -- xml.entity_handler == function storage.register("xml/entities",xml.entities,"xml.entities") -- this will move to lxml diff --git a/tex/context/base/lxml-inf.lua b/tex/context/base/lxml-inf.lua index 629c869ec..6862c476b 100644 --- a/tex/context/base/lxml-inf.lua +++ b/tex/context/base/lxml-inf.lua @@ -8,6 +8,9 @@ if not modules then modules = { } end modules ['lxml-inf'] = { -- This file will be loaded runtime by x-pending.tex. + +local xmlwithelements = xml.withelements + local status, stack local function get(e,d) diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv index 0f04d0488..99e9dd7ac 100644 --- a/tex/context/base/lxml-ini.mkiv +++ b/tex/context/base/lxml-ini.mkiv @@ -91,9 +91,6 @@ \def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("any:///#1")}} \def\xmlpos #1{\ctxlua{lxml.pos("#1")}} -%def\xmldoifelse #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",false))}} -%def\xmldoifelsetext #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",true ))}} - % kind of special: \def\xmlstartraw{\ctxlua{lxml.startraw()}} diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua index 983d631e9..2db7a4a23 100644 --- a/tex/context/base/lxml-lpt.lua +++ b/tex/context/base/lxml-lpt.lua @@ -51,6 +51,8 @@ of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We will explain more about its usage in other documents.</p> --ldx]]-- +local xml = xml + local lpathcalls = 0 function xml.lpathcalls () return lpathcalls end local lpathcached = 0 function xml.lpathcached() return lpathcached end diff --git a/tex/context/base/lxml-mis.lua b/tex/context/base/lxml-mis.lua index 9fd4270af..78297b592 100644 --- a/tex/context/base/lxml-mis.lua +++ b/tex/context/base/lxml-mis.lua @@ -11,6 +11,8 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton local format, gsub, match = string.format, string.gsub, string.match local lpegmatch = lpeg.match +local xml = xml + --[[ldx-- <p>The following helper functions best belong to the <t>lxml-ini</t> module. Some are here because we need then in the <t>mk</t> diff --git a/tex/context/base/lxml-sor.lua b/tex/context/base/lxml-sor.lua index e220bfad6..a159fd4e0 100644 --- a/tex/context/base/lxml-sor.lua +++ b/tex/context/base/lxml-sor.lua @@ -10,6 +10,8 @@ local format, concat = string.format, table.concat local lpegmatch = lpeg.match local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local xml, lxml = xml, lxml + lxml.sorters = lxml.sorters or { } if not lxml.splitid then diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua index 49db5eb26..e368764ad 100644 --- a/tex/context/base/lxml-tab.lua +++ b/tex/context/base/lxml-tab.lua @@ -27,6 +27,7 @@ optimize the code.</p> --ldx]]-- xml = xml or { } +local xml = xml --~ local xml = xml diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index 5b116fbf4..6aef2fc24 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -15,6 +15,11 @@ local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match local P, S, C, Cc = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc +local tex, xml = tex, xml + +lxml = lxml or { } +local lxml = lxml + if not tex and not tex.sprint then -- no longer needed tex = { sprint = function(catcodes,...) texio.write(table.concat{...}) end, @@ -45,9 +50,7 @@ local trace_comments = false trackers.register("lxml.comments", function(v) tra local report_lxml = logs.new("lxml") -lxml = lxml or { } -lxml.loaded = lxml.loaded or { } - +lxml.loaded = lxml.loaded or { } local loaded = lxml.loaded -- print(contextdirective("context-mathml-directive function reduction yes ")) @@ -77,7 +80,7 @@ local xmltextcapture = ( space^0 * newline^2 * Cc("") / texprint + -- better ^-2 ? space^0 * newline * space^0 * Cc(" ") / texsprint + content / function(str) return texsprint(notcatcodes,str) end + -- was just texsprint, current catcodes regime is notcatcodes - entity / xml.resolved_entity + entity / xml.resolved_entity )^0 local ctxtextcapture = ( diff --git a/tex/context/base/lxml-xml.lua b/tex/context/base/lxml-xml.lua index 6080e4207..2a6d56800 100644 --- a/tex/context/base/lxml-xml.lua +++ b/tex/context/base/lxml-xml.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } +local xml = xml + local finalizers = xml.finalizers.xml local xmlfilter = xml.filter -- we could inline this one for speed local xmltostring = xml.tostring diff --git a/tex/context/base/m-punk.mkiv b/tex/context/base/m-punk.mkiv index 3ea738003..5b1486c81 100644 --- a/tex/context/base/m-punk.mkiv +++ b/tex/context/base/m-punk.mkiv @@ -176,7 +176,7 @@ fonts.define.methods.install( "punkboldslanted", { { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 }, } ) -typesetting.cases.actions[99] = function(current) +typesetters.cases.actions[99] = function(current) local used = fontdata[current.font].variants if used then local f = math.random(1,#used) diff --git a/tex/context/base/math-dim.lua b/tex/context/base/math-dim.lua index fbaffe4fb..f21575a1d 100644 --- a/tex/context/base/math-dim.lua +++ b/tex/context/base/math-dim.lua @@ -11,8 +11,6 @@ if not modules then modules = { } end modules ['math-dim'] = { local abs, next = math.abs, next -mathematics = mathematics or { } - local defaults = { ['axis']={ ['default']={ "AxisHeight", "axis_height" }, diff --git a/tex/context/base/math-ext.lua b/tex/context/base/math-ext.lua index 32d0263d9..d65f70245 100644 --- a/tex/context/base/math-ext.lua +++ b/tex/context/base/math-ext.lua @@ -8,18 +8,19 @@ if not modules then modules = { } end modules ['math-ext'] = { local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end) -mathematics = mathematics or { } -characters = characters or { } +local mathematics = mathematics +local characters = characters local report_math = logs.new("mathematics") mathematics.extras = mathematics.extras or { } -characters.math = characters.math or { } +local extras = mathematics.extras -local chardata = characters.data -local mathdata = characters.math +characters.math = characters.math or { } +local mathdata = characters.math +local chardata = characters.data -function mathematics.extras.add(unicode,t) +function extras.add(unicode,t) local min, max = mathematics.extrabase, mathematics.privatebase - 1 if unicode >= min and unicode <= max then mathdata[unicode], chardata[unicode] = t, t @@ -28,7 +29,7 @@ function mathematics.extras.add(unicode,t) end end -function mathematics.extras.copy(tfmdata) +function extras.copy(tfmdata) local math_parameters = tfmdata.math_parameters local MathConstants = tfmdata.MathConstants if (math_parameters and next(math_parameters)) or (MathConstants and next(MathConstants)) then @@ -72,11 +73,11 @@ function mathematics.extras.copy(tfmdata) end end -table.insert(fonts.tfm.mathactions,mathematics.extras.copy) +table.insert(fonts.tfm.mathactions,extras.copy) -- 0xFE302 -- 0xFE320 for accents -mathematics.extras.add(0xFE302, { +extras.add(0xFE302, { category="mn", description="WIDE MATHEMATICAL HAT", direction="nsm", @@ -88,7 +89,7 @@ mathematics.extras.add(0xFE302, { nextinsize={ 0x00302, 0x0005E }, } ) -mathematics.extras.add(0xFE303, { +extras.add(0xFE303, { category="mn", cjkwd="a", description="WIDE MATHEMATICAL TILDE", @@ -103,7 +104,7 @@ mathematics.extras.add(0xFE303, { -- 0xFE321 -- 0xFE340 for missing characters -mathematics.extras.add(0xFE321, { +extras.add(0xFE321, { category="sm", description="MATHEMATICAL SHORT BAR", -- direction="on", @@ -113,7 +114,7 @@ mathematics.extras.add(0xFE321, { unicodeslot=0xFE321, } ) -mathematics.extras.add(0xFE322, { +extras.add(0xFE322, { category="sm", description="MATHEMATICAL LEFT HOOK", mathclass="relation", @@ -121,7 +122,7 @@ mathematics.extras.add(0xFE322, { unicodeslot=0xFE322, } ) -mathematics.extras.add(0xFE323, { +extras.add(0xFE323, { category="sm", description="MATHEMATICAL RIGHT HOOK", mathclass="relation", @@ -129,7 +130,7 @@ mathematics.extras.add(0xFE323, { unicodeslot=0xFE323, } ) -mathematics.extras.add(0xFE324, { +extras.add(0xFE324, { category="sm", description="MATHEMATICAL SHORT BAR MIRRORED", -- direction="on", @@ -139,7 +140,7 @@ mathematics.extras.add(0xFE324, { unicodeslot=0xFE324, } ) ---~ mathematics.extras.add(0xFE304, { +--~ extras.add(0xFE304, { --~ category="sm", --~ description="TOP AND BOTTOM PARENTHESES", --~ direction="on", @@ -150,7 +151,7 @@ mathematics.extras.add(0xFE324, { --~ accents={ 0x023DC, 0x023DD }, --~ } ) ---~ mathematics.extras.add(0xFE305, { +--~ extras.add(0xFE305, { --~ category="sm", --~ description="TOP AND BOTTOM BRACES", --~ direction="on", diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua index b5927f998..73a6725bb 100644 --- a/tex/context/base/math-ini.lua +++ b/tex/context/base/math-ini.lua @@ -17,7 +17,8 @@ local trace_defining = false trackers.register("math.defining", function(v) tra local report_math = logs.new("mathematics") -mathematics = mathematics or { } +mathematics = mathematics or { } +local mathematics = mathematics mathematics.extrabase = 0xFE000 -- here we push some virtuals mathematics.privatebase = 0xFF000 -- here we push the ex diff --git a/tex/context/base/math-map.lua b/tex/context/base/math-map.lua index 405133ece..9b1a925cd 100644 --- a/tex/context/base/math-map.lua +++ b/tex/context/base/math-map.lua @@ -28,7 +28,8 @@ local trace_greek = false trackers.register("math.greek", function(v) trace_g local report_math = logs.new("mathematics") -mathematics = mathematics or { } +mathematics = mathematics or { } +local mathematics = mathematics -- we could use one level less and have tf etc be tables directly but the -- following approach permits easier remapping of a-a, A-Z and 0-9 to diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index 19cc94ea7..cb0b7a1e6 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -14,17 +14,27 @@ if not modules then modules = { } end modules ['math-noa'] = { local utf = unicode.utf8 +local format, rep = string.format, string.rep +local utfchar, utfbyte = utf.char, utf.byte + +local fonts, nodes, node, mathematics = fonts, nodes, node, mathematics + local set_attribute = node.set_attribute local has_attribute = node.has_attribute local mlist_to_hlist = node.mlist_to_hlist local font_of_family = node.family_font local fontdata = fonts.identifiers -local nodecodes = nodes.nodecodes -local format, rep = string.format, string.rep -local utfchar, utfbyte = utf.char, utf.byte +noads = noads or { } +local noads = noads -noads = noads or { } +noads.processors = noads.processors or { } +local processors = noads.processors + +noads.handlers = noads.handlers or { } +local handlers = noads.handlers + +local tasks = nodes.tasks local trace_remapping = false trackers.register("math.remapping", function(v) trace_remapping = v end) local trace_processing = false trackers.register("math.processing", function(v) trace_processing = v end) @@ -32,65 +42,26 @@ local trace_analyzing = false trackers.register("math.analyzing", function(v) local report_noads = logs.new("mathematics") --- todo: nodes.noadcodes - -local noad_ord = 0 -local noad_op_displaylimits = 1 -local noad_op_limits = 2 -local noad_op_nolimits = 3 -local noad_bin = 4 -local noad_rel = 5 -local noad_open = 6 -local noad_close = 7 -local noad_punct = 8 -local noad_inner = 9 -local noad_under = 10 -local noad_over = 11 -local noad_vcenter = 12 - --- obsolete: --- --- math_ord = nodecodes.ord") -- attr nucleus sub sup --- math_op = nodecodes.op") -- attr nucleus sub sup subtype --- math_bin = nodecodes.bin") -- attr nucleus sub sup --- math_rel = nodecodes.rel") -- attr nucleus sub sup --- math_punct = nodecodes.punct") -- attr nucleus sub sup ---_ --- math_open = nodecodes.open") -- attr nucleus sub sup --- math_close = nodecodes.close") -- attr nucleus sub sup ---_ --- math_inner = nodecodes.inner") -- attr nucleus sub sup --- math_vcenter = nodecodes.vcenter") -- attr nucleus sub sup --- math_under = nodecodes.under") -- attr nucleus sub sup --- math_over = nodecodes.over") -- attr nucleus sub sup - -local math_noad = nodecodes.noad -- attr nucleus sub sup - -local math_accent = nodecodes.accent -- attr nucleus sub sup accent -local math_radical = nodecodes.radical -- attr nucleus sub sup left degree -local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right - -local math_box = nodecodes.sub_box -- attr list -local math_sub = nodecodes.sub_mlist -- attr list -local math_char = nodecodes.math_char -- attr fam char -local math_text_char = nodecodes.math_text_char -- attr fam char -local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char -local math_style = nodecodes.style -- attr style -local math_choice = nodecodes.choice -- attr display text script scriptscript -local math_fence = nodecodes.fence -- attr subtype - -local simple_noads = table.tohash { - math_noad, -} +local nodecodes = nodes.nodecodes +local noadcodes = nodes.noadcodes -local all_noads = { - math_noad, - math_box, math_sub, - math_char, math_text_char, math_delim, math_style, - math_accent, math_radical, math_fraction, math_choice, math_fence, -} +local noad_ord = noadcodes.ord +local noad_punct = noadcodes.punct + +local math_noad = nodecodes.noad -- attr nucleus sub sup +local math_accent = nodecodes.accent -- attr nucleus sub sup accent +local math_radical = nodecodes.radical -- attr nucleus sub sup left degree +local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right +local math_box = nodecodes.subbox -- attr list +local math_sub = nodecodes.submlist -- attr list +local math_char = nodecodes.mathchar -- attr fam char +local math_textchar = nodecodes.mathtextchar -- attr fam char +local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char +local math_style = nodecodes.style -- attr style +local math_choice = nodecodes.choice -- attr display text script scriptscript +local math_fence = nodecodes.fence -- attr subtype -noads.processors = noads.processors or { } +local left_fence_code = 1 local function process(start,what,n,parent) if n then n = n + 1 else n = 0 end @@ -105,7 +76,7 @@ local function process(start,what,n,parent) if newstart then start = newstart end - elseif id == math_char or id == math_text_char or id == math_delim then + elseif id == math_char or id == math_textchar or id == math_delim then break elseif id == math_style then -- has a next @@ -153,7 +124,7 @@ noads.process = process local mathalphabet = attributes.private("mathalphabet") local mathgreek = attributes.private("mathgreek") -noads.processors.relocate = { } +processors.relocate = { } local function report_remap(tag,id,old,new,extra) report_noads("remapping %s in font %s from U+%04X (%s) to U+%04X (%s)%s",tag,id,old,utfchar(old),new,utfchar(new),extra or "") @@ -189,7 +160,7 @@ local fcs = fonts.color.set --~ end --~ end -noads.processors.relocate[math_char] = function(pointer) +processors.relocate[math_char] = function(pointer) local g = has_attribute(pointer,mathgreek) or 0 local a = has_attribute(pointer,mathalphabet) or 0 if a > 0 or g > 0 then @@ -228,20 +199,20 @@ noads.processors.relocate[math_char] = function(pointer) end end -noads.processors.relocate[math_text_char] = function(pointer) +processors.relocate[math_textchar] = function(pointer) if trace_analyzing then fcs(pointer,"font:init") end end -noads.processors.relocate[math_delim] = function(pointer) +processors.relocate[math_delim] = function(pointer) if trace_analyzing then fcs(pointer,"font:fina") end end -function noads.relocate_characters(head,style,penalties) - process(head,noads.processors.relocate) +function handlers.relocate(head,style,penalties) + process(head,processors.relocate) return true end @@ -257,10 +228,10 @@ end local mathsize = attributes.private("mathsize") -local resize = { } noads.processors.resize = resize +local resize = { } processors.resize = resize resize[math_fence] = function(pointer) - if pointer.subtype == 1 then -- left + if pointer.subtype == left_fence_code then local a = has_attribute(pointer,mathsize) if a and a > 0 then set_attribute(pointer,mathsize,0) @@ -275,7 +246,7 @@ resize[math_fence] = function(pointer) end end -function noads.resize_characters(head,style,penalties) +function handlers.resize(head,style,penalties) process(head,resize) return true end @@ -284,7 +255,7 @@ end local mathpunctuation = attributes.private("mathpunctuation") -local respace = { } noads.processors.respace = respace +local respace = { } processors.respace = respace local chardata = characters.data @@ -337,7 +308,7 @@ respace[math_noad] = function(pointer) end end -function noads.respace_characters(head,style,penalties) +function handlers.respace(head,style,penalties) process(head,respace) return true end @@ -379,7 +350,7 @@ local get_alternate = fonts.otf.get_alternate local mathalternate = attributes.private("mathalternate") -local alternate = { } -- noads.processors.alternate = alternate +local alternate = { } -- processors.alternate = alternate function mathematics.setalternate(fam,tag) local id = font_of_family(fam) @@ -407,14 +378,14 @@ alternate[math_char] = function(pointer) end end -function noads.check_alternates(head,style,penalties) +function handlers.check(head,style,penalties) process(head,alternate) return true end -- the normal builder -function noads.mlist_to_hlist(head,style,penalties) +function builders.kernel.mlist_to_hlist(head,style,penalties) return mlist_to_hlist(head,style,penalties), true end @@ -432,14 +403,14 @@ local actions = tasks.actions("math",2) -- head, style, penalties local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming -function nodes.processors.mlist_to_hlist(head,style,penalties) +function processors.mlist_to_hlist(head,style,penalties) starttiming(noads) local head, done = actions(head,style,penalties) stoptiming(noads) return head, done end -callbacks.register('mlist_to_hlist',nodes.processors.mlist_to_hlist,"preprocessing math list") +callbacks.register('mlist_to_hlist',processors.mlist_to_hlist,"preprocessing math list") -- tracing diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua index 7960c014f..278e3b9cb 100644 --- a/tex/context/base/math-tag.lua +++ b/tex/context/base/math-tag.lua @@ -6,35 +6,40 @@ if not modules then modules = { } end modules ['math-tag'] = { license = "see context related readme files" } -local has_attribute = nodes.has_attribute -local set_attribute = nodes.set_attribute -local set_attributes = nodes.set_attributes -local traverse_nodes = node.traverse +local attributes, nodes = attributes, nodes -local nodecodes = nodes.nodecodes +local has_attribute = nodes.has_attribute +local set_attribute = nodes.set_attribute +local set_attributes = nodes.set_attributes +local traverse_nodes = node.traverse -local math_noad = nodecodes.noad -- attr nucleus sub sup -local math_noad = nodecodes.noad -- attr nucleus sub sup -local math_accent = nodecodes.accent -- attr nucleus sub sup accent -local math_radical = nodecodes.radical -- attr nucleus sub sup left degree -local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right -local math_box = nodecodes.sub_box -- attr list -local math_sub = nodecodes.sub_mlist -- attr list -local math_char = nodecodes.math_char -- attr fam char -local math_text_char = nodecodes.math_text_char -- attr fam char -local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char -local math_style = nodecodes.style -- attr style -local math_choice = nodecodes.choice -- attr display text script scriptscript -local math_fence = nodecodes.fence -- attr subtype +local nodecodes = nodes.nodecodes -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local glyph = nodecodes.glyph +local math_noad_code = nodecodes.noad -- attr nucleus sub sup +local math_accent_code = nodecodes.accent -- attr nucleus sub sup accent +local math_radical_code = nodecodes.radical -- attr nucleus sub sup left degree +local math_fraction_code = nodecodes.fraction -- attr nucleus sub sup left right +local math_box_code = nodecodes.subbox -- attr list +local math_sub_code = nodecodes.submlist -- attr list +local math_char_code = nodecodes.mathchar -- attr fam char +local math_textchar_code = nodecodes.mathtextchar -- attr fam char +local math_delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char +local math_style_code = nodecodes.style -- attr style +local math_choice_code = nodecodes.choice -- attr display text script scriptscript +local math_fence_code = nodecodes.fence -- attr subtype -local a_tagged = attributes.private('tagged') +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph + +local a_tagged = attributes.private('tagged') + +local tags = structures.tags + +local start_tagged = tags.start +local stop_tagged = tags.stop +local taglist = tags.taglist -local start_tagged = structure.tags.start -local stop_tagged = structure.tags.stop local chardata = characters.data local process @@ -67,7 +72,7 @@ end process = function(start) -- we cannot use the processor as we have no finalizers (yet) while start do local id = start.id - if id == math_char then + if id == math_char_code then -- check for code local ch = chardata[start.char] local mc = ch and ch.mathclass @@ -80,22 +85,22 @@ process = function(start) -- we cannot use the processor as we have no finalizer end stop_tagged() break - elseif id == math_text_char then + elseif id == math_textchar_code then -- check for code set_attribute(start,a_tagged,start_tagged("ms")) stop_tagged() break - elseif id == math_delim then + elseif id == math_delim_code then -- check for code set_attribute(start,a_tagged,start_tagged("mo")) stop_tagged() break - elseif id == math_style then + elseif id == math_style_code then -- has a next - elseif id == math_noad then + elseif id == math_noad_code then processsubsup(start) - elseif id == math_box or id == hlist or id == vlist then - -- keep an eye on math_box and see what ends up in there + elseif id == math_box_code or id == hlist_code or id == vlist_code then + -- keep an eye on math_box_code and see what ends up in there local attr = has_attribute(start,a_tagged) local text = start_tagged("mtext") set_attribute(start,a_tagged,text) @@ -110,16 +115,15 @@ process = function(start) -- we cannot use the processor as we have no finalizer -- 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. - local taglist = structure.tags.taglist local tagdata = taglist[attr] local common = #tagdata + 1 local function runner(list) -- quite inefficient local cache = { } -- we can have nested unboxed mess so best local to runner for n in traverse_nodes(list) do local id = n.id - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then runner(n.list) - elseif id == glyph then + elseif id == glyph_code then local aa = has_attribute(n,a_tagged) -- only glyph needed if aa then local ac = cache[aa] @@ -148,14 +152,14 @@ process = function(start) -- we cannot use the processor as we have no finalizer runner(list) end stop_tagged() - elseif id == math_sub then + elseif id == math_sub_code then local list = start.list if list then set_attribute(start,a_tagged,start_tagged("mrow")) process(list) stop_tagged() end - elseif id == math_fraction then + elseif id == math_fraction_code then local num, denom, left, right = start.num, start.denom, start.left, start.right if left then set_attribute(left,a_tagged,start_tagged("mo")) @@ -171,7 +175,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer process(right) stop_tagged() end - elseif id == math_choice then + elseif id == math_choice_code then local display, text, script, scriptscript = start.display, start.text, start.script, start.scriptscript if display then process(display) @@ -185,14 +189,14 @@ process = function(start) -- we cannot use the processor as we have no finalizer if scriptscript then process(scriptscript) end - elseif id == math_fence then + elseif id == math_fence_code then local delim = start.delim if delim then set_attribute(start,a_tagged,start_tagged("mo")) process(delim) stop_tagged() end - elseif id == math_radical then + elseif id == math_radical_code then local left, degree = start.left, start.degree if left then process(left) -- mrow needed ? @@ -207,7 +211,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer processsubsup(start) stop_tagged() end - elseif id == math_accent then + elseif id == math_accent_code then local accent, bot_accent = start.accent, start.bot_accent if bot_accent then if accent then @@ -238,7 +242,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer end end -function noads.add_tags(head,style,penalties) +function noads.handlers.tags(head,style,penalties) set_attribute(head,a_tagged,start_tagged("math")) set_attribute(head,a_tagged,start_tagged("mrow")) process(head) diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua index dccb30c92..71eb6c76e 100644 --- a/tex/context/base/math-vfu.lua +++ b/tex/context/base/math-vfu.lua @@ -18,6 +18,8 @@ local trace_timings = false trackers.register("math.timings", function(v) trace_ local report_virtual = logs.new("virtual math") +local fonts, nodes, mathematics = fonts, nodes, mathematics + fonts.enc.math = fonts.enc.math or { } local shared = { } diff --git a/tex/context/base/meta-fun.lua b/tex/context/base/meta-fun.lua index fef2aa12b..9a6d971ba 100644 --- a/tex/context/base/meta-fun.lua +++ b/tex/context/base/meta-fun.lua @@ -11,10 +11,13 @@ if not modules then modules = { } end modules ['meta-fun'] = { local format, loadstring, type = string.format, loadstring, type local texwrite = tex.write -metafun = metafun or { } +local metapost = metapost + +metapost.metafun = metapost.metafun or { } +local metafun = metapost.metafun function metafun.topath(t,connector) - tex.write("(") + texwrite("(") if #t > 0 then for i=1,#t do if i > 1 then @@ -35,7 +38,7 @@ end function metafun.interpolate(f,b,e,s,c) local done = false - tex.write("(") + texwrite("(") for i=b,e,(e-b)/s do local d = loadstring(format("return function(x) return %s end",f)) if d then diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index c44be4282..3d1d87b1c 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -714,8 +714,6 @@ \def\resetMPenvironment {\ctxlua{metapost.tex.reset()}} -\resetMPenvironment - \def\useMPenvironmentbuffer[#1]% {\ctxlua{metapost.tex.set(buffers.content("#1"))}} diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua index 9a9b13028..0deda627f 100644 --- a/tex/context/base/meta-pdf.lua +++ b/tex/context/base/meta-pdf.lua @@ -17,6 +17,8 @@ local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local report_mptopdf = logs.new("mptopdf") +local mplib, metapost, lpdf = mplib, metapost, lpdf + local pdfrgbcode = lpdf.rgbcode local pdfcmykcode = lpdf.cmykcode local pdfgraycode = lpdf.graycode @@ -24,8 +26,10 @@ local pdfspotcode = lpdf.spotcode local pdftransparencycode = lpdf.transparencycode local pdffinishtransparencycode = lpdf.finishtransparencycode -mptopdf = { } -mptopdf.n = 0 +metapost.mptopdf = metapost.mptopdf or { } +local mptopdf = metapost.mptopdf + +mptopdf.n = 0 local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false @@ -114,7 +118,8 @@ end -- mp interface -mps = mps or { } +metapost.mps = metapost.mps or { } +local mps = metapost.mps or { } function mps.creator(a, b, c) m_version = tonumber(b) diff --git a/tex/context/base/meta-pdf.mkiv b/tex/context/base/meta-pdf.mkiv index fa9627fbe..4d5e5232a 100644 --- a/tex/context/base/meta-pdf.mkiv +++ b/tex/context/base/meta-pdf.mkiv @@ -57,7 +57,7 @@ \forgetall \offinterlineskip \setbox\scratchbox\vbox\bgroup - \ctxlua{mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces + \ctxlua{metapost.mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces \egroup \setbox\scratchbox\hbox\bgroup \hskip-\MPllx\onebasepoint diff --git a/tex/context/base/meta-pdh.lua b/tex/context/base/meta-pdh.lua index 05cdfc176..88c050ffb 100644 --- a/tex/context/base/meta-pdh.lua +++ b/tex/context/base/meta-pdh.lua @@ -27,10 +27,14 @@ local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local tostring, tonumber, select = tostring, tonumber, select local lpegmatch = lpeg.match -mptopdf = { } -mptopdf.parsers = { } -mptopdf.parser = 'none' -mptopdf.n = 0 +local metapost = metapost + +metapost.mptopdf = metapost.mptopdf or { } +local mptopdf = metapost.mptopdf + +mptopdf.parsers = { } +mptopdf.parser = 'none' +mptopdf.n = 0 function mptopdf.reset() mptopdf.data = "" @@ -126,9 +130,9 @@ function mptopdf.steps.convert() mptopdf.data = gsub(mptopdf.data,"%s*([^%a]-)%s*(%a+)", function(args,cmd) if cmd == "textext" then t = mptopdf.texts[tonumber(args)] - return "mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n" + return "metapost.mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n" else - return "mps." .. cmd .. "(" .. gsub(args," +",",") .. ")\n" + return "metapost.mps." .. cmd .. "(" .. gsub(args," +",",") .. ")\n" end end) end @@ -229,7 +233,8 @@ end -- mp interface -mps = mps or { } +metapost.mps = metapost.mps or { } +local mps = metapost.mps or { } function mps.creator(a, b, c) mptopdf.version = tonumber(b) diff --git a/tex/context/base/meta-pdh.mkiv b/tex/context/base/meta-pdh.mkiv index 7cdd1471f..2a8aabed4 100644 --- a/tex/context/base/meta-pdh.mkiv +++ b/tex/context/base/meta-pdh.mkiv @@ -112,7 +112,7 @@ \startMPresources \pdfliteral{\letterpercent\space mps begin}% \pdfliteral{q 1 0 0 1 0 0 cm}% - \ctxlua{mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces + \ctxlua{metapost.mptopdf.convertmpstopdf("\MPfilename")}\removeunwantedspaces \pdfliteral{Q}% \pdfliteral{\letterpercent\space mps end}% \stopMPresources diff --git a/tex/context/base/mlib-ctx.lua b/tex/context/base/mlib-ctx.lua index d04d9b370..8de6a4df6 100644 --- a/tex/context/base/mlib-ctx.lua +++ b/tex/context/base/mlib-ctx.lua @@ -8,14 +8,18 @@ if not modules then modules = { } end modules ['mlib-ctx'] = { -- todo -local format, join = string.format, table.concat +local format, concat = string.format, table.concat local sprint = tex.sprint local report_mplib = logs.new("mplib") local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming -metapost = metapost or {} +local mplib = mplib + +metapost = metapost or {} +local metapost = metapost + metapost.defaultformat = "metafun" function metapost.graphic(instance,mpsformat,str,initializations,preamble,askedfig) @@ -64,7 +68,7 @@ end function metapost.theclippath(...) local result = metapost.getclippath(...) if result then -- we could just print the table - result = join(metapost.flushnormalpath(result),"\n") + result = concat(metapost.flushnormalpath(result),"\n") sprint(result) end end @@ -84,3 +88,19 @@ statistics.register("metapost processing time", function() return nil end end) + +-- only used in graphictexts + +metapost.tex = metapost.tex or { } + +local environments = { } + +function metapost.tex.set(str) + environments[#environments+1] = str +end +function metapost.tex.reset() + environments = { } +end +function metapost.tex.get() + return concat(environments,"\n") +end diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua index 28f9c57ca..27e27eadb 100644 --- a/tex/context/base/mlib-pdf.lua +++ b/tex/context/base/mlib-pdf.lua @@ -12,11 +12,15 @@ local abs, sqrt, round = math.abs, math.sqrt, math.round local report_mplib = logs.new("mplib") -local copy_node, write_node = node.copy, node.write +local mplib = mplib local ctxcatcodes = tex.ctxcatcodes +local copy_node = node.copy +local write_node = node.write metapost = metapost or { } +local metapost = metapost + metapost.multipass = false metapost.n = 0 metapost.optimize = true -- false @@ -63,7 +67,7 @@ metapost.flushers.pdf = { } local savedliterals = nil -local mpsliteral = nodes.register(node.new("whatsit",8)) +local mpsliteral = nodes.pool.register(node.new("whatsit",8)) -- pdfliteral function metapost.flush_literal(d) -- \def\MPLIBtoPDF#1{\ctxlua{metapost.flush_literal(#1)}} if savedliterals then diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua index 9d6b4eb7a..97b336a63 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -26,19 +26,26 @@ local trace_textexts = false trackers.register("metapost.textexts", function(v) local report_mplib = logs.new("mplib") -colors = colors or { } +local colors = attributes.colors local rgbtocmyk = colors.rgbtocmyk or function() return 0,0,0,1 end local cmyktorgb = colors.cmyktorgb or function() return 0,0,0 end local rgbtogray = colors.rgbtogray or function() return 0 end local cmyktogray = colors.cmyktogray or function() return 0 end -metapost = metapost or { } -metapost.specials = metapost.specials or { } -metapost.specials.data = metapost.specials.data or { } -metapost.externals = metapost.externals or { n = 0 } +local mplib, lpdf = mplib, lpdf -local data = metapost.specials.data +metapost = metapost or { } +local metapost = metapost + +metapost.specials = metapost.specials or { } +local specials = metapost.specials + +specials.data = specials.data or { } +local data = specials.data + +metapost.externals = metapost.externals or { n = 0 } +local externals = metapost.externals local colordata = { {}, {}, {}, {}, {} } @@ -59,6 +66,8 @@ local innertransparency = nooutertransparency local pdfcolor, pdftransparency = lpdf.color, lpdf.transparency local registercolor, registerspotcolor = colors.register, colors.registerspotcolor + +local transparencies = attributes.transparencies local registertransparency = transparencies.register function metapost.set_outer_color(mode,colormodel,colorattribute,transparencyattribute) @@ -100,7 +109,7 @@ function metapost.colorinitializer() return outercolor, outertransparency end -function metapost.specials.register(str) -- only colors +function specials.register(str) -- only colors local size, content, n, class = match(str,"^%%%%MetaPostSpecial: (%d+) (.*) (%d+) (%d+)$") if class then -- use lpeg splitter @@ -182,7 +191,7 @@ function metapost.colorspec(cs) -- used for shades ... returns table (for checki end end -function metapost.specials.tr(specification,object,result) +function specials.tr(specification,object,result) local a, t = match(specification,"^(.+),(.+)$") local before = a and t and function() result[#result+1] = format("/Tr%s gs",registertransparency(nil,a,t,true)) -- maybe nil instead of 'mp' @@ -209,11 +218,11 @@ local colorsplitter = lpeg.Ct(lpeg.splitter(":",tonumber)) -- -- This is also an example of a simple plugin. ---~ function metapost.specials.cc(specification,object,result) +--~ function specials.cc(specification,object,result) --~ object.color = lpegmatch(specificationsplitter,specification) --~ return object, nil, nil, nil --~ end ---~ function metapost.specials.cc(specification,object,result) +--~ function specials.cc(specification,object,result) --~ local c = lpegmatch(specificationsplitter,specification) --~ local o = object.color[1] --~ c[1],c[2],c[3],c[4] = o*c[1],o*c[2],o*c[3],o*c[4] @@ -225,7 +234,7 @@ local colorsplitter = lpeg.Ct(lpeg.splitter(":",tonumber)) -- x' = sx * x + ry * y + tx -- y' = rx * x + sy * y + ty -function metapost.specials.fg(specification,object,result,flusher) -- graphics +function specials.fg(specification,object,result,flusher) -- graphics local op = object.path local first, second, fourth = op[1], op[2], op[4] local tx, ty = first.x_coord , first.y_coord @@ -242,7 +251,7 @@ function metapost.specials.fg(specification,object,result,flusher) -- graphics return { } , before, nil, nil -- replace { } by object for tracing end -function metapost.specials.ps(specification,object,result) -- positions +function specials.ps(specification,object,result) -- positions local op = object.path local first, third = op[1], op[3] local x, y = first.x_coord, first.y_coord @@ -347,7 +356,7 @@ end -- todo: we need a way to move/scale -function metapost.specials.cs(specification,object,result,flusher) -- spot colors? +function specials.cs(specification,object,result,flusher) -- spot colors? nofshades = nofshades + 1 local t = lpegmatch(specificationsplitter,specification) local ca = lpegmatch(colorsplitter,t[4]) @@ -359,7 +368,7 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color return resources(object,name,flusher,result) -- object, before, nil, after end -function metapost.specials.ls(specification,object,result,flusher) +function specials.ls(specification,object,result,flusher) nofshades = nofshades + 1 local t = lpegmatch(specificationsplitter,specification) local ca = lpegmatch(colorsplitter,t[4]) @@ -414,7 +423,7 @@ function metapost.gettext(box,slot) -- textexts[slot] = nil -- no, pictures can be placed several times end -function metapost.specials.tf(specification,object) +function specials.tf(specification,object) --~ print("setting", metapost.textext_current) local n, str = match(specification,"^(%d+):(.+)$") if n and str then @@ -433,7 +442,7 @@ function metapost.specials.tf(specification,object) return { }, nil, nil, nil end -function metapost.specials.ts(specification,object,result,flusher) +function specials.ts(specification,object,result,flusher) -- print("getting", metapost.textext_current) local n, str = match(specification,"^(%d+):(.+)$") if n and str then @@ -787,30 +796,12 @@ function metapost.graphic_extra_pass(askedfig) }, false, nil, false, true, askedfig ) end -metapost.tex = metapost.tex or { } - -do -- only used in graphictexts - - local environments = { } - - function metapost.tex.set(str) - environments[#environments+1] = str - end - function metapost.tex.reset() - environments = { } - end - function metapost.tex.get() - return concat(environments,"\n") - end - -end - local graphics = { } local start = [[\starttext]] local preamble = [[\long\def\MPLIBgraphictext#1{\startTEXpage[scale=10000]#1\stopTEXpage}]] local stop = [[\stoptext]] -function metapost.specials.gt(specification,object) -- number, so that we can reorder +function specials.gt(specification,object) -- number, so that we can reorder graphics[#graphics+1] = format("\\MPLIBgraphictext{%s}",specification) metapost.intermediate.needed = true metapost.multipass = true @@ -819,7 +810,6 @@ end function metapost.intermediate.actions.makempy() if #graphics > 0 then - local externals = metapost.externals externals.n = externals.n + 1 starttiming(externals) local mpofile = tex.jobname .. "-mpgraph" diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index a119b0836..c7b24f0f7 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -33,13 +33,16 @@ local trace_graphics = false trackers.register("metapost.graphics", function(v) local report_mplib = logs.new("mplib") -local texerrormessage = tracers.texerrormessage +local texerrormessage = logs.texerrormessage local format, gsub, match = string.format, string.gsub, string.match local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming -metapost = metapost or { } +local mplib = mplib + +metapost = metapost or { } +local metapost = metapost metapost.showlog = false metapost.lastlog = "" diff --git a/tex/context/base/mult-aux.lua b/tex/context/base/mult-aux.lua new file mode 100644 index 000000000..997760a37 --- /dev/null +++ b/tex/context/base/mult-aux.lua @@ -0,0 +1,128 @@ +if not modules then modules = { } end modules ['mult-aux'] = { + version = 1.001, + comment = "companion to mult-aux.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +interfaces.namespaces = interfaces.namespaces or { } +local namespaces = interfaces.namespaces +local variables = interfaces.variables + +local trace_namespaces = false trackers.register("interfaces.namespaces", function(v) trace_namespaces = v end) + +local report_namespaces = logs.new("namespaces") + +local v_yes, v_list = variables.yes, variables.list + +local prefix = "????" +local meaning = "@@@@" + +local data = { } + +function namespaces.define(namespace,settings) + if data[namespace] then + report_namespaces("namespace '%s' is already taken",namespace) + end + if #namespace < 2 then + report_namespaces("namespace '%s' should have more than 1 character",namespace) + end + local ns = { } + data[namespace] = ns + utilities.parsers.settings_to_hash(settings,ns) + local name = ns.name + if not name or name == "" then + report_namespaces("provide a (command) name in namespace '%s'",namespace) + end + local self = prefix .. namespace + context.unprotect() + -- context.installnamespace(namespace) + context("\\def\\%s%s{%s%s}",prefix,self,meaning,namespace) + if trace_namespaces then + report_namespaces("installing namespace '%s' for '%s'",namespace,name) + end + local parent = ns.parent or "" + if parent ~= "" then + if trace_namespaces then + report_namespaces("namespace '%s' for '%s' uses parent '%s'",namespace,name,parent) + end + parent = prefix .. parent + -- todo: check if defined + end + context.installparameterhandler(self,name) + if trace_namespaces then + report_namespaces("installing parameter handler for '%s'",name) + end + context.installparameterhashhandler(self,name) + if trace_namespaces then + report_namespaces("installing parameterhash handler for '%s'",name) + end + local style = ns.style + if style == v_yes then + context.installattributehandler(self,name) + if trace_namespaces then + report_namespaces("installing attribute handler for '%s'",name) + end + end + local command = ns.command + if command == v_yes then + context.installdefinehandler(self,name,parent) + if trace_namespaces then + report_namespaces("installing definition command for '%s' (single)",name) + end + elseif command == v_list then + context.installdefinehandler(self,name,parent) + if trace_namespaces then + report_namespaces("installing definition command for '%s' (multiple)",name) + end + end + local setup = ns.setup + if setup == v_yes then + context.installsetuphandler(self,name) + if trace_namespaces then + report_namespaces("installing setup command for '%s' (single)",name) + end + elseif setup == v_list then + context.installsetuphandler(self,name) + if trace_namespaces then + report_namespaces("installing setup command for '%s' (multiple)",name) + end + end + context.protect() +end + +function utilities.formatters.list(data,key,keys) + if not keys then + keys = { } + for _, v in next, data do + for k, _ in next, v do + keys[k] = true + end + end + keys = table.sortedkeys(keys) + end + context.starttabulate { "|"..string.rep("l|",#keys+1) } + context.NC() + context(key) + for i=1,#keys do + context.NC() + context(keys[i]) + end context.NR() + context.HL() + for k, v in table.sortedhash(data) do + context.NC() + context(k) + for i=1,#keys do + context.NC() + context(v[keys[i]]) + end context.NR() + end + context.stoptabulate() +end + +function namespaces.list() + -- utilities.formatters.list(data,"namespace") + local keys = { "type", "name", "comment", "version", "parent", "definition", "setup", "style" } + utilities.formatters.list(data,"namespace",keys) +end diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv index c364c3507..295b0a71c 100644 --- a/tex/context/base/mult-aux.mkiv +++ b/tex/context/base/mult-aux.mkiv @@ -2,7 +2,7 @@ %D [ file=mult-aux, %D version=2010.08.2, %D title=\CONTEXT\ Multilingual Macros, -%D subtitle=Definitions, +%D subtitle=helpers, %D author=Hans Hagen, %D date=\currentdate, %D copyright=PRAGMA] @@ -12,7 +12,12 @@ %C details. %D A generalization of \MKIV-like inheritance. Just something to play -%D with (interface might change). +%D with (interface might change). The code here evolved in an email +%D exchange between me and Wolgang Schuster. + +\writestatus{loading}{ConTeXt Multilingual Macros / Helpers} + +\registerctxluafile{mult-aux}{1.001} \unprotect @@ -48,52 +53,44 @@ % problem: every* could clash -% faster but assumes \c!always -% -% \unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7#8#9% \??aa {whatever} \current.. -% {\def#3##1{\csname#6{#1#2}##1\endcsname}% -% \def#4##1{#7{#1#2}##1}% -% \def#5##1##2{\csname#6{#1##2}##1\endcsname}% -% \def#6##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#8\csname##1\s!parent\endcsname##2\fi}% -% \def#7##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#9\csname##1\s!parent\endcsname##2\fi}% -% \def#8##1##2{\ifx##1\relax\s!empty\else#6{##1}##2\fi}% -% \def#9##1##2{\ifx##1\relax \else#7{##1}##2\fi}} - -\unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7#8#9% \??aa {whatever} \current.. - {\def#3##1{\csname#6{#1#2}{##1}\endcsname}% - \def#4##1{#7{#1#2}{##1}}% - \def#5##1##2{\csname#6{#1##1}{##2}\endcsname}% - \def#6##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#8\csname##1\s!parent\endcsname{##2}\fi}% - \def#7##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#9\csname##1\s!parent\endcsname{##2}\fi}% - \def#8##1##2{\ifx##1\relax\s!empty\else#6{##1}{##2}\fi}% - \def#9##1##2{\ifx##1\relax \else#7{##1}{##2}\fi}} +% There can be less {} in the following definitions if we assume \??aa and \c!somecs % todo: \def\detokenized...parameter#1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2\endcsname}} % always root +\unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7% + {\def#3##1{\csname#4{#1#2}{##1}\endcsname}% + \def#4##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#5\csname##1\s!parent\endcsname{##2}\fi}% + \def#5##1##2{\ifx##1\relax\s!empty\else#4{##1}{##2}\fi}% + \def#6##1##2{\csname#4{#1##1}{##2}\endcsname}% + \def#7##1{\detokenize\expandafter\expandafter\expandafter{\csname#1##1\endcsname}}} % always root + \def\installparameterhandler#1#2% {\normalexpanded {\doinstallparameterhandler {\noexpand#1}% \??aa \expandafter\noexpand\csname current#2\endcsname - \expandafter\noexpand\csname #2parameter\endcsname % can move - \expandafter\noexpand\csname #2parameterhash\endcsname % can move - \expandafter\noexpand\csname named#2parameter\endcsname % can move + \expandafter\noexpand\csname #2parameter\endcsname \expandafter\noexpand\csname do#2parameter\endcsname - \expandafter\noexpand\csname do#2parameterhash\endcsname \expandafter\noexpand\csname do#2parentparameter\endcsname - \expandafter\noexpand\csname do#2parentparameterhash\endcsname}} + \expandafter\noexpand\csname named#2parameter\endcsname + \expandafter\noexpand\csname detokenized#2parameter\endcsname}} -% faster but assumes \c!always -% -% \unexpanded\def\doinstallattributehandler#1#2#3% #1 not used here -% {\expandafter\def\csname doset#2attributes\endcsname##1##2% style color -% {\edef\fontattributehash {#3##1}% -% \edef\colorattributehash{#3##2}% -% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash ##1\fi -% \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash##2\fi}} +\unexpanded\def\doinstallparameterhashhandler#1#2#3#4#5% + {\def#3##1{#4{#1#2}{##1}}% + \def#4##1##2{\ifcsname##1##2\endcsname##1\else\expandafter#5\csname##1\s!parent\endcsname{##2}\fi}% + \def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}} + +\def\installparameterhashhandler#1#2% + {\normalexpanded + {\doinstallparameterhashhandler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname #2parameterhash\endcsname + \expandafter\noexpand\csname do#2parameterhash\endcsname + \expandafter\noexpand\csname do#2parentparameterhash\endcsname}} \unexpanded\def\doinstallattributehandler#1#2#3% #1 not used here - {\expandafter\def\csname doset#2attributes\endcsname##1##2% style color + {\def#2##1##2% style color {\edef\fontattributehash {#3{##1}}% \edef\colorattributehash{#3{##2}}% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash {##1}\fi @@ -103,12 +100,13 @@ {\normalexpanded {\doinstallattributehandler {\noexpand#1}% \??aa - {\noexpand#2}% whatever + \expandafter\noexpand\csname doset#2attributes\endcsname \expandafter\noexpand\csname #2parameterhash\endcsname}} \unexpanded\def\doinstalldefinehandler#1#2#3#4#5#6#7% - {\unexpanded\expandafter\def\csname define#2\endcsname{\dodoubleempty#5}% - \expandafter\newtoks\csname everydefine#2\endcsname + {\unexpanded\def#2{\dodoubleempty#5}% + \newtoks#6% + \newtoks#7% \def#5[##1][##2]% {\edef#4{##1}% \the#6% predefine @@ -123,20 +121,20 @@ {\normalexpanded {\doinstalldefinehandler {\noexpand#1}% \??aa - {#2}% whatever - {#3}% root + \expandafter\noexpand\csname define#2\endcsname + {\noexpand#3}% root \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname dodefine#2\endcsname \expandafter\noexpand\csname everypreset#2\endcsname \expandafter\noexpand\csname everydefine#2\endcsname}} \unexpanded\def\doinstallsetuphandler#1#2#3#4#5% - {\unexpanded\expandafter\def\csname setup#2\endcsname{\dodoubleempty#4}% - \expandafter\newtoks\csname everysetup#2\endcsname + {\unexpanded\def#2{\dodoubleempty#4}% + \newtoks#5% \def#4[##1][##2]% {\ifsecondargument \def\docommand####1% we will have a simple one as well - {\edef#3{##1#1}% + {\edef#3{##1}% \getparameters[#1#3][##2]% \the#5}% \processcommalist[##1]\docommand @@ -150,16 +148,53 @@ {\normalexpanded {\doinstallsetuphandler {\noexpand#1}% \??aa - {#2}% whatever + \expandafter\noexpand\csname setup#2\endcsname \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname dosetup#2\endcsname \expandafter\noexpand\csname everysetup#2\endcsname}} -\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self) - {\installparameterhandler{#1}{#2}% - \installdefinehandler {#1}{#2}#3% - \installsetuphandler {#1}{#2}% - \installattributehandler{#1}{#2}} +\unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self) + {\installparameterhandler {#1}{#2}% + \installparameterhashhandler{#1}{#2}% + \installdefinehandler {#1}{#2}{#3}% + \installsetuphandler {#1}{#2}% + \installattributehandler {#1}{#2}} + +\def\installnamespace#1% + {\setvalue{????#1}{@@@@#1}} + +% \start +% +% \enabletrackers[interfaces.namespaces] +% +% \definenamespace +% [ws] +% [type=module, +% comment=letter module, +% version=1, +% name=letter, +% style=yes, +% command=yes, +% setup=list, +% parent=ws-common] +% +% \ttx \listnamespaces +% +% \defineletter[mine][whatever=true] \setupletter[mine][whatever=true] +% +% \namedletterparameter{mine}{whatever} +% +% \def\currentletter{mine} \letterparameter{whatever} +% +% \stop + +\def\definenamespace{\dodoubleargument\dodefinenamespace} + +\def\dodefinenamespace[#1][#2]% namespace settings + {\ctxlua{interfaces.namespaces.define(\!!bs#1\!!es,\!!bs#2\!!es)}} + +\def\listnamespaces + {\ctxlua{interfaces.namespaces.list()}} \protect diff --git a/tex/context/base/mult-chk.lua b/tex/context/base/mult-chk.lua index bdbd1dd22..46b67e864 100644 --- a/tex/context/base/mult-chk.lua +++ b/tex/context/base/mult-chk.lua @@ -10,6 +10,7 @@ local format = string.format local lpegmatch = lpeg.match local type = type local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local make_settings_to_hash_pattern, settings_to_set = utilities.parsers.make_settings_to_hash_pattern, utilities.parsers.settings_to_set interfaces = interfaces or { } @@ -25,10 +26,10 @@ function interfaces.setvalidkeys(kind,list) local s = interfaces.syntax[kind] if not s then interfaces.syntax[kind] = { - keys = aux.settings_to_set(list) + keys = settings_to_set(list) } else - s.keys = aux.settings_to_set(list) + s.keys = settings_to_set(list) end end @@ -36,10 +37,10 @@ function interfaces.addvalidkeys(kind,list) local s = interfaces.syntax[kind] if not s then interfaces.syntax[kind] = { - keys = aux.settings_to_set(list) + keys = settings_to_set(list) } else - aux.settings_to_set(list,s.keys) + settings_to_set(list,s.keys) end end @@ -53,9 +54,9 @@ local function set(key,value) end end -local pattern = aux.make_settings_to_hash_pattern(set,"tolerant") +local pattern = make_settings_to_hash_pattern(set,"tolerant") -function commands.getcheckedparameters(k,p,s) +function interfaces.getcheckedparameters(k,p,s) if s and s ~= "" then prefix, kind = p, k keys = k and k ~= "" and interfaces.syntax[k].keys @@ -63,4 +64,4 @@ function commands.getcheckedparameters(k,p,s) end end -_gcp_ = commands.getcheckedparameters +-- _igcp_ = interfaces.getcheckedparameters diff --git a/tex/context/base/mult-chk.mkiv b/tex/context/base/mult-chk.mkiv index 7b40bd64a..cf38daf67 100644 --- a/tex/context/base/mult-chk.mkiv +++ b/tex/context/base/mult-chk.mkiv @@ -50,7 +50,8 @@ \fi{#1}{#3}#5} \def\dogetcheckedparametersyes#1#2#3]% - {\ctxlua{_gcp_("#1","#2",\!!bs\detokenize{#3}\!!es)}} + %{\ctxlua{_igcp_("#1","#2",\!!bs\detokenize{#3}\!!es)}} + {\ctxlua{interfaces.getcheckedparameters("#1","#2",\!!bs\detokenize{#3}\!!es)}} \def\getcheckedparametersnop[#1]#2[#3]#4[#5% {\if\noexpand#5]% diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua index 9e7f94287..ac746b28b 100644 --- a/tex/context/base/mult-cld.lua +++ b/tex/context/base/mult-cld.lua @@ -20,10 +20,12 @@ context = context or { } local format, concat = string.format, table.concat local next, type, tostring = next, type, tostring -local texsprint, texiowrite, ctxcatcodes = tex.sprint, texio.write, tex.ctxcatcodes +local texsprint, texiowrite, texcount, ctxcatcodes = tex.sprint, texio.write, tex.count, tex.ctxcatcodes local flush = texsprint or function(cct,...) print(concat{...}) end +local report_cld = logs.new("cld") + local _stack_, _n_ = { }, 0 local function _store_(ti) @@ -33,7 +35,10 @@ local function _store_(ti) end local function _flush_(n) - if not _stack_[n]() then + local sn = _stack_[n] + if not sn then + report_cld("data with id %s cannot be found on stack",n) + elseif not sn() and texcount.trialtypesettingmode == 0 then _stack_[n] = nil else -- keep, beware, that way the stack can grow @@ -201,7 +206,9 @@ local function indexer(t,k) end local function caller(t,f,a,...) - if a then + if not t then + -- so we don't need to test in the calling (slower but often no issue) + elseif a then flush(ctxcatcodes,format(f,a,...)) elseif type(f) == "function" then flush(ctxcatcodes,"{\\mkivflush{" .. _store_(f) .. "}}") diff --git a/tex/context/base/mult-clm.lua b/tex/context/base/mult-clm.lua index 8838ea532..628c255e9 100644 --- a/tex/context/base/mult-clm.lua +++ b/tex/context/base/mult-clm.lua @@ -17,7 +17,7 @@ local trace_define = false trackers.register("context.define", function(v) trac mkiv = mkiv or { } -mkiv.h, mkiv.a = aux.settings_to_hash, aux.settings_to_array +mkiv.h, mkiv.a = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array local starters, stoppers, macros, stack = { }, { }, { }, { } diff --git a/tex/context/base/mult-de.tex b/tex/context/base/mult-de.tex index a924c0bec..6f9dca7c6 100644 --- a/tex/context/base/mult-de.tex +++ b/tex/context/base/mult-de.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{hintergrundoffset} \setinterfaceconstant{backgroundradius}{hintergrundradius} \setinterfaceconstant{backgroundscreen}{hintergrundraster} +\setinterfaceconstant{backreference}{backreference} \setinterfaceconstant{backspace}{rumpfspatium} \setinterfaceconstant{balance}{ausgleichen} \setinterfaceconstant{before}{vor} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interaktion} \setinterfaceconstant{interlinespace}{zeilenabstande} +\setinterfaceconstant{internalgrid}{internalgrid} \setinterfaceconstant{itemalign}{itemalign} \setinterfaceconstant{items}{posten} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua index 1614301ac..6f63d4072 100644 --- a/tex/context/base/mult-def.lua +++ b/tex/context/base/mult-def.lua @@ -6868,6 +6868,10 @@ return { ["pe"]="فضایپس", ["ro"]="spatiuspate", }, + ["backreference"]={ + ["en"]="backreference", + ["nl"]="terugreferentie", + }, ["balance"]={ ["cs"]="rovnovaha", ["de"]="ausgleichen", @@ -8216,6 +8220,10 @@ return { ["pe"]="فضایبینخط", ["ro"]="spatiereinterliniara", }, + ["internalgrid"]={ + ["nl"]="interngrid", + ["en"]="internalgrid", + }, ["itemalign"]={ ["cs"]="itemalign", ["de"]="itemalign", diff --git a/tex/context/base/mult-en.tex b/tex/context/base/mult-en.tex index 094678d1e..53df30f02 100644 --- a/tex/context/base/mult-en.tex +++ b/tex/context/base/mult-en.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{backgroundoffset} \setinterfaceconstant{backgroundradius}{backgroundradius} \setinterfaceconstant{backgroundscreen}{backgroundscreen} +\setinterfaceconstant{backreference}{backreference} \setinterfaceconstant{backspace}{backspace} \setinterfaceconstant{balance}{balance} \setinterfaceconstant{before}{before} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interaction} \setinterfaceconstant{interlinespace}{interlinespace} +\setinterfaceconstant{internalgrid}{internalgrid} \setinterfaceconstant{itemalign}{itemalign} \setinterfaceconstant{items}{items} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/mult-fr.tex b/tex/context/base/mult-fr.tex index 52dfab7e4..50da78c48 100644 --- a/tex/context/base/mult-fr.tex +++ b/tex/context/base/mult-fr.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{decalagearriereplan} \setinterfaceconstant{backgroundradius}{rayonarriereplan} \setinterfaceconstant{backgroundscreen}{ecranarriereplan} +\setinterfaceconstant{backreference}{backreference} \setinterfaceconstant{backspace}{retour} \setinterfaceconstant{balance}{equilibre} \setinterfaceconstant{before}{avant} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interaction} \setinterfaceconstant{interlinespace}{espaceinterligne} +\setinterfaceconstant{internalgrid}{internalgrid} \setinterfaceconstant{itemalign}{itemalign} \setinterfaceconstant{items}{elements} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index 92a7bc629..2b31bcfc0 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -19,6 +19,10 @@ storage.register("interfaces/messages", interfaces.messages, "interfaces.messa storage.register("interfaces/constants", interfaces.constants, "interfaces.constants") storage.register("interfaces/variables", interfaces.variables, "interfaces.variables") +interfaces.interfaces = { + "cs", "de", "en", "fr", "it", "nl", "ro", "pe", +} + local messages, constants, variables = interfaces.messages, interfaces.constants, interfaces.variables function interfaces.setmessages(category,str) @@ -81,8 +85,8 @@ end interfaces.cachedsetups = interfaces.cachedsetups or { } interfaces.hashedsetups = interfaces.hashedsetups or { } -storage.register("interfaces.cachedsetups", interfaces.cachedsetups, "interfaces.cachedsetups") -storage.register("interfaces.hashedsetups", interfaces.hashedsetups, "interfaces.hashedsetups") +storage.register("interfaces/cachedsetups", interfaces.cachedsetups, "interfaces.cachedsetups") +storage.register("interfaces/hashedsetups", interfaces.hashedsetups, "interfaces.hashedsetups") local cachedsetups = interfaces.cachedsetups local hashedsetups = interfaces.hashedsetups diff --git a/tex/context/base/mult-it.tex b/tex/context/base/mult-it.tex index fe9534c08..71e1f8ac5 100644 --- a/tex/context/base/mult-it.tex +++ b/tex/context/base/mult-it.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{offsetsfondo} \setinterfaceconstant{backgroundradius}{raggiosfondo} \setinterfaceconstant{backgroundscreen}{schermosfondo} +\setinterfaceconstant{backreference}{backreference} \setinterfaceconstant{backspace}{backspace} \setinterfaceconstant{balance}{bilanciamento} \setinterfaceconstant{before}{prima} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interazione} \setinterfaceconstant{interlinespace}{interlinea} +\setinterfaceconstant{internalgrid}{internalgrid} \setinterfaceconstant{itemalign}{itemalign} \setinterfaceconstant{items}{elementi} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/mult-nl.tex b/tex/context/base/mult-nl.tex index 4b08fcdaa..d1406e1f5 100644 --- a/tex/context/base/mult-nl.tex +++ b/tex/context/base/mult-nl.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{achtergrondoffset} \setinterfaceconstant{backgroundradius}{achtergrondstraal} \setinterfaceconstant{backgroundscreen}{achtergrondraster} +\setinterfaceconstant{backreference}{terugreferentie} \setinterfaceconstant{backspace}{rugwit} \setinterfaceconstant{balance}{balanceren} \setinterfaceconstant{before}{voor} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interactie} \setinterfaceconstant{interlinespace}{interlinie} +\setinterfaceconstant{internalgrid}{interngrid} \setinterfaceconstant{itemalign}{itemuitlijnen} \setinterfaceconstant{items}{items} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/mult-ro.tex b/tex/context/base/mult-ro.tex index 8eae4e4b5..2a19ca229 100644 --- a/tex/context/base/mult-ro.tex +++ b/tex/context/base/mult-ro.tex @@ -554,6 +554,7 @@ \setinterfaceconstant{backgroundoffset}{offsetfundal} \setinterfaceconstant{backgroundradius}{razafundal} \setinterfaceconstant{backgroundscreen}{ecranfundal} +\setinterfaceconstant{backreference}{backreference} \setinterfaceconstant{backspace}{spatiuspate} \setinterfaceconstant{balance}{balanta} \setinterfaceconstant{before}{inainte} @@ -703,6 +704,7 @@ \setinterfaceconstant{intent}{intent} \setinterfaceconstant{interaction}{interactiune} \setinterfaceconstant{interlinespace}{spatiereinterliniara} +\setinterfaceconstant{internalgrid}{internalgrid} \setinterfaceconstant{itemalign}{itemalign} \setinterfaceconstant{items}{elemente} \setinterfaceconstant{juniorsep}{juniorsep} diff --git a/tex/context/base/node-acc.lua b/tex/context/base/node-acc.lua index fc0c5fb0f..c131a0002 100644 --- a/tex/context/base/node-acc.lua +++ b/tex/context/base/node-acc.lua @@ -6,25 +6,29 @@ if not modules then modules = { } end modules ['node-acc'] = { license = "see context related readme files" } -local traverse_nodes, traverse_id, has_attribute, copy_node = node.traverse, node.traverse_id, node.has_attribute, node.copy +local nodes, node = nodes, node -nodes.accessibility = nodes.accessibility or { } +local nodecodes = nodes.nodecodes +local tasks = nodes.tasks -local nodecodes = nodes.nodecodes +local traverse_nodes = node.traverse +local traverse_id = node.traverse_id +local has_attribute = node.has_attribute +local copy_node = node.copy -local glue = nodecodes.glue -local glyph = nodecodes.glyph -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local glue_code = nodecodes.glue +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist local function injectspaces(head) local p for n in traverse_nodes(head) do local id = n.id - if id == glue then -- todo: check for subtype related to spacing (13/14 but most seems to be 0) + if id == glue_code then -- todo: check for subtype related to spacing (13/14 but most seems to be 0) -- local at = has_attribute(n,attribute) -- if at then - if p and p.id == glyph then + if p and p.id == glyph_code then local g = copy_node(p) local s = copy_node(n.spec) g.char, n.spec = 32, s @@ -33,7 +37,7 @@ local function injectspaces(head) s.width = s.width - g.width end -- end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then injectspaces(n.list,attribute) end p = n @@ -41,9 +45,7 @@ local function injectspaces(head) return head, true end -nodes.accessibility.handler = injectspaces - --- nodes.accessibility.handler(tex.box[255].list) +nodes.handlers.accessibility = injectspaces -- todo: @@ -53,7 +55,7 @@ nodes.accessibility.handler = injectspaces --~ --~ local function compact(n) --~ local t = { } ---~ for n in traverse_id(glyph,n) do +--~ for n in traverse_id(glyph_code,n) do --~ t[#t+1] = utfchar(n.char) -- check for unicode --~ end --~ return concat(t,"") @@ -74,7 +76,7 @@ nodes.accessibility.handler = injectspaces --~ end --~ set_attribute(n,a_hyphenated,hsh) --~ end ---~ elseif id == hlist or id == vlist then +--~ elseif id == hlist_code or id == vlist_code then --~ injectspans(n.list) --~ end --~ end @@ -97,7 +99,7 @@ nodes.accessibility.handler = injectspaces --~ node.insert_before(head,n,b) --~ node.insert_after(head,n,e) --~ end ---~ elseif id == hlist or id == vlist then +--~ elseif id == hlist_code or id == vlist_code then --~ injectspans(n.list) --~ end --~ end diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua index 4b57bf225..58049f020 100644 --- a/tex/context/base/node-aux.lua +++ b/tex/context/base/node-aux.lua @@ -1,20 +1,25 @@ if not modules then modules = { } end modules ['node-aux'] = { version = 1.001, - comment = "companion to node-spl.mkiv", + comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -local gsub, format = string.gsub, string.format +local nodes, node = nodes, node -local free_node, hpack_nodes, node_fields, traverse_nodes = node.free, node.hpack, node.fields, node.traverse -local has_attribute, set_attribute, unset_attribute, has_attribute = node.has_attribute, node.set_attribute, node.unset_attribute,node.has_attribute +local nodecodes = nodes.nodecodes -local nodecodes = nodes.nodecodes +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local traverse_nodes = node.traverse +local free_node = node.free +local hpack_nodes = node.hpack +local has_attribute = node.has_attribute +local set_attribute = node.set_attribute +local get_attribute = node.get_attribute +local unset_attribute = node.unset_attribute function nodes.repack_hlist(list,...) local temp, b = hpack_nodes(list,...) @@ -24,44 +29,46 @@ function nodes.repack_hlist(list,...) return list, b end -function nodes.merge(a,b) - if a and b then - local t = node.fields(a.id) - for i=3,#t do - local name = t[i] - a[name] = b[name] +local function set_attributes(head,attr,value) + for n in traverse_nodes(head) do + set_attribute(n,attr,value) + local id = n.id + if id == hlist_node or id == vlist_node then + set_attributes(n.list,attr,value) end end - return a, b end -local fields, whatsitfields = { }, { } - -for k, v in next, node.types() do - if v == "whatsit" then - fields[k], fields[v] = { }, { } - for kk, vv in next, node.whatsits() do - local f = node_fields(k,kk) - whatsitfields[kk], whatsitfields[vv] = f, f +local function set_unset_attributes(head,attr,value) + for n in traverse_nodes(head) do + if not has_attribute(n,attr) then + set_attribute(n,attr,value) + end + local id = n.id + if id == hlist_code or id == vlist_code then + set_unset_attributes(n.list,attr,value) end - else - local f = node_fields(k) - fields[k], fields[v] = f, f end end -nodes.fields, nodes.whatsitfields = fields, whatsitfields - -function nodes.info(n) - local id = n.id - local tp = node.type(id) - local list = (tp == "whatsit" and whatsitfields[n.subtype]) or fields[id] - logs.report(format("%14s","type"),tp) - for k,v in next, list do - logs.report(format("%14s",v),gsub(gsub(tostring(n[v]),"%s+"," "),"node ","")) +local function unset_attributes(head,attr) + for n in traverse_nodes(head) do + unset_attribute(n,attr) + local id = n.id + if id == hlist_code or id == vlist_code then + unset_attributes(n.list,attr) + end end end +nodes.set_attribute = set_attribute +nodes.unset_attribute = unset_attribute +nodes.has_attribute = has_attribute + +nodes.set_attributes = set_attributes +nodes.set_unset_attributes = set_unset_attributes +nodes.unset_attributes = unset_attributes + -- history: -- -- local function cp_skipable(a,id) -- skipable nodes at the margins during character protrusion @@ -146,43 +153,3 @@ end -- return -u -- end -- end - - -local function set_attributes(head,attr,value) - for n in traverse_nodes(head) do - set_attribute(n,attr,value) - local id = n.id - if id == hlist or id == vlist then - set_attributes(n.list,attr,value) - end - end -end - -local function set_unset_attributes(head,attr,value) - for n in traverse_nodes(head) do - if not has_attribute(n,attr) then - set_attribute(n,attr,value) - end - local id = n.id - if id == hlist or id == vlist then - set_unset_attributes(n.list,attr,value) - end - end -end - -local function unset_attributes(head,attr) - for n in traverse_nodes(head) do - unset_attribute(n,attr) - local id = n.id - if id == hlist or id == vlist then - unset_attributes(n.list,attr) - end - end -end - -nodes.set_attribute = set_attribute -nodes.unset_attribute = unset_attribute -nodes.has_attribute = has_attribute -nodes.set_attributes = set_attributes -nodes.set_unset_attributes = set_unset_attributes -nodes.unset_attributes = unset_attributes diff --git a/tex/context/base/node-bck.lua b/tex/context/base/node-bck.lua index 593be8492..e1e4d4652 100644 --- a/tex/context/base/node-bck.lua +++ b/tex/context/base/node-bck.lua @@ -9,17 +9,22 @@ if not modules then modules = { } end modules ['node-bck'] = { -- beware, this one takes quite some runtime, so we need a status flag -- maybe some page related state -local nodecodes = nodes.nodecodes +local attributes, nodes, node = attributes, nodes, node -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local nodecodes = nodes.nodecodes -local has_attribute = node.has_attribute -local set_attribute = node.set_attribute -local traverse = node.traverse +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist -local new_rule = nodes.rule -local new_glue = nodes.glue +local has_attribute = node.has_attribute +local set_attribute = node.set_attribute +local traverse = node.traverse + +local nodepool = nodes.pool +local tasks = nodes.tasks + +local new_rule = nodepool.rule +local new_glue = nodepool.glue local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') @@ -28,11 +33,11 @@ local a_background = attributes.private('background') local function add_backgrounds(head) -- boxes, inline will be done too local id = head.id - if id == vlist or id == hlist then + if id == vlist_code or id == hlist_code then local current = head.list while current do local id = current.id - if id == hlist then -- and current.list + if id == hlist_code then -- and current.list local background = has_attribute(current,a_background) if background then -- direct to hbox @@ -86,7 +91,7 @@ local function add_backgrounds(head) -- boxes, inline will be done too add_backgrounds(current) end end - elseif id == vlist then -- and current.list + elseif id == vlist_code then -- and current.list -- direct to vbox local background = has_attribute(current,a_background) if background then @@ -116,6 +121,6 @@ local function add_backgrounds(head) -- boxes, inline will be done too return head, true end -nodes.add_backgrounds = add_backgrounds +nodes.handlers.backgrounds = add_backgrounds -tasks.appendaction("shipouts","normalizers","nodes.add_backgrounds") +tasks.appendaction("shipouts","normalizers","nodes.handlers.backgrounds") diff --git a/tex/context/base/node-dir.lua b/tex/context/base/node-dir.lua index 3f65c75b1..f168c7f2b 100644 --- a/tex/context/base/node-dir.lua +++ b/tex/context/base/node-dir.lua @@ -15,7 +15,7 @@ adapted and now has the mappings as comments. This lua file is based on that file. ]]-- -nodes = nodes or { } +local nodes = nodes nodes.is_mirrored = { -- TLT = false, diff --git a/tex/context/base/node-dum.lua b/tex/context/base/node-dum.lua index 9483e51fc..831c0a842 100644 --- a/tex/context/base/node-dum.lua +++ b/tex/context/base/node-dum.lua @@ -10,12 +10,24 @@ nodes = nodes or { } fonts = fonts or { } attributes = attributes or { } +nodes.pool = nodes.pool or { } +nodes.handlers = nodes.handlers or { } + +local nodecodes = { } for k,v in next, node.types () do nodecodes[string.gsub(v,"_","")] = k end +local whatcodes = { } for k,v in next, node.whatsits() do whatcodes[string.gsub(v,"_","")] = k end +local glyphcodes = { [0] = "character", "glyph", "ligature", "ghost", "left", "right" } + +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes +nodes.whatsitcodes = whatcodes +nodes.glyphcodes = glyphcodes + local traverse_id = node.traverse_id local free_node = node.free local remove_node = node.remove local new_node = node.new -local glyph = node.id('glyph') +local glyph_code = nodecodes.glyph -- fonts @@ -23,9 +35,9 @@ local fontdata = fonts.ids or { } function nodes.simple_font_handler(head) -- lang.hyphenate(head) - head = nodes.process_characters(head) - nodes.inject_kerns(head) - nodes.protect_glyphs(head) + head = nodes.handlers.characters(head) + nodes.handlers.injectkerns(head) + nodes.handlers.protectglyphs(head) head = node.ligaturing(head) head = node.kerning(head) return head @@ -43,45 +55,47 @@ if tex.attribute[0] ~= 0 then end -nodes.protect_glyphs = node.protect_glyphs -nodes.unprotect_glyphs = node.unprotect_glyphs - -function nodes.process_characters(head) - local usedfonts, done, prevfont = { }, false, nil - for n in traverse_id(glyph,head) do - local font = n.font - if font ~= prevfont then - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - done = true +nodes.handlers.protectglyphs = node.protect_glyphs +nodes.handlers.unprotectglyphs = node.unprotect_glyphs + +nodes.characters = { + handler = function (head) + local usedfonts, done, prevfont = { }, false, nil + for n in traverse_id(glyph_code,head) do + local font = n.font + if font ~= prevfont then + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + done = true + end end end end end end - end - if done then - for font, processors in next, usedfonts do - for i=1,#processors do - local h, d = processors[i](head,font,0) - head, done = h or head, done or d + if done then + for font, processors in next, usedfonts do + for i=1,#processors do + local h, d = processors[i](head,font,0) + head, done = h or head, done or d + end end end + return head, true end - return head, true -end +} -- helper -function nodes.kern(k) +function nodes.pool.kern(k) local n = new_node("kern",1) n.kern = k return n diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 004d72765..84b60232c 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -11,26 +11,33 @@ if not modules then modules = { } end modules ['node-fin'] = { local next, type, format = next, type, string.format local texsprint = tex.sprint local ctxcatcodes = tex.ctxcatcodes -local has_attribute, copy_node = node.has_attribute, node.copy -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming -local nodecodes = nodes.nodecodes +local attributes, nodes, node = attributes, nodes, node -local glyph = nodecodes.glyph -local disc = nodecodes.disc -local glue = nodecodes.glue -local rule = nodecodes.rule -local whatsit = nodecodes.whatsit -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local has_attribute = node.has_attribute +local copy_node = node.copy -states = states or { } -shipouts = shipouts or { } +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist + +local pdfliteral_code = whatcodes.pdfliteral + +local states = attributes.states local numbers = attributes.numbers local trigger = attributes.private('trigger') local triggering = false +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + -- these two will be like trackers function states.enabletriggering() @@ -108,7 +115,7 @@ local function process_attribute(head,plugin) -- head,attribute,enabled,initiali end end -nodes.process_attribute = process_attribute +-- nodes.process_attribute = process_attribute function nodes.install_attribute_handler(plugin) -- we need to avoid this nested function return function(head) @@ -182,7 +189,7 @@ end function states.finalize(namespace,attribute,head) -- is this one ok? if current > 0 and nsnone then local id = head.id - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then local list = head.list if list then head.list = insert_node_before(list,list,copy_node(nsnone)) @@ -200,9 +207,9 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr while stack do local id = stack.id -- we need to deal with literals too (reset as well as oval) - -- if id == glyph or (id == whatsit and stack.subtype == 8) or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc - if id == glyph -- or id == disc - or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc + -- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code + if id == glyph_code -- or id == disc_code + or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code local c = has_attribute(stack,attribute) if c then if default and c == inheritance then @@ -215,13 +222,13 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr current, done = c, true end -- here ? compare selective - if id == glue then --leader + if id == glue_code then --leader -- same as *list local content = stack.leader if content then local savedcurrent = current local ci = content.id - if ci == hlist or ci == vlist then + if ci == hlist_code or ci == vlist_code then -- else we reset inside a box unneeded, okay, the downside is -- that we trigger color in each repeated box, so there is room -- for improvement here @@ -251,7 +258,7 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr head = insert_node_before(head,stack,copy_node(nsnone)) current, done = 0, true end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then local content = stack.list if content then local ok = false @@ -286,9 +293,9 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at while stack do local id = stack.id -- we need to deal with literals too (reset as well as oval) - -- if id == glyph or (id == whatsit and stack.subtype == 8) or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc - if id == glyph -- or id == disc - or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc + -- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code + if id == glyph_code -- or id == disc_code + or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code local c = has_attribute(stack,attribute) if c then if default and c == inheritance then @@ -315,13 +322,13 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at head = insert_node_before(head,stack,copy_node(nsnone)) current, current_selector, done = 0, 0, true end - if id == glue then -- leader + if id == glue_code then -- leader -- same as *list local content = stack.leader if content then local savedcurrent = current local ci = content.id - if ci == hlist or ci == vlist then + if ci == hlist_code or ci == vlist_code then -- else we reset inside a box unneeded, okay, the downside is -- that we trigger color in each repeated box, so there is room -- for improvement here @@ -342,7 +349,7 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at done = done or ok end end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then local content = stack.list if content then local ok = false @@ -377,7 +384,7 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in local current, depth = default or 0, 0 while stack do local id = stack.id - if id == glyph or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc + if id == glyph_code or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code local c = has_attribute(stack,attribute) if c then if current ~= c then @@ -385,7 +392,7 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in depth = depth + 1 current, done = c, true end - if id == glue then + if id == glue_code then local content = stack.leader if content then -- unchecked local ok = false @@ -400,7 +407,7 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in depth = depth - 1 current, done = 0, true end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then local content = stack.list if content then -- the problem is that broken lines gets the attribute which can be a later one diff --git a/tex/context/base/node-fin.mkiv b/tex/context/base/node-fin.mkiv index ea9e83f16..8e3ce5c3d 100644 --- a/tex/context/base/node-fin.mkiv +++ b/tex/context/base/node-fin.mkiv @@ -22,8 +22,8 @@ \definesystemattribute[trigger] \chardef\triggerattribute \dogetattributeid{trigger} % feature inheritance -\def\finalizeobjectbox #1{\ctxlua{nodes.process_page(tex.box[\number#1])}} -\def\finalizeshipoutbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}} +\def\finalizeobjectbox #1{\ctxlua{nodes.handlers.finalize(tex.box[\number#1])}} +\def\finalizeshipoutbox#1{\ctxlua{nodes.handlers.finalize(tex.box[\number#1])}} % tricky stuff: @@ -56,12 +56,12 @@ \stopinheritattributes} \def\enableattributeinheritance - {\ctxlua{states.enabletriggering()}% + {\ctxlua{attributes.states.enabletriggering()}% \let\attributedcopy\doattributedcopy \let\attributedbox \doattributedbox} \def\disableattributeinheritance - {\ctxlua{states.disabletriggering()}% + {\ctxlua{attributes.states.disabletriggering()}% \let\attributedcopy\copy \let\attributedbox \box} diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua index ad7af592f..3c98785e5 100644 --- a/tex/context/base/node-fnt.lua +++ b/tex/context/base/node-fnt.lua @@ -12,18 +12,20 @@ local next, type = next, type local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end) -local traverse_id, has_attribute = node.traverse_id, node.has_attribute -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming - -local nodecodes = nodes.nodecodes - -local glyph = nodecodes.glyph +local nodes, node = nodes, node fonts = fonts or { } fonts.tfm = fonts.tfm or { } fonts.ids = fonts.ids or { } -local fontdata = fonts.ids +local traverse_id = node.traverse_id +local has_attribute = node.has_attribute +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local nodecodes = nodes.nodecodes +local glyph = nodecodes.glyph +local fontdata = fonts.ids +local handlers = nodes.handlers -- some tests with using an array of dynamics[id] and processes[id] demonstrated -- that there was nothing to gain (unless we also optimize other parts) @@ -35,7 +37,7 @@ local fontdata = fonts.ids -- happen often; we could consider processing sublists but that might need mor -- checking later on; the current approach also permits variants -function nodes.process_characters(head) +function handlers.characters(head) -- either next or not, but definitely no already processed list starttiming(nodes) local usedfonts, attrfonts, done = { }, { }, false @@ -151,5 +153,5 @@ function nodes.process_characters(head) return head, true end -nodes.protect_glyphs = node.protect_glyphs -nodes.unprotect_glyphs = node.unprotect_glyphs +handlers.protectglyphs = node.protect_glyphs +handlers.unprotectglyphs = node.unprotect_glyphs diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua index 836c43860..5af780264 100644 --- a/tex/context/base/node-ini.lua +++ b/tex/context/base/node-ini.lua @@ -15,7 +15,11 @@ modules.</p> local utf = unicode.utf8 local next, type = next, type -local format, concat, match, utfchar = string.format, table.concat, string.match, utf.char +local format, concat, match, gsub = string.format, table.concat, string.match, string.gsub +local utfchar = utf.char +local swapped = table.swapped +local lpegmatch = lpeg.match +local formatcolumns = utilities.formatters.formatcolumns --[[ldx-- <p>Access to nodes is what gives <l n='luatex'/> its power. Here we @@ -50,12 +54,15 @@ into the <l n='tex'/> engine, but this is a not so natural extension.</p> also ignore the empty nodes. [This is obsolete!]</p> --ldx]]-- -nodes = nodes or { } - local traverse, traverse_id = node.traverse, node.traverse_id local free_node, remove_node = node.free, node.remove local insert_node_before, insert_node_after = node.insert_before, node.insert_after +nodes = nodes or { } +local nodes = nodes + +nodes.handlers = nodes.handlers or { } + -- there will be more of this: local skipcodes = { @@ -82,9 +89,9 @@ local skipcodes = { local noadcodes = { [ 0] = "ord", - [ 1] = "op_displaylimits", - [ 2] = "op_limits", - [ 3] = "op_nolimits", + [ 1] = "opdisplaylimits", + [ 2] = "oplimits", + [ 3] = "opnolimits", [ 4] = "bin", [ 5] = "rel", [ 6] = "open", @@ -96,27 +103,112 @@ local noadcodes = { [12] = "vcenter", } -local nodecodes = node.types() -local whatsitcodes = node.whatsits() +local listcodes = { + [ 0] = "unknown", + [ 1] = "line", + [ 2] = "box", + [ 3] = "indent", + [ 4] = "alignment", -- row or column + [ 5] = "cell", +} + +local glyphcodes = { + [0] = "character", + [1] = "glyph", + [2] = "ligature", + [3] = "ghost", + [4] = "left", + [5] = "right", +} + +local kerncodes = { + [0] = "fontkern", + [1] = "userkern", + [2] = "accentkern", +} + +local mathcodes = { + [0] = "beginmath", + [1] = "endmath", +} + +local fillcodes = { + [0] = "stretch", + [1] = "fi", + [2] = "fil", + [3] = "fill", + [4] = "filll", +} + +local function simplified(t) + local r = { } + for k, v in next, t do + r[k] = gsub(v,"_","") + end + return r +end -skipcodes = table.swapped(skipcodes,skipcodes) -noadcodes = table.swapped(noadcodes,noadcodes) -nodecodes = table.swapped(nodecodes,nodecodes) -whatsitcodes = table.swapped(whatsitcodes,whatsitcodes) +local nodecodes = simplified(node.types()) +local whatcodes = simplified(node.whatsits()) -nodes.skipcodes = skipcodes -nodes.gluecodes = skipcodes -- more official -nodes.noadcodes = noadcodes -nodes.nodecodes = nodecodes -nodes.whatsitcodes = whatsitcodes +skipcodes = swapped(skipcodes, skipcodes) +noadcodes = swapped(noadcodes, noadcodes) +nodecodes = swapped(nodecodes, nodecodes) +whatcodes = swapped(whatcodes, whatcodes) +listcodes = swapped(listcodes, listcodes) +glyphcodes = swapped(glyphcodes,glyphcodes) +kerncodes = swapped(kerncodes, kerncodes) +mathcodes = swapped(mathcodes, mathcodes) +fillcodes = swapped(fillcodes, fillcodes) -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local glyph = nodecodes.glyph -local glue = nodecodes.glue -local penalty = nodecodes.penalty -local kern = nodecodes.kern -local whatsit = nodecodes.whatsit +nodes.skipcodes = skipcodes nodes.gluecodes = skipcodes -- more official +nodes.noadcodes = noadcodes +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes nodes.whatsitcodes = whatcodes -- more official +nodes.listcodes = listcodes +nodes.glyphcodes = glyphcodes +nodes.kerncodes = kerncodes +nodes.mathcodes = mathcodes +nodes.fillcodes = fillcodes + +listcodes.row = listcodes.alignment +listcodes.column = listcodes.alignment + +kerncodes.italiccorrection = kerncodes.userkern +kerncodes.kerning = kerncodes.fontkern + +nodes.codes = { + hlist = listcodes, + vlist = listcodes, + glyph = glyphcodes, + glue = skipcodes, + kern = kerncodes, + whatsit = whatcodes, + math = mathnodes, + noad = noadcodes, +} + +function nodes.showcodes() + local t = { } + for name, codes in table.sortedhash(nodes.codes) do + local sorted = table.sortedkeys(codes) + for i=1,#sorted do + local s = sorted[i] + if type(s) ~= "number" then + t[#t+1] = { name, s, codes[s] } + end + end + end + formatcolumns(t) + for k=1,#t do + texio.write_nl(t[k]) + end +end + +trackers.register("system.showcodes", nodes.showcodes) + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist function nodes.remove(head, current, free_too) local t = current @@ -210,7 +302,7 @@ local function count(stack,flat) local n = 0 while stack do local id = stack.id - if not flat and id == hlist or id == vlist then + if not flat and id == hlist_code or id == vlist_code then local list = stack.list if list then n = n + 1 + count(list) -- self counts too @@ -229,4 +321,8 @@ nodes.count = count local left, space = lpeg.P("<"), lpeg.P(" ") -nodes.filterkey = left * (1-left)^0 * left * space^0 * lpeg.C((1-space)^0) +local reference = left * (1-left)^0 * left * space^0 * lpeg.C((1-space)^0) + +function nodes.reference(n) + return lpegmatch(reference,tostring(n)) +end diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv index a5559e85d..3bc258ce6 100644 --- a/tex/context/base/node-ini.mkiv +++ b/tex/context/base/node-ini.mkiv @@ -18,14 +18,13 @@ \newcount\filterstate \filterstate\plusone \registerctxluafile{node-ini}{1.001} +\registerctxluafile{node-res}{1.001} \registerctxluafile{node-dir}{1.001} \registerctxluafile{node-aux}{1.001} \registerctxluafile{node-tst}{1.001} \registerctxluafile{node-tra}{1.001} % we might split it off (module) -\registerctxluafile{node-seq}{1.001} % we might generalize this one \registerctxluafile{node-tsk}{1.001} \registerctxluafile{node-tex}{1.001} -\registerctxluafile{node-res}{1.001} \registerctxluafile{node-pro}{1.001} \registerctxluafile{node-shp}{1.001} \registerctxluafile{node-ser}{1.001} diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua index 22a716a12..527df7ca9 100644 --- a/tex/context/base/node-inj.lua +++ b/tex/context/base/node-inj.lua @@ -19,14 +19,17 @@ local trace_injections = false trackers.register("nodes.injections", function(v local report_injections = logs.new("injections") +local attributes, nodes, node = attributes, nodes, node + fonts = fonts or { } fonts.tfm = fonts.tfm or { } fonts.ids = fonts.ids or { } -local fontdata = fonts.ids - -local glyph = node.id('glyph') -local kern = node.id('kern') +local fontdata = fonts.ids +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local nodepool = nodes.pool +local newkern = nodepool.kern local traverse_id = node.traverse_id local unset_attribute = node.unset_attribute @@ -35,8 +38,6 @@ local set_attribute = node.set_attribute local insert_node_before = node.insert_before local insert_node_after = node.insert_after -local newkern = nodes.kern - local markbase = attributes.private('markbase') local markmark = attributes.private('markmark') local markdone = attributes.private('markdone') @@ -121,12 +122,13 @@ function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, m return dx, dy, bound end +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end + function nodes.trace_injection(head) - local function dir(n) - return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or ("unset") - end report_injections("begin run") - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then local kp = has_attribute(n,kernpair) local mb = has_attribute(n,markbase) @@ -175,7 +177,7 @@ end -- todo: reuse tables (i.e. no collection), but will be extra fields anyway -- todo: check for attribute -function nodes.inject_kerns(head,where,keep) +function nodes.handlers.injectkerns(head,where,keep) local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) if has_marks or has_cursives then --~ if has_marks or has_cursives or has_kerns then @@ -186,7 +188,7 @@ function nodes.inject_kerns(head,where,keep) local done, ky, rl, valid, cx, wx, mk = false, { }, { }, { }, { }, { }, { } if has_kerns then -- move outside loop local nf, tm = nil, nil - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then valid[#valid+1] = n if n.font ~= nf then @@ -214,7 +216,7 @@ function nodes.inject_kerns(head,where,keep) end else local nf, tm = nil, nil - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then valid[#valid+1] = n if n.font ~= nf then @@ -307,7 +309,7 @@ function nodes.inject_kerns(head,where,keep) local p_markbase = has_attribute(p,markbase) if p_markbase then local mrks = marks[p_markbase] - for n in traverse_id(glyph,p.next) do + for n in traverse_id(glyph_code,p.next) do local n_markmark = has_attribute(n,markmark) if p_markbase == n_markmark then local index = has_attribute(n,markdone) or 1 @@ -386,7 +388,7 @@ function nodes.inject_kerns(head,where,keep) if trace_injections then nodes.trace_injection(head) end - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then local k = has_attribute(n,kernpair) if k then diff --git a/tex/context/base/node-mig.lua b/tex/context/base/node-mig.lua index c2d6e8eca..24f01fbff 100644 --- a/tex/context/base/node-mig.lua +++ b/tex/context/base/node-mig.lua @@ -8,18 +8,21 @@ if not modules then modules = { } end modules ['node-mig'] = { local format = string.format +local attributes, nodes, node = attributes, nodes, node + local has_attribute = node.has_attribute local set_attribute = node.set_attribute local remove_nodes = nodes.remove -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local tasks = nodes.tasks -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local insert = nodecodes.ins -local mark = nodecodes.mark +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local insert_code = nodecodes.ins +local mark_code = nodecodes.mark -local migrated = attributes.private("migrated") +local migrated = attributes.private("migrated") local trace_migrations = false trackers.register("nodes.migrations", function(v) trace_migrations = v end) @@ -33,10 +36,10 @@ local function locate(head,first,last,ni,nm) local current = head while current do local id = current.id - if id == vlist or id == hlist then + if id == vlist_code or id == hlist_code then current.list, first, last, ni, nm = locate(current.list,first,last,ni,nm) current= current.next - elseif migrate_inserts and id == insert then + elseif migrate_inserts and id == insert_code then local insert head, current, insert = remove_nodes(head,current) insert.next = nil @@ -46,7 +49,7 @@ local function locate(head,first,last,ni,nm) insert.prev, first = nil, insert end last, ni = insert, ni + 1 - elseif migrate_marks and id == mark then + elseif migrate_marks and id == mark_code then local mark head, current, mark = remove_nodes(head,current) mark.next = nil @@ -63,20 +66,20 @@ local function locate(head,first,last,ni,nm) return head, first, last, ni, nm end -function nodes.migrate_outwards(head,where) +function nodes.handlers.migrate(head,where) local done = false if head then local current = head while current do local id = current.id - if id == vlist or id == hlist and not has_attribute(current,migrated) then + if id == vlist_code or id == hlist_code and not has_attribute(current,migrated) then set_attribute(current,migrated,1) t_sweeps = t_sweeps + 1 local h = current.list local first, last, ni, nm while h do local id = h.id - if id == vlist or id == hlist then + if id == vlist_code or id == hlist_code then h, first, last, ni, nm = locate(h,first,last,0,0) end h = h.next @@ -103,14 +106,14 @@ end experiments.register("marks.migrate", function(v) if v then - tasks.enableaction("mvlbuilders", "nodes.migrate_outwards") + tasks.enableaction("mvlbuilders", "nodes.handlers.migrate") end migrate_marks = v end) experiments.register("inserts.migrate", function(v) if v then - tasks.enableaction("mvlbuilders", "nodes.migrate_outwards") + tasks.enableaction("mvlbuilders", "nodes.handlers.migrate") end migrate_inserts = v end) diff --git a/tex/context/base/node-pag.lua b/tex/context/base/node-pag.lua index 4bc53c6dd..f5a6f9d93 100644 --- a/tex/context/base/node-pag.lua +++ b/tex/context/base/node-pag.lua @@ -13,7 +13,7 @@ pagebuilders = pagebuilders or { } local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming -local actions = tasks.actions("pagebuilders",5) +local actions = nodes.tasks.actions("pagebuilders",5) local function processor(head,groupcode,size,packtype,maxdepth,direction) starttiming(pagebuilders) diff --git a/tex/context/base/node-par.lua b/tex/context/base/node-par.lua index b5140f7a1..ef387cd55 100644 --- a/tex/context/base/node-par.lua +++ b/tex/context/base/node-par.lua @@ -6,27 +6,37 @@ if not modules then modules = { } end modules ['node-par'] = { license = "see context related readme files" } -parbuilders = parbuilders or { } +local builders, nodes, node = builders, nodes, node + +builders.paragraphs = builders.paragraphs or { } +local parbuilders = builders.paragraphs + parbuilders.constructors = parbuilders.constructors or { } +local constructors = parbuilders.constructors + parbuilders.names = parbuilders.names or { } +local names = parbuilders.names + parbuilders.numbers = parbuilders.numbers or { } -parbuilders.attribute = attributes.numbers['parbuilder'] or 999 +local numbers = parbuilders.numbers -storage.register("parbuilders.names", parbuilders.names, "parbuilders.names") -storage.register("parbuilders.numbers", parbuilders.numbers, "parbuilders.numbers") +local p_attribute = attributes.numbers['parbuilder'] or 999 +parbuilders.attribute = p_attribute -local report_parbuilders = logs.new("parbuilders") +local has_attribute = node.has_attribute +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming -local constructors, names, numbers, p_attribute = parbuilders.constructors, parbuilders.names, parbuilders.numbers, parbuilders.attribute +storage.register("builders/paragraphs/names", names, "builders.paragraphs.names") +storage.register("builders/paragraphs/numbers", numbers, "builders.paragraphs.numbers") -local has_attribute = node.has_attribute -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming +local report_parbuilders = logs.new("parbuilders") local mainconstructor = nil -- not stored in format function parbuilders.register(name,number) - parbuilders.names[number] = name - parbuilders.numbers[name] = number + names[number] = name + numbers[name] = number end function parbuilders.setmain(name) @@ -62,20 +72,20 @@ end -- just for testing -function parbuilders.constructors.default(head,followed_by_display) +function constructors.default(head,followed_by_display) return true -- let tex break end -- also for testing (no surrounding spacing done) -function parbuilders.constructors.oneline(head,followed_by_display) +function constructors.oneline(head,followed_by_display) return node.hpack(head) end -- It makes no sense to have a sequence here as we already have -- pre and post hooks and only one parbuilder makes sense, so no: -- --- local actions = tasks.actions("parbuilders",1) +-- local actions = nodes.tasks.actions("parbuilders",1) -- todo: enable one as main diff --git a/tex/context/base/node-par.mkiv b/tex/context/base/node-par.mkiv index cb53e643d..4db097c92 100644 --- a/tex/context/base/node-par.mkiv +++ b/tex/context/base/node-par.mkiv @@ -40,7 +40,7 @@ \unexpanded\def\defineparbuilder[#1]% {\global\advance\nofparbuilders\plusone - \ctxlua{parbuilders.register("#1",\number\nofparbuilders)}% + \ctxlua{builders.paragraphs.register("#1",\number\nofparbuilders)}% \setxvalue{\??ng:#1}{\attribute\parbuilderattribute\nofparbuilders}} \unexpanded\def\startparbuilder[#1]% @@ -56,7 +56,7 @@ \checkparbuilders} \def\setmainparbuilder[#1]% - {\ctxlua{parbuilders.setmain("#1")}} + {\ctxlua{builders.paragraphs.setmain("#1")}} % no high level interface, after all implementing a linebreaker is not something that % the average user will do @@ -65,8 +65,8 @@ \defineparbuilder[oneline] % just for testing \defineparbuilder[basic] % just for testing -\def\enableparbuilders {\ctxlua{parbuilders.enable ()}} -\def\disableparbuilders{\ctxlua{parbuilders.disable()}} +\def\enableparbuilders {\ctxlua{builders.paragraphs.enable ()}} +\def\disableparbuilders{\ctxlua{builders.paragraphs.disable()}} \def\checkparbuilders % can be more efficient as we don't want to do this to often {\ifcase\attribute\parbuilderattribute diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua index d10d2ebe4..01dfc3352 100644 --- a/tex/context/base/node-pro.lua +++ b/tex/context/base/node-pro.lua @@ -14,12 +14,17 @@ local trace_callbacks = false trackers.register("nodes.callbacks", function(v) local report_nodes = logs.new("nodes") -local glyph = node.id('glyph') +local nodes, node = nodes, node + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local tasks = nodes.tasks local free_node = node.free local first_character = node.first_character nodes.processors = nodes.processors or { } +local processors = nodes.processors -- vbox: grouptype: vbox vtop output split_off split_keep | box_type: exactly|aditional -- hbox: grouptype: hbox adjusted_hbox(=hbox_in_vmode) | box_type: exactly|aditional @@ -33,7 +38,7 @@ local function reconstruct(head) local h = head while h do local id = h.id - if id == glyph then + if id == glyph_code then t[#t+1] = utfchar(h.char) else t[#t+1] = "[]" @@ -57,11 +62,11 @@ local function tracer(what,state,head,groupcode,before,after,show) end end -nodes.processors.tracer = tracer +processors.tracer = tracer -nodes.processors.enabled = true -- thsi will become a proper state (like trackers) +processors.enabled = true -- this will become a proper state (like trackers) -function nodes.processors.pre_linebreak_filter(head,groupcode,size,packtype,direction) +function processors.pre_linebreak_filter(head,groupcode,size,packtype,direction) local first, found = first_character(head) if found then if trace_callbacks then @@ -85,7 +90,7 @@ function nodes.processors.pre_linebreak_filter(head,groupcode,size,packtype,dire return true end -function nodes.processors.hpack_filter(head,groupcode,size,packtype,direction) +function processors.hpack_filter(head,groupcode,size,packtype,direction) local first, found = first_character(head) if found then if trace_callbacks then @@ -109,8 +114,8 @@ function nodes.processors.hpack_filter(head,groupcode,size,packtype,direction) return true end -callbacks.register('pre_linebreak_filter', nodes.processors.pre_linebreak_filter,"all kind of horizontal manipulations (before par break)") -callbacks.register('hpack_filter' , nodes.processors.hpack_filter,"all kind of horizontal manipulations") +callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter,"all kind of horizontal manipulations (before par break)") +callbacks.register('hpack_filter' , processors.hpack_filter,"all kind of horizontal manipulations") local actions = tasks.actions("finalizers",1) -- head, where @@ -119,7 +124,7 @@ local actions = tasks.actions("finalizers",1) -- head, where -- -- beware, much can pass twice, for instance vadjust passes two times -function nodes.processors.post_linebreak_filter(head,groupcode) +function processors.post_linebreak_filter(head,groupcode) --~ local first, found = first_character(head) --~ if found then if trace_callbacks then @@ -143,7 +148,7 @@ function nodes.processors.post_linebreak_filter(head,groupcode) --~ return true end -callbacks.register('post_linebreak_filter', nodes.processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") +callbacks.register('post_linebreak_filter', processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") statistics.register("h-node processing time", function() return statistics.elapsedseconds(nodes,"including kernel") -- hm, ok here? diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 3c0d03f82..2f4575598 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -16,9 +16,16 @@ if not modules then modules = { } end modules ['node-bck'] = { local cleanupreferences, cleanupdestinations = false, true +local attributes, nodes, node = attributes, nodes, node + local nodeinjections = backends.nodeinjections local codeinjections = backends.codeinjections +local transparencies = attributes.transparencies +local colors = attributes.colors +local references = structures.references +local tasks = nodes.tasks + local hpack_list = node.hpack local list_dimensions = node.dimensions @@ -30,19 +37,33 @@ local trace_destinations = false trackers.register("nodes.destinations", functi local report_backends = logs.new("backends") -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes +local whatcodes = nodes.whatcodes +local listcodes = nodes.listcodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glue_code = nodecodes.glue +local whatsit_code = nodecodes.whatsit + +local leftskip_code = skipcodes.leftskip +local rightskip_code = skipcodes.rightskip +local parfillskip_code = skipcodes.parfillskip -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local glue = nodecodes.glue -local whatsit = nodecodes.whatsit +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir -local new_kern = nodes.kern +local line_code = listcodes.line -local has_attribute = node.has_attribute -local traverse = node.traverse -local find_node_tail = node.tail or node.slide -local tosequence = nodes.tosequence +local nodepool = nodes.pool + +local new_kern = nodepool.kern + +local has_attribute = node.has_attribute +local traverse = node.traverse +local find_node_tail = node.tail or node.slide +local tosequence = nodes.tosequence local function dimensions(parent,start,stop) stop = stop and stop.next @@ -115,20 +136,17 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) local width, height, depth, correction = current.width, current.height, current.depth, 0 local moveright = false local first = current.list - if id == hlist then + if id == hlist_code then -- box_code line_code -- can be either an explicit hbox or a line and there is no way -- to recognize this; anyway only if ht/dp (then inline) - -- - -- to be tested: 0=unknown, 1=linebreak, 2=hbox ---~ if id.subtype == 1 then local sr = stack[reference] if first then if sr and sr[2] then local last = find_node_tail(first) - if last.id == glue and last.subtype == 9 then + if last.id == glue_code and last.subtype == rightskip_code then local prev = last.prev - moveright = first.id == glue and first.subtype == 8 - if prev and prev.id == glue and prev.subtype == 15 then + moveright = first.id == glue_code and first.subtype == leftskip_code + if prev and prev.id == glue_code and prev.subtype == parfillskip_code then width = dimensions(current,first,prev.prev) -- maybe not current as we already take care of it else if moveright and first.writable then @@ -142,10 +160,6 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) else -- also weird end ---~ else ---~ print("!!!!!!!!!!!!!!!!!") - -- simple ---~ end else -- ok end @@ -190,14 +204,15 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx while current do local id = current.id local r = has_attribute(current,attribute) - if id == whatsit then + if id == whatsit_code then local subtype = current.subtype - if subtype == 6 then + if subtype == localpar_code then pardir = current.dir - elseif subtype == 7 then + elseif subtype == dir_code then txtdir = current.dir end - elseif id == hlist or id == vlist then +elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left? + elseif id == hlist_code or id == vlist_code then if not reference and r and (not skip or r > skip) then inject_list(id,current,r,make,stack,pardir,txtdir) end @@ -218,7 +233,7 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx reference, first, last, firstdir = r, current, current, txtdir elseif r == reference then last = current - elseif (done[reference] or 0) == 0 then + elseif (done[reference] or 0) == 0 then -- or id == glue_code and current.subtype == right_skip_code if not skip or r > skip then head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) reference, first, last, firstdir = nil, nil, nil, nil @@ -243,14 +258,14 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) while current do local id = current.id local r = has_attribute(current,attribute) - if id == whatsit then + if id == whatsit_code then local subtype = current.subtype - if subtype == 6 then + if subtype == localpar_code then pardir = current.dir - elseif subtype == 7 then + elseif subtype == dir_code then txtdir = current.dir end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then if r and not done[r] then done[r] = true inject_list(id,current,r,make,stack,pardir,txtdir) @@ -268,8 +283,12 @@ end -- tracing -local new_rule = nodes.rule -local new_kern = nodes.kern + +local nodepool = nodes.pool + +local new_rule = nodepool.rule +local new_kern = nodepool.kern + local set_attribute = node.set_attribute local register_color = colors.register @@ -312,7 +331,10 @@ local function colorize(width,height,depth,n) end end -local new_kern = nodes.kern +local nodepool = nodes.pool + +local new_kern = nodepool.kern + local texattribute = tex.attribute local texcount = tex.count @@ -375,7 +397,7 @@ local function makereference(width,height,depth,reference) end end -function nodes.add_references(head) +function nodes.references.handler(head) if topofstack > 0 then return inject_areas(head,attribute,makereference,stack,done) else @@ -445,8 +467,11 @@ local function makedestination(width,height,depth,reference) current = annot end end - result = hpack_list(result,0) - result.width, result.height, result.depth = 0, 0, 0 + if result then + -- some internal error + result = hpack_list(result,0) + result.width, result.height, result.depth = 0, 0, 0 + end if cleanupdestinations then stack[reference] = nil end return result, resolved elseif trace_destinations then @@ -454,7 +479,7 @@ local function makedestination(width,height,depth,reference) end end -function nodes.add_destinations(head) +function nodes.destinations.handler(head) if topofstack > 0 then return inject_area(head,attribute,makedestination,stack,done) -- singular else @@ -464,12 +489,12 @@ end -- will move -function jobreferences.mark(reference,h,d,view) +function references.mark(reference,h,d,view) return setdestination(tex.currentgrouplevel,h,d,reference,view) end -function jobreferences.inject(prefix,reference,h,d,highlight,newwindow,layer) -- todo: use currentreference is possible - local set, bug = jobreferences.identify(prefix,reference) +function references.inject(prefix,reference,h,d,highlight,newwindow,layer) -- todo: use currentreference is possible + local set, bug = references.identify(prefix,reference) if bug or #set == 0 then -- unknown ref, just don't set it and issue an error else @@ -479,8 +504,8 @@ function jobreferences.inject(prefix,reference,h,d,highlight,newwindow,layer) -- end end -function jobreferences.injectcurrentset(h,d) -- used inside doifelse - local currentset = jobreferences.currentset +function references.injectcurrentset(h,d) -- used inside doifelse + local currentset = references.currentset if currentset then setreference(tex.currentgrouplevel,h,d,currentset) -- sets attribute / todo: for set[*].error end @@ -490,11 +515,11 @@ end local function checkboth(open,close) if open and open ~= "" then - local set, bug = jobreferences.identify("",open) + local set, bug = references.identify("",open) open = not bug and #set > 0 and set end if close and close ~= "" then - local set, bug = jobreferences.identify("",close) + local set, bug = references.identify("",close) close = not bug and #set > 0 and set end return open, close @@ -506,24 +531,24 @@ local opendocument, closedocument, openpage, closepage local function check(what) if what and what ~= "" then - local set, bug = jobreferences.identify("",what) + local set, bug = references.identify("",what) return not bug and #set > 0 and set end end -function jobreferences.checkopendocumentactions (open) opendocument = check(open) end -function jobreferences.checkclosedocumentactions(close) closedocument = check(close) end -function jobreferences.checkopenpageactions (open) openpage = check(open) end -function jobreferences.checkclosepageactions (close) closepage = check(close) end +function references.checkopendocumentactions (open) opendocument = check(open) end +function references.checkclosedocumentactions(close) closedocument = check(close) end +function references.checkopenpageactions (open) openpage = check(open) end +function references.checkclosepageactions (close) closepage = check(close) end -function jobreferences.flushdocumentactions() +function references.flushdocumentactions() if opendocument or closedocument then - backends.codeinjections.flushdocumentactions(opendocument,closedocument) -- backend + codeinjections.flushdocumentactions(opendocument,closedocument) -- backend end end -function jobreferences.flushpageactions() +function references.flushpageactions() if openpage or closepage then - backends.codeinjections.flushpageactions(openpage,closepage) -- backend + codeinjections.flushpageactions(openpage,closepage) -- backend end end @@ -537,7 +562,7 @@ statistics.register("interactive elements", function() end end) -function jobreferences.enable_interaction() - tasks.enableaction("shipouts","nodes.add_references") - tasks.enableaction("shipouts","nodes.add_destinations") +function references.enable_interaction() + tasks.enableaction("shipouts","nodes.references.handler") + tasks.enableaction("shipouts","nodes.destinations.handler") end diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua index bafa5e159..ea34f935c 100644 --- a/tex/context/base/node-res.lua +++ b/tex/context/base/node-res.lua @@ -7,20 +7,29 @@ if not modules then modules = { } end modules ['node-res'] = { } local gmatch, format = string.gmatch, string.format -local copy_node, free_node, free_list, new_node, node_type, node_id = node.copy, node.free, node.flush_list, node.new, node.type, node.id local tonumber, round = tonumber, math.round -local glyph_node = node_id("glyph") - --[[ldx-- <p>The next function is not that much needed but in <l n='context'/> we use for debugging <l n='luatex'/> node management.</p> --ldx]]-- -nodes = nodes or { } +local nodes, node = nodes, node + +local copy_node = node.copy +local free_node = node.free +local free_list = node.flush_list +local new_node = node.new +local node_type = node.type + +nodes.pool = nodes.pool or { } +local pool = nodes.pool local whatsitcodes = nodes.whatsitcodes local skipcodes = nodes.skipcodes +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph local reserved = { } @@ -29,9 +38,9 @@ local function register_node(n) return n end -nodes.register = register_node +pool.register = register_node -function nodes.cleanup_reserved(nofboxes) -- todo +function pool.cleanup(nofboxes) -- todo nodes.tracers.steppers.reset() -- todo: make a registration subsystem local nr, nl = #reserved, 0 for i=1,nr do @@ -54,7 +63,7 @@ function nodes.cleanup_reserved(nofboxes) -- todo return nr, nl, nofboxes -- can be nil end -function nodes.usage() +function pool.usage() local t = { } for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do t[tag] = n @@ -68,13 +77,13 @@ local penalty = register_node(new_node("penalty")) local glue = register_node(new_node("glue")) -- glue.spec = nil local glue_spec = register_node(new_node("glue_spec")) local glyph = register_node(new_node("glyph",0)) -local textdir = register_node(new_node("whatsit",whatsitcodes.dir)) -- 7 (6 is local par node) +local textdir = register_node(new_node("whatsit",whatsitcodes.dir)) local rule = register_node(new_node("rule")) -local latelua = register_node(new_node("whatsit",whatsitcodes.late_lua)) -- 35 -local user_n = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_n.type = 100 -- 44 -local user_l = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_l.type = 110 -- 44 -local user_s = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_s.type = 115 -- 44 -local user_t = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_t.type = 116 -- 44 +local latelua = register_node(new_node("whatsit",whatsitcodes.latelua)) +local user_n = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_n.type = 100 -- 44 +local user_l = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_l.type = 110 -- 44 +local user_s = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_s.type = 115 -- 44 +local user_t = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_t.type = 116 -- 44 local left_margin_kern = register_node(new_node("margin_kern",0)) local right_margin_kern = register_node(new_node("margin_kern",1)) local lineskip = register_node(new_node("glue",skipcodes.lineskip)) @@ -84,7 +93,7 @@ local rightskip = register_node(new_node("glue",skipcodes.rightskip)) local temp = register_node(new_node("temp",0)) local noad = register_node(new_node("noad")) -function nodes.zeroglue(n) +function pool.zeroglue(n) local s = n.spec return not writable or ( s.width == 0 @@ -95,26 +104,26 @@ function nodes.zeroglue(n) ) end -function nodes.glyph(fnt,chr) +function pool.glyph(fnt,chr) local n = copy_node(glyph) if fnt then n.font = fnt end if chr then n.char = chr end return n end -function nodes.penalty(p) +function pool.penalty(p) local n = copy_node(penalty) n.penalty = p return n end -function nodes.kern(k) +function pool.kern(k) local n = copy_node(kern) n.kern = k return n end -function nodes.glue_spec(width,stretch,shrink) +function pool.gluespec(width,stretch,shrink) local s = copy_node(glue_spec) s.width, s.stretch, s.shrink = width, stretch, shrink return s @@ -135,33 +144,37 @@ local function someskip(skip,width,stretch,shrink) return n end -function nodes.glue(width,stretch,shrink) +function pool.glue(width,stretch,shrink) return someskip(glue,width,stretch,shrink) end -function nodes.leftskip(width,stretch,shrink) + +function pool.leftskip(width,stretch,shrink) return someskip(leftskip,width,stretch,shrink) end -function nodes.rightskip(width,stretch,shrink) + +function pool.rightskip(width,stretch,shrink) return someskip(rightskip,width,stretch,shrink) end -function nodes.lineskip(width,stretch,shrink) + +function pool.lineskip(width,stretch,shrink) return someskip(lineskip,width,stretch,shrink) end -function nodes.baselineskip(width,stretch,shrink) + +function pool.baselineskip(width,stretch,shrink) return someskip(baselineskip,width,stretch,shrink) end -function nodes.disc() +function pool.disc() return copy_node(disc) end -function nodes.textdir(dir) +function pool.textdir(dir) local t = copy_node(textdir) t.dir = dir return t end -function nodes.rule(width,height,depth,dir) +function pool.rule(width,height,depth,dir) local n = copy_node(rule) if width then n.width = width end if height then n.height = height end @@ -170,17 +183,17 @@ function nodes.rule(width,height,depth,dir) return n end -function nodes.latelua(code) +function pool.latelua(code) local n = copy_node(latelua) n.data = code return n end -function nodes.leftmarginkern(glyph,width) +function pool.leftmarginkern(glyph,width) local n = copy_node(left_margin_kern) if not glyph then logs.fatal("nodes","invalid pointer to left margin glyph node") - elseif glyph.id ~= glyph_node then + elseif glyph.id ~= glyph_code then logs.fatal("nodes","invalid node type %s for left margin glyph node",node_type(glyph)) else n.glyph = glyph @@ -191,11 +204,11 @@ function nodes.leftmarginkern(glyph,width) return n end -function nodes.rightmarginkern(glyph,width) +function pool.rightmarginkern(glyph,width) local n = copy_node(right_margin_kern) if not glyph then logs.fatal("nodes","invalid pointer to right margin glyph node") - elseif glyph.id ~= glyph_node then + elseif glyph.id ~= glyph_code then logs.fatal("nodes","invalid node type %s for right margin glyph node",node_type(p)) else n.glyph = glyph @@ -206,11 +219,11 @@ function nodes.rightmarginkern(glyph,width) return n end -function nodes.temp() +function pool.temp() return copy_node(temp) end -function nodes.noad() +function pool.noad() return copy_node(noad) end @@ -227,7 +240,7 @@ and hide it for the user. And yes, LuaTeX now gives a warning as well.</p> ]]-- -function nodes.writable_spec(n) +function nodes.writable_spec(n) -- not pool local spec = n.spec if not spec then spec = copy_node(glue_spec) @@ -239,51 +252,52 @@ function nodes.writable_spec(n) return spec end -local cache = { } - -function nodes.usernumber(num) - local n = cache[num] - if n then - return copy_node(n) - else - local n = copy_node(user_n) - if num then n.value = num end - return n +function pool.usernumber(id,num) -- if one argument then num + local n = copy_node(user_n) + if num then + n.user_id, n.value = id, num + elseif id then + n.value = id end + return n end -function nodes.userlist(list) +function pool.userlist(id,list) local n = copy_node(user_l) - if list then n.value = list end + if list then + n.user_id, n.value =id, list + else + n.value = id + end return n end -local cache = { } -- we could use the same cache - -function nodes.userstring(str) - local n = cache[str] - if n then - return copy_node(n) +function pool.userstring(id,str) + local n = copy_node(user_s) + if str then + n.user_id, n.value =id, str else - local n = copy_node(user_s) - n.type = 115 - if str then n.value = str end - return n + n.value = id end + return n end -function nodes.usertokens(tokens) +function pool.usertokens(id,tokens) local n = copy_node(user_t) - if tokens then n.value = tokens end + if tokens then + n.user_id, n.value =id, tokens + else + n.value = id + end return n end statistics.register("cleaned up reserved nodes", function() - return format("%s nodes, %s lists of %s", nodes.cleanup_reserved(tex.count["lastallocatedbox"])) + return format("%s nodes, %s lists of %s", pool.cleanup(tex.count["lastallocatedbox"])) end) -- \topofboxstack statistics.register("node memory usage", function() -- comes after cleanup ! return status.node_mem_usage end) -lua.registerfinalizer(nodes.cleanup_reserved, "cleanup reserved nodes") +lua.registerfinalizer(pool.cleanup, "cleanup reserved nodes") diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua index e981b83b4..eb388a6d9 100644 --- a/tex/context/base/node-rul.lua +++ b/tex/context/base/node-rul.lua @@ -11,11 +11,14 @@ if not modules then modules = { } end modules ['node-rul'] = { -- -- todo: make robust for layers ... order matters -local nodecodes = nodes.nodecodes +local attributes, nodes, node = attributes, nodes, node + +local nodecodes = nodes.nodecodes +local tasks = nodes.tasks -local glyph = nodecodes.glyph -local disc = nodecodes.disc -local rule = nodecodes.rule +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local rule_code = nodecodes.rule function nodes.strip_range(first,last) -- todo: dir if first and last then -- just to be sure @@ -24,7 +27,7 @@ function nodes.strip_range(first,last) -- todo: dir end while first and first ~= last do local id = first.id - if id == glyph or id == disc then -- or id == rule + if id == glyph_code or id == disc_code then -- or id == rule_code break else first = first.next @@ -37,7 +40,7 @@ function nodes.strip_range(first,last) -- todo: dir end while last and last ~= first do local id = last.id - if id == glyph or id == disc then -- or id == rule + if id == glyph_code or id == disc_code then -- or id == rule_code break else last = last.prev @@ -67,30 +70,40 @@ local a_colorspace = attributes.private('colormodel') local insert_before, insert_after, strip_range = node.insert_before, node.insert_after, nodes.strip_range local list_dimensions, has_attribute, set_attribute = node.dimensions, node.has_attribute, node.set_attribute local hpack_nodes = node.hpack -local skipcodes, nodecodes = nodes.skipcodes, nodes.nodecodes local dimenfactor = fonts.dimenfactor local texwrite = tex.write local fontdata = fonts.ids local variables = interfaces.variables -local glyph = nodecodes.glyph -local disc = nodecodes.disc -local glue = nodecodes.glue -local penalty = nodecodes.penalty -local kern = nodecodes.kern -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local rule = nodecodes.rule -local whatsit = nodecodes.whatsit +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes +local whatcodes = nodes.whatcodes +local kerncodes = nodes.kerncodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit + +local userskip_code = skipcodes.userskip +local spaceskip_code = skipcodes.spaceskip +local xspaceskip_code = skipcodes.xspaceskip + +local dir_code = whatcodes.dir + +local kerning_code = kerncodes.kern -local userskip = skipcodes.userskip -local spaceskip = skipcodes.spaceskip -local xspaceskip = skipcodes.xspaceskip +local nodepool = nodes.pool -local new_rule = nodes.rule -local new_kern = nodes.kern -local new_glue = nodes.glue +local new_rule = nodepool.rule +local new_kern = nodepool.kern +local new_glue = nodepool.glue -- we can use this one elsewhere too -- @@ -115,7 +128,7 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd local continue, done, strip, level = false, false, true, -1 while n do local id = n.id - if id == glyph or id == rule then + if id == glyph_code or id == rule_code then local aa = has_attribute(n,attribute) if aa then if aa == a then @@ -145,9 +158,9 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd end f, l, a = nil, nil, nil end - elseif f and (id == disc or (id == kern and n.subtype == 0)) then + elseif f and (id == disc_code or (id == kern_code and n.subtype == kerning_code)) then l = n - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then if f then head, done = flush(head,f,l,d,level,parent,strip), true f, l, a = nil, nil, nil @@ -156,21 +169,21 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd if list then n.list = process_words(attribute,data,flush,list,n) end - elseif checkdir and id == whatsit and n.subtype == 7 then -- only changes in dir, we assume proper boundaries + elseif checkdir and id == whatsit_code and n.subtype == dir_code then -- only changes in dir, we assume proper boundaries if f and a then l = n end elseif f then if continue then - if id == penalty then + if id == penalty_code then l = n - elseif id == kern then + elseif id == kern_code then l = n - elseif id == glue then + elseif id == glue_code then -- catch \underbar{a} \underbar{a} (subtype test is needed) local subtype = n.subtype if continue and has_attribute(n,attribute) and - (subtype == userskip or subtype == spaceskip or subskip == xspaceskip) then + (subtype == userskip_code or subtype == spaceskip_code or subskip == xspaceskip_code) then l = n else head, done = flush(head,f,l,d,level,parent,strip), true @@ -213,7 +226,7 @@ local a_viewerlayer = attributes.private("viewerlayer") local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose -- check for f and l - if f.id ~= glyph then + if f.id ~= glyph_code then -- saveguard ... we need to deal with rules and so (math) return head end @@ -286,16 +299,16 @@ end local process = nodes.process_words -nodes.rules.process = function(head) return process(a_ruled,data,flush_ruled,head) end +nodes.rules.handler = function(head) return process(a_ruled,data,flush_ruled,head) end function nodes.rules.enable() - tasks.enableaction("shipouts","nodes.rules.process") + tasks.enableaction("shipouts","nodes.rules.handler") end -- elsewhere: -- --- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process") --- tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used +-- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.handler") +-- tasks.disableaction("shipouts", "nodes.rules.handler") -- only kick in when used local trace_shifted = false trackers.register("nodes.shifted", function(v) trace_shifted = v end) @@ -342,8 +355,8 @@ end local process = nodes.process_words -nodes.shifts.process = function(head) return process(a_shifted,data,flush_shifted,head) end +nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end function nodes.shifts.enable() - tasks.enableaction("shipouts","nodes.shifts.process") + tasks.enableaction("shipouts","nodes.shifts.handler") end diff --git a/tex/context/base/node-ser.lua b/tex/context/base/node-ser.lua index b6e72f9fb..0b8b2212e 100644 --- a/tex/context/base/node-ser.lua +++ b/tex/context/base/node-ser.lua @@ -9,18 +9,20 @@ if not modules then modules = { } end modules ['node-ser'] = { -- beware, some field names will change in a next releases -- of luatex; this is pretty old code that needs an overhaul -local type, format, concat = type, string.format, table.concat +local type, format, concat, rep = type, string.format, table.concat, string.rep local ctxcatcodes = tex.ctxcatcodes +local nodes, node = nodes, node + local traverse = node.traverse local node_fields = node.fields local node_type = node.type -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist local expand = table.tohash { "list", -- list_ptr & ins_ptr & adjust_ptr @@ -241,8 +243,8 @@ function nodes.list(head,n) -- name might change to nodes.type end while head do local id = head.id - tex.print(string.rep(" ",n or 0) .. tostring(head) .. "\n") - if id == hlist or id == vlist then + tex.print(rep(" ",n or 0) .. tostring(head) .. "\n") + if id == hlist_code or id == vlist_code then nodes.list(head.list,(n or 0)+1) end head = head.next @@ -255,8 +257,8 @@ end function nodes.print(head,n) while head do local id = head.id - texio.write_nl(string.rep(" ",n or 0) .. tostring(head)) - if id == hlist or id == vlist then + texio.write_nl(rep(" ",n or 0) .. tostring(head)) + if id == hlist_code or id == vlist_code then nodes.print(head.list,(n or 0)+1) end head = head.next diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua index 1066ab064..e637153dc 100644 --- a/tex/context/base/node-shp.lua +++ b/tex/context/base/node-shp.lua @@ -6,28 +6,32 @@ if not modules then modules = { } end modules ['node-shp'] = { license = "see context related readme files" } -local free_node, remove_node = node.free, node.remove +local nodes, node = nodes, node -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local tasks = nodes.tasks -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local disc = nodecodes.disc -local mark = nodecodes.mark -local kern = nodecodes.kern -local glue = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local mark_code = nodecodes.mark +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue -local function cleanup_page(head) -- rough +local free_node = node.free +local remove_node = node.remove + +local function cleanup(head) -- rough local start = head while start do local id = start.id - if id == disc or (id == glue and not start.writable) or (id == kern and start.kern == 0) or id == mark then + if id == disc_code or (id == glue_code and not start.writable) or (id == kern_code and start.kern == 0) or id == mark_code then head, start, tmp = remove_node(head,start) free_node(tmp) - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then local sl = start.list if sl then - start.list = cleanup_page(sl) + start.list = cleanup(sl) start = start.next else head, start, tmp = remove_node(head,start) @@ -40,20 +44,19 @@ local function cleanup_page(head) -- rough return head end -nodes.cleanup_page_first = false +directives.register("backend.cleanup", function() + tasks.enableaction("shipouts","nodes.handlers.cleanuppage") +end) -function nodes.cleanup_page(head) +function nodes.handlers.cleanuppage(head) -- about 10% of the nodes make no sense for the backend - if nodes.cleanup_page_first then - head = cleanup_page(head) - end - return head, false + return cleanup(head), true end local actions = tasks.actions("shipouts",0) -- no extra arguments -function nodes.process_page(head) -- problem, attr loaded before node, todo ... +function nodes.handlers.finalize(head) -- problem, attr loaded before node, todo ... return actions(head) end ---~ nodes.process_page = actions +--~ nodes.handlers.finalize = actions diff --git a/tex/context/base/node-spl.lua b/tex/context/base/node-spl.lua index de1935a03..db279b73f 100644 --- a/tex/context/base/node-spl.lua +++ b/tex/context/base/node-spl.lua @@ -23,16 +23,19 @@ local next, tostring, tonumber = next, tostring, tonumber local utfchar = utf.char local random = math.random local variables = interfaces.variables +local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash -local trace_split = false trackers.register("parbuilders.solutions.splitters.splitter", function(v) trace_split = v end) -local trace_optimize = false trackers.register("parbuilders.solutions.splitters.optimizer", function(v) trace_optimize = v end) -local trace_colors = false trackers.register("parbuilders.solutions.splitters.colors", function(v) trace_colors = v end) -local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +local trace_split = false trackers.register("builders.paragraphs.solutions.splitters.splitter", function(v) trace_split = v end) +local trace_optimize = false trackers.register("builders.paragraphs.solutions.splitters.optimizer", function(v) trace_optimize = v end) +local trace_colors = false trackers.register("builders.paragraphs.solutions.splitters.colors", function(v) trace_colors = v end) +local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) local report_fonts = logs.new("fonts") local report_splitter = logs.new("splitter") local report_optimizer = logs.new("optimizer") +local nodes, node = nodes, node + local find_node_tail = node.tail or node.slide local free_node = node.free local free_nodelist = node.flush_list @@ -43,29 +46,38 @@ local copy_node = node.copy local copy_nodelist = node.copy_list local traverse_nodes = node.traverse local traverse_ids = node.traverse_id -local protect_nodes = node.protect_glyphs +local protect_glyphs = nodes.handlers.protectglyphs or node.protect_glyphs local hpack_nodes = node.hpack local insert_node_before = node.insert_before local insert_node_after = node.insert_after local repack_hlist = nodes.repack_hlist -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local hlist_code = nodecodes.hlist +local whatsit_code = nodecodes.whatsit + +local localpar_code = whatsitcodes.localpar +local dir_code = whatsitcodes.dir +local userdefined_code = whatsitcodes.userdefined -local glyph = nodecodes.glyph -local glue = nodecodes.glue -local kern = nodecodes.kern -local disc = nodecodes.disc -local hlist = nodecodes.hlist -local whatsit = nodecodes.whatsit +local nodepool = nodes.pool +local tasks = nodes.tasks + +local new_textdir = nodepool.textdir +local new_usernumber = nodepool.usernumber local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming - -local process_characters = nodes.process_characters -local inject_kerns = nodes.inject_kerns +local process_characters = nodes.handlers.characters +local inject_kerns = nodes.handlers.injectkerns local set_dynamics = fonts.otf.set_dynamics local fontdata = fonts.ids +local parbuilders = builders.paragraphs parbuilders.solutions = parbuilders.solutions or { } parbuilders.solutions.splitters = parbuilders.solutions.splitters or { } @@ -84,7 +96,7 @@ local randomseed = nil local optimize = nil -- set later function splitters.setup(setups) - local method = aux.settings_to_hash(setups.method or "") + local method = settings_to_hash(setups.method or "") if method[variables.preroll] then preroll = true else @@ -144,11 +156,11 @@ fonts.goodies.register("solutions",initialize) function splitters.define(name,parameters) local setups = fonts.define.specify.context_setups - local settings = aux.settings_to_hash(parameters) -- todo: interfacing + local settings = settings_to_hash(parameters) -- todo: interfacing local goodies, solution, less, more = settings.goodies, settings.solution, settings.less, settings.more local less_set, more_set - local l = less and aux.settings_to_array(less) - local m = more and aux.settings_to_array(more) + local l = less and settings_to_array(less) + local m = more and settings_to_array(more) if goodies then goodies = fonts.goodies.get(goodies) -- also in tfmdata if goodies then @@ -196,10 +208,6 @@ function splitters.define(name,parameters) tex.write(#solutions) end -local user_node_one = nodes.register(new_node("whatsit",44)) user_node_one.user_id, user_node_one.type = 1, 100 -local user_node_two = nodes.register(new_node("whatsit",44)) user_node_two.user_id, user_node_two.type = 2, 100 -local text_node_trt = nodes.register(new_node("whatsit", 7)) text_node_trt.dir = "+TRT" - local fcs = (fonts.color and fonts.color.set) or function() end local nofwords, noftries, nofadapted, nofkept, nofparagraphs = 0, 0, 0, 0, 0 @@ -213,13 +221,12 @@ function splitters.split(head) local last = stop.next local list = last and copy_nodelist(start,last) or copy_nodelist(start) local n = #cache + 1 - local user_one = copy_node(user_node_one) - local user_two = copy_node(user_node_two) - user_one.value, user_two.value = n, n + local user_one = new_usernumber(1,n) + local user_two = new_usernumber(2,n) head, start = insert_node_before(head,start,user_one) insert_node_after(head,stop,user_two) if rlmode == "TRT" or rlmode == "+TRT" then - local dirnode = copy_node(text_node_trt) + local dirnode = new_textdir("+TRT") list.prev = dirnode dirnode.next = list list = dirnode @@ -243,7 +250,7 @@ function splitters.split(head) end while current do local id = current.id - if id == glyph and current.subtype < 255 then + if id == glyph_code and current.subtype < 256 then local a = has_attribute(current,split) if not a then start, stop = nil, nil @@ -255,14 +262,14 @@ function splitters.split(head) stop = current end current = current.next - elseif id == disc then + elseif id == disc_code then start, stop, current = nil, nil, current.next - elseif id == whatsit then + elseif id == whatsit_code then if start then flush() end local subtype = current.subtype - if subtype == 7 or subtype == 6 then + if subtype == dir_code or subtype == localpar_code then rlmode = current.dir end current = current.next @@ -283,8 +290,8 @@ end local function collect_words(list) local words, word = { }, nil - for current in traverse_ids(whatsit,list) do - if current.subtype == 44 then + for current in traverse_ids(whatsit_code,list) do + if current.subtype == userdefined_code then local user_id = current.user_id if user_id == 1 then word = { current.value, current, current } @@ -344,7 +351,7 @@ local function doit(word,list,best,width,badness,line,set,listdir) first = inject_kerns(first) local h = word[2].next -- head of current word local t = word[3].prev -- tail of current word - if first.id == whatsit then + if first.id == whatsit_code then local temp = first first = first.next free_node(temp) @@ -478,7 +485,7 @@ function splitters.optimize(head) report_optimizer("preroll: %s, variant: %s, preroll criterium: %s, cache size: %s", tostring(preroll),variant,criterium,nc) end - for current in traverse_ids(hlist,head) do + for current in traverse_ids(hlist_code,head) do -- report_splitter("before: [%s] => %s",current.dir,nodes.tosequence(current.list,nil)) line = line + 1 local sign, dir, list, width = current.glue_sign, current.dir, current.list, current.width @@ -546,7 +553,7 @@ function splitters.optimize(head) end if done then if b <= criterium then -- was == 0 - protect_nodes(list) + protect_glyphs(list) break end end @@ -581,11 +588,11 @@ statistics.register("optimizer statistics", function() end) function splitters.enable() - tasks.enableaction("processors", "parbuilders.solutions.splitters.split") - tasks.enableaction("finalizers", "parbuilders.solutions.splitters.optimize") + tasks.enableaction("processors", "builders.paragraphs.solutions.splitters.split") + tasks.enableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") end function splitters.disable() - tasks.disableaction("processors", "parbuilders.solutions.splitters.split") - tasks.disableaction("finalizers", "parbuilders.solutions.splitters.optimize") + tasks.disableaction("processors", "builders.paragraphs.solutions.splitters.split") + tasks.disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") end diff --git a/tex/context/base/node-spl.mkiv b/tex/context/base/node-spl.mkiv index af98f45c7..062ce35fe 100644 --- a/tex/context/base/node-spl.mkiv +++ b/tex/context/base/node-spl.mkiv @@ -82,14 +82,14 @@ {\dodoubleargument\dodefinefontsolution} \def\dodefinefontsolution[#1][#2]% we could set the attribute at the lua end - {\setxvalue{\??fu:#1}{\attribute\splitterattribute\ctxlua{parbuilders.solutions.splitters.define("#1","#2")}\relax}} + {\setxvalue{\??fu:#1}{\attribute\splitterattribute\ctxlua{builders.paragraphs.solutions.splitters.define("#1","#2")}\relax}} \unexpanded\def\setfontsolution[#1]% - {\ctxlua{parbuilders.solutions.splitters.enable()}% + {\ctxlua{builders.paragraphs.solutions.splitters.enable()}% \csname\??fu:#1\endcsname} \unexpanded\def\resetfontsolution - {\ctxlua{parbuilders.solutions.splitters.disable()}% + {\ctxlua{builders.paragraphs.solutions.splitters.disable()}% \attribute\splitterattribute\attributeunsetvalue} \letvalue{\??fu:\v!reset}\resetfontsolution @@ -99,7 +99,7 @@ \the\everysetupfontsolutions} \appendtoks - \ctxlua{parbuilders.solutions.splitters.setup { + \ctxlua{builders.paragraphs.solutions.splitters.setup { method = "\@@fumethod", criterium = "\@@fucriterium", }}% diff --git a/tex/context/base/node-tex.lua b/tex/context/base/node-tex.lua index a6eef3269..2170e0603 100644 --- a/tex/context/base/node-tex.lua +++ b/tex/context/base/node-tex.lua @@ -8,7 +8,9 @@ if not modules then modules = { } end modules ['node-tex'] = { local format = string.format -kernel = kernel or { } +builders = builders or { } +builders.kernel = builders.kernel or { } +local kernel = builders.kernel local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming local hyphenate, ligaturing, kerning = lang.hyphenate, node.ligaturing, node.kerning diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 5134611c4..16829a1e5 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -14,22 +14,35 @@ might become a runtime module instead. This module will be cleaned up!</p> local utfchar = utf.char local concat = table.concat local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes local report_nodes = logs.new("nodes") -fonts = fonts or { } +fonts = fonts or { } +nodes = nodes or { } + +local fonts, nodes, node = fonts, nodes, node + fonts.tfm = fonts.tfm or { } fonts.ids = fonts.ids or { } fonts.chr = fonts.chr or { } -nodes = nodes or { } -nodes.tracers = nodes.tracers or { } -nodes.tracers.characters = nodes.tracers.characters or { } -nodes.tracers.steppers = nodes.tracers.steppers or { } +nodes.tracers = nodes.tracers or { } +local tracers = nodes.tracers + +nodes.tasks = nodes.tasks or { } +local tasks = nodes.tasks + +nodes.handlers = nodes.handlers or { } +local handlers = nodes.handlers + +tracers.characters = tracers.characters or { } +tracers.steppers = tracers.steppers or { } -local tracers = nodes.tracers +local char_tracers = tracers.characters +local step_tracers = tracers.steppers local copy_node_list = node.copy_list local hpack_node_list = node.hpack @@ -38,26 +51,38 @@ local first_character = node.first_character local node_type = node.type local traverse_nodes = node.traverse -local texsprint = tex.sprint -local fontdata = fonts.ids -local fontchar = fonts.chr -local nodecodes = nodes.nodecodes - -local glyph = nodecodes.glyph -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local disc = nodecodes.disc -local glue = nodecodes.glue -local kern = nodecodes.kern -local rule = nodecodes.rule -local whatsit = nodecodes.whatsit - -function tracers.characters.collect(head,list,tag,n) +local texsprint = tex.sprint +local fontdata = fonts.ids +local fontchar = fonts.chr + +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local skipcodes = nodes.skipcodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit + +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir + +local userskip_code = skipcodes.userskip + +local nodepool = nodes.pool + +local new_glyph = nodepool.glyph + +function char_tracers.collect(head,list,tag,n) n = n or 0 local ok, fn = false, nil while head do local id = head.id - if id == glyph then + if id == glyph_code then local f = head.font if f ~= fn then ok, fn = false, f @@ -72,7 +97,7 @@ function tracers.characters.collect(head,list,tag,n) end local l = list[n][tag] l[#l+1] = { c, f, i } - elseif id == disc then + elseif id == disc_code then -- skip else ok = false @@ -81,7 +106,7 @@ function tracers.characters.collect(head,list,tag,n) end end -function tracers.characters.equal(ta, tb) +function char_tracers.equal(ta, tb) if #ta ~= #tb then return false else @@ -95,7 +120,7 @@ function tracers.characters.equal(ta, tb) return true end -function tracers.characters.string(t) +function char_tracers.string(t) local tt = { } for i=1,#t do tt[i] = utfchar(t[i][1]) @@ -103,7 +128,7 @@ function tracers.characters.string(t) return concat(tt,"") end -function tracers.characters.unicodes(t,decimal) +function char_tracers.unicodes(t,decimal) local tt = { } for i=1,#t do local n = t[i][1] @@ -118,7 +143,7 @@ function tracers.characters.unicodes(t,decimal) return concat(tt," ") end -function tracers.characters.indices(t,decimal) +function char_tracers.indices(t,decimal) local tt = { } for i=1,#t do local n = t[i][3] @@ -133,20 +158,20 @@ function tracers.characters.indices(t,decimal) return concat(tt," ") end -function tracers.characters.start() - local npc = nodes.process_characters +function char_tracers.start() + local npc = handlers.characters local list = { } - function nodes.process_characters(head) + function handlers.characters(head) local n = #list - tracers.characters.collect(head,list,'before',n) + char_tracers.collect(head,list,'before',n) local h, d = npc(head) - tracers.characters.collect(head,list,'after',n) + char_tracers.collect(head,list,'after',n) if #list > n then list[#list+1] = { } end return h, d end - function tracers.characters.stop() + function char_tracers.stop() tracers.list['characters'] = list local variables = { ['title'] = 'ConTeXt Character Processing Information', @@ -154,7 +179,7 @@ function tracers.characters.start() ['color-background-two'] = lmx.get('color-background-purple'), } lmx.show('context-characters.lmx',variables) - nodes.process_characters = npc + handlers.characters = npc tasks.restart("processors", "characters") end tasks.restart("processors", "characters") @@ -181,15 +206,15 @@ end local collection, collecting, messages = { }, false, { } -function tracers.steppers.start() +function step_tracers.start() collecting = true end -function tracers.steppers.stop() +function step_tracers.stop() collecting = false end -function tracers.steppers.reset() +function step_tracers.reset() for i=1,#collection do local c = collection[i] if c then @@ -199,23 +224,23 @@ function tracers.steppers.reset() collection, messages = { }, { } end -function tracers.steppers.nofsteps() +function step_tracers.nofsteps() return tex.write(#collection) end -function tracers.steppers.glyphs(n,i) +function step_tracers.glyphs(n,i) local c = collection[i] if c then tex.box[n] = hpack_node_list(copy_node_list(c)) end end -function tracers.steppers.features() +function step_tracers.features() -- local f = first_character(collection[1]) -- if f then -- something fishy with first_character local f = collection[1] while f do - if f.id == glyph then + if f.id == glyph_code then local tfmdata, t = fontdata[f.font], { } for feature, value in table.sortedhash(tfmdata.shared.features) do if feature == "number" or feature == "features" then @@ -242,22 +267,22 @@ function tracers.steppers.features() end function tracers.fontchar(font,char) - local n = nodes.glyph() + local n = new_glyph() n.font, n.char, n.subtype = font, char, 256 node.write(n) end -function tracers.steppers.codes(i,command) +function step_tracers.codes(i,command) local c = collection[i] while c do local id = c.id - if id == glyph then + if id == glyph_code then if command then texsprint(ctxcatcodes,format("%s{%s}{%s}",command,c.font,c.char)) else texsprint(ctxcatcodes,format("[%s:U+%04X]",c.font,c.char)) end - elseif id == whatsit and (c.subtype == 6 or c.subtype == 7) then + elseif id == whatsit_code and (c.subtype == localpar_code or c.subtype == dir_code) then texsprint(ctxcatcodes,format("[%s]",c.dir)) else texsprint(ctxcatcodes,format("[%s]",node_type(id))) @@ -266,7 +291,7 @@ function tracers.steppers.codes(i,command) end end -function tracers.steppers.messages(i,command,split) +function step_tracers.messages(i,command,split) local list = messages[i] -- or { "no messages" } if list then for i=1,#list do @@ -283,29 +308,29 @@ end -- hooks into the node list processor (see otf) -function tracers.steppers.check(head) +function step_tracers.check(head) if collecting then - tracers.steppers.reset() + step_tracers.reset() local n = copy_node_list(head) - nodes.inject_kerns(n,nil,"trace",true) - nodes.protect_glyphs(n) -- can be option + handlers.injectkerns(n,nil,"trace",true) + handlers.protectglyphs(n) -- can be option collection[1] = n end end -function tracers.steppers.register(head) +function step_tracers.register(head) if collecting then local nc = #collection+1 if messages[nc] then local n = copy_node_list(head) - nodes.inject_kerns(n,nil,"trace",true) - nodes.protect_glyphs(n) -- can be option + handlers.injectkerns(n,nil,"trace",true) + handlers.protectglyphs(n) -- can be option collection[nc] = n end end end -function tracers.steppers.message(str,...) +function step_tracers.message(str,...) str = format(str,...) if collecting then local n = #collection + 1 @@ -329,7 +354,7 @@ end function nodes.check_glyphs(head,message) local t = { } - for g in traverse_id(glyph,head) do + for g in traverse_id(glyph_code,head) do t[#t+1] = format("U+%04X:%s",g.char,g.subtype) end if #t > 0 then @@ -343,7 +368,7 @@ local function tosequence(start,stop,compact) local t = { } while start do local id = start.id - if id == glyph then + if id == glyph_code then local c = start.char if compact then if start.components then @@ -354,9 +379,9 @@ local function tosequence(start,stop,compact) else t[#t+1] = format("U+%04X:%s",c,utfchar(c)) end - elseif id == whatsit and start.subtype == 6 or start.subtype == 7 then + elseif id == whatsit_code and start.subtype == localpar_code or start.subtype == dir_code then t[#t+1] = "[" .. start.dir .. "]" - elseif id == rule then + elseif id == rule_code then if compact then t[#t+1] = "|" else @@ -448,7 +473,7 @@ local function show_simple_list(h,depth,n) texio.write_nl(rep(" ",n) .. tostring(h)) if not depth or n < depth then local id = h.id - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then show_simple_list(h.list,depth,n+1) end end @@ -470,7 +495,7 @@ function nodes.list_to_utf(h,joiner) local joiner = (joiner ==true and utfchar(0x200C)) or joiner -- zwnj local w = { } while h do - if h.id == glyph then -- always true + if h.id == glyph_code then -- always true w[#w+1] = utfchar(h.char) if joiner then w[#w+1] = joiner @@ -489,7 +514,7 @@ local function show_boxes(n,symbol,depth) depth, symbol = depth or 0, symbol or "." for n in traverse_nodes(n) do local id = n.id - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then local s = n.subtype logs.simple(rep(symbol,depth) .. what[s] or s) show_boxes(n.list,symbol,depth+1) @@ -501,10 +526,10 @@ nodes.show_boxes = show_boxes local threshold = 65536 -function toutf(list,result) +local function toutf(list,result) for n in traverse_nodes(list) do local id = n.id - if id == glyph then + if id == glyph_code then local c = n.char local fc = fontchar[n.font] if fc then @@ -519,14 +544,21 @@ function toutf(list,result) else result[#result+1] = utfchar(c) end - elseif id == disc then + elseif id == disc_code then toutf(n.replace,result) - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then + if #result > 0 and result[#result] ~= " " then + result[#result+1] = " " + end toutf(n.list,result) - elseif id == glue and n.subtype == 0 and n.spec.width > threshold then - result[#result+1] = " " - elseif id == kern and n.kern > threshold then - result[#result+1] = " " + elseif id == glue_code and n.subtype == userskip_code and n.spec.width > threshold then + if #result > 0 and result[#result] ~= " " then + result[#result+1] = " " + end + elseif id == kern_code and n.kern > threshold then + if #result > 0 and result[#result] ~= " " then + result[#result+1] = " " + end end end return result @@ -535,3 +567,14 @@ end function nodes.toutf(list) return concat(toutf(list,{})) end + +-- might move elsewhere + +local factor = number.dimenfactors.pt +local stripper = lpeg.patterns.strip_zeros + +local points = function(n) + return lpegmatch(stripper,format("%.5fpt",n*factor)) +end + +number.points = points diff --git a/tex/context/base/node-tsk.lua b/tex/context/base/node-tsk.lua index b47bceef1..0b2e16b92 100644 --- a/tex/context/base/node-tsk.lua +++ b/tex/context/base/node-tsk.lua @@ -12,84 +12,90 @@ local trace_tasks = false trackers.register("tasks.creation", function(v) trace local report_tasks = logs.new("tasks") -tasks = tasks or { } -tasks.data = tasks.data or { } +local nodes = nodes + +nodes.tasks = nodes.tasks or { } +local tasks = nodes.tasks +tasks.data = tasks.data or { } +local tasksdata = tasks.data + +local sequencers = utilities.sequencers function tasks.new(name,list) - local tasklist = sequencer.reset() - tasks.data[name] = { list = tasklist, runner = false } + local tasklist = sequencers.reset() + tasksdata[name] = { list = tasklist, runner = false } for l=1,#list do - sequencer.appendgroup(tasklist,list[l]) + sequencers.appendgroup(tasklist,list[l]) end end function tasks.restart(name) - local data = tasks.data[name] + local data = tasksdata[name] if data then data.runner = false end end function tasks.enableaction(name,action) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.enableaction(data.list,action) + sequencers.enableaction(data.list,action) data.runner = false end end function tasks.disableaction(name,action) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.disableaction(data.list,action) + sequencers.disableaction(data.list,action) data.runner = false end end function tasks.enablegroup(name,group) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.enablegroup(data.list,group) + sequencers.enablegroup(data.list,group) data.runner = false end end function tasks.disablegroup(name,group) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.disablegroup(data.list,group) + sequencers.disablegroup(data.list,group) data.runner = false end end function tasks.appendaction(name,group,action,where,kind) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.appendaction(data.list,group,action,where,kind) + sequencers.appendaction(data.list,group,action,where,kind) data.runner = false end end function tasks.prependaction(name,group,action,where,kind) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.prependaction(data.list,group,action,where,kind) + sequencers.prependaction(data.list,group,action,where,kind) data.runner = false end end function tasks.removeaction(name,group,action) - local data = tasks.data[name] + local data = tasksdata[name] if data then - sequencer.removeaction(data.list,group,action) + sequencers.removeaction(data.list,group,action) data.runner = false end end function tasks.showactions(name,group,action,where,kind) - local data = tasks.data[name] + local data = tasksdata[name] if data then - report_tasks("task %s, list:\n%s",name,sequencer.nodeprocessor(data.list)) + report_tasks("task %s, list:\n%s",name,sequencers.nodeprocessor(data.list)) end end @@ -102,16 +108,16 @@ local created, total = 0, 0 statistics.register("node list callback tasks", function() if total > 0 then - return string.format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasks.data),created,total) + return string.format("%s unique task lists, %s instances (re)created, %s calls",table.count(tasksdata),created,total) else return nil end end) -local compile, nodeprocessor = sequencer.compile, sequencer.nodeprocessor +local compile, nodeprocessor = sequencers.compile, sequencers.nodeprocessor function tasks.actions(name,n) -- we optimize for the number or arguments (no ...) - local data = tasks.data[name] + local data = tasksdata[name] if data then if n == 0 then return function(head) @@ -218,7 +224,7 @@ function tasks.actions(name,n) -- we optimize for the number or arguments (no .. end function tasks.table(name) --maybe move this to task-deb.lua - local tsk = tasks.data[name] + local tsk = tasksdata[name] local lst = tsk and tsk.list local HL, NC, NR, bold, type = context.HL, context.NC, context.NR, context.bold, context.type if lst then diff --git a/tex/context/base/node-tst.lua b/tex/context/base/node-tst.lua index c7e79c48f..c3b555b20 100644 --- a/tex/context/base/node-tst.lua +++ b/tex/context/base/node-tst.lua @@ -6,30 +6,34 @@ if not modules then modules = { } end modules ['node-tst'] = { license = "see context related readme files" } -local find_node_tail = node.tail or node.slide +local nodes, node = nodes, node -local chardata = characters.data -local nodecodes = nodes.nodecodes +local chardata = characters.data +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes -local glue = nodecodes.glue -local penalty = nodecodes.penalty -local kern = nodecodes.kern -local glyph = nodecodes.glyph -local whatsit = nodecodes.whatsit -local hlist = nodecodes.hlist +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local glyph_code = nodecodes.glyph +local whatsit_code = nodecodes.whatsit +local hlist_code = nodecodes.hlist + +local leftskip_code = skipcodes.leftskip +local rightskip_code = skipcodes.rightskip +local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip +local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip + +local find_node_tail = node.tail or node.slide function nodes.the_left_margin(n) -- todo: three values while n do local id = n.id - if id == glue then - if n.subtype == 8 then -- 7 in c/web source - return n.spec.width - else - return 0 - end - elseif id == whatsit then + if id == glue_code then + return n.subtype == leftskip_code and n.spec.width or 0 + elseif id == whatsit_code then n = n.next - elseif id == hlist then + elseif id == hlist_code then return n.width else break @@ -43,13 +47,9 @@ function nodes.the_right_margin(n) n = find_node_tail(n) while n do local id = n.id - if id == glue then - if n.subtype == 9 then -- 8 in the c/web source - return n.spec.width - else - return 0 - end - elseif id == whatsit then + if id == glue_code then + return n.subtype == rightskip_code and n.spec.width or 0 + elseif id == whatsit_code then n = n.prev else break @@ -62,14 +62,14 @@ end function nodes.somespace(n,all) if n then local id = n.id - if id == glue then - return (all or (n.spec.width ~= 0)) and glue - elseif id == kern then + if id == glue_code then + return (all or (n.spec.width ~= 0)) and glue_code + elseif id == kern_code then return (all or (n.kern ~= 0)) and kern - elseif id == glyph then + elseif id == glyph_code then local category = chardata[n.char].category -- maybe more category checks are needed - return (category == "zs") and glyph + return (category == "zs") and glyph_code end end return false @@ -78,7 +78,7 @@ end function nodes.somepenalty(n,value) if n then local id = n.id - if id == penalty then + if id == penalty_code then if value then return n.penalty == value else @@ -93,9 +93,9 @@ function nodes.is_display_math(head) local n = head.prev while n do local id = n.id - if id == penalty then - elseif id == glue then - if n.subtype == 6 then -- above_display_short_skip + if id == penalty_code then + elseif id == glue_code then + if n.subtype == abovedisplayshortskip_code then return true end else @@ -106,9 +106,9 @@ function nodes.is_display_math(head) n = head.next while n do local id = n.id - if id == penalty then - elseif id == glue then - if n.subtype == 7 then -- below_display_short_skip + if id == penalty_code then + elseif id == glue_code then + if n.subtype == belowdisplayshortskip_code then return true end else diff --git a/tex/context/base/node-typ.lua b/tex/context/base/node-typ.lua index b807e6aae..684fc94ba 100644 --- a/tex/context/base/node-typ.lua +++ b/tex/context/base/node-typ.lua @@ -6,14 +6,19 @@ if not modules then modules = { } end modules ['node-typ'] = { license = "see context related readme files" } --- this will be replaced by blob-ini cum suis so typesetting will go away +-- this will be replaced by blob-ini cum suis so typesetters will go away local utfvalues = string.utfvalues -local newglyph, newglue = nodes.glyph, nodes.glue -local hpack, vpack = node.hpack, node.vpack +local hpack = node.hpack +local vpack = node.vpack -typesetting = typesetting or { } +local nodepool = nodes.pool + +local new_glyph = nodepool.glyph +local new_glue = nodepool.glue + +typesetters = typesetters or { } local function tonodes(str,fontid,spacing) -- don't use this local head, prev = nil, nil @@ -35,17 +40,17 @@ local function tonodes(str,fontid,spacing) -- don't use this return head end -typesetting.tonodes = tonodes +typesetters.tonodes = tonodes -function typesetting.hpack(str,fontid,spacing) +function typesetters.hpack(str,fontid,spacing) return hpack(tonodes(str,fontid,spacing)) end -function typesetting.vpack(str,fontid,spacing) +function typesetters.vpack(str,fontid,spacing) -- vpack is just a hack, and a proper implentation is on the agenda -- as it needs more info etc than currently available return vpack(tonodes(str,fontid,spacing)) end ---~ node.write(typesetting.hpack("Hello World!")) ---~ node.write(typesetting.hpack("Hello World!",1,100*1024*10)) +--~ node.write(typesetters.hpack("Hello World!")) +--~ node.write(typesetters.hpack("Hello World!",1,100*1024*10)) diff --git a/tex/context/base/pack-box.mkii b/tex/context/base/pack-box.mkii index 8adeedb91..f27d8b4fd 100644 --- a/tex/context/base/pack-box.mkii +++ b/tex/context/base/pack-box.mkii @@ -447,7 +447,6 @@ \def\bleed {\dosingleempty\dobleed} - \def\bleedwidth {\the\hsize}% \def\bleedheight{\the\vsize}% @@ -478,12 +477,13 @@ rt=>\!!donebtrue\!!donectrue]% \doifelse\@@bgstretch\v!yes\donetrue\donefalse \scratchdimen\@@bgwidth + \edef\currentbgposition {\??bg:\number\nofbleeds}% + \edef\currentpageposition{page:0}% todo: per page \ifdone \if!!donea - \advance\scratchdimen\MPx{\??bg:\number\nofbleeds}% + \advance\scratchdimen\dimexpr \MPx\currentbgposition-\MPx\currentpageposition\relax \else\if!!doneb - \scratchdimen\paperwidth - \advance\scratchdimen-\MPx{\??bg:\number\nofbleeds}% + \scratchdimen\dimexpr\paperwidth-\MPx\currentbgposition-\MPx\currentpageposition\relax % not checked \fi\fi \fi \advance\scratchdimen\@@bghoffset @@ -491,10 +491,9 @@ \scratchdimen\@@bgheight \ifdone \if!!donec - \scratchdimen\paperheight - \advance\scratchdimen-\MPy{\??bg:\number\nofbleeds}% + \scratchdimen\dimexpr\paperheight-\MPy\currentbgposition-\MPy\currentpageposition\relax % not checked \else\if!!doned - \advance\scratchdimen\MPy{\??bg:\number\nofbleeds}% + \advance\scratchdimen\dimexpr \MPy\currentbgposition-\MPy\currentpageposition\relax % not checked \fi\fi \fi \advance\scratchdimen\@@bgvoffset @@ -514,7 +513,7 @@ \ht\scratchbox\@@bgheight \dp\scratchbox\zeropoint \ifdone - \hpos{\??bg:\number\nofbleeds}{\box\scratchbox}% + \hpos\currentbgposition{\box\scratchbox}% \else \box\scratchbox \fi diff --git a/tex/context/base/pack-box.mkiv b/tex/context/base/pack-box.mkiv index 6cb492aa6..2c25f5c3a 100644 --- a/tex/context/base/pack-box.mkiv +++ b/tex/context/base/pack-box.mkiv @@ -443,10 +443,9 @@ \c!voffset=\@@bgoffset, \c!hoffset=\@@bgoffset] -\def\bleed +\unexpanded\def\bleed {\dosingleempty\dobleed} - \def\bleedwidth {\the\hsize}% \def\bleedheight{\the\vsize}% @@ -477,12 +476,13 @@ rt=>\!!donebtrue\!!donectrue]% \doifelse\@@bgstretch\v!yes\donetrue\donefalse \scratchdimen\@@bgwidth + \edef\currentbgposition {\??bg:\number\nofbleeds}% + \edef\currentpageposition{page:0}% todo: per page \ifdone \if!!donea - \advance\scratchdimen\MPx{\??bg:\number\nofbleeds}% + \advance\scratchdimen\dimexpr \MPx\currentbgposition-\MPx\currentpageposition\relax \else\if!!doneb - \scratchdimen\paperwidth - \advance\scratchdimen-\MPx{\??bg:\number\nofbleeds}% + \scratchdimen\dimexpr\paperwidth-\MPx\currentbgposition-\MPx\currentpageposition\relax % not checked \fi\fi \fi \advance\scratchdimen\@@bghoffset @@ -490,10 +490,9 @@ \scratchdimen\@@bgheight \ifdone \if!!donec - \scratchdimen\paperheight - \advance\scratchdimen-\MPy{\??bg:\number\nofbleeds}% + \scratchdimen\dimexpr\paperheight-\MPy\currentbgposition-\MPy\currentpageposition\relax % not checked \else\if!!doned - \advance\scratchdimen\MPy{\??bg:\number\nofbleeds}% + \advance\scratchdimen\dimexpr \MPy\currentbgposition-\MPy\currentpageposition\relax % not checked \fi\fi \fi \advance\scratchdimen\@@bgvoffset @@ -513,7 +512,7 @@ \ht\scratchbox\@@bgheight \dp\scratchbox\zeropoint \ifdone - \hpos{\??bg:\number\nofbleeds}{\box\scratchbox}% + \hpos\currentbgposition{\box\scratchbox}% \else \box\scratchbox \fi @@ -521,7 +520,7 @@ \setupbleeding[\c!stretch=\v!yes] -\defineexternalfigure[bleed][\c!width=\bleedwidth,\c!height=\bleedheight] +\defineexternalfigure[bleed][\c!width=\bleedwidth,\c!height=\bleedheight] % should be \v!bleed % \placefigure[left]{none} % {\bleed[width=5cm,height=3cm,location=lt]{\externalfigure[koe][bleed]}} diff --git a/tex/context/base/pack-obj.lua b/tex/context/base/pack-obj.lua index 0ee46fc99..07ba6da31 100644 --- a/tex/context/base/pack-obj.lua +++ b/tex/context/base/pack-obj.lua @@ -13,9 +13,12 @@ reusable components.</p> local texsprint, texcount = tex.sprint, tex.count -jobobjects = jobobjects or { } -jobobjects.collected = jobobjects.collected or { } -jobobjects.tobesaved = jobobjects.tobesaved or { } +local jobobjects = { + collected = { }, + tobesaved = { }, +} + +job.objects = jobobjects local collected, tobesaved = jobobjects.collected, jobobjects.tobesaved @@ -23,7 +26,7 @@ local function initializer() collected, tobesaved = jobobjects.collected, jobobjects.tobesaved end -job.register('jobobjects.collected', jobobjects.tobesaved, initializer, nil) +job.register('job.objects.collected', jobobjects.tobesaved, initializer, nil) function jobobjects.save(tag,number,page) local t = { number, page } diff --git a/tex/context/base/pack-obj.mkiv b/tex/context/base/pack-obj.mkiv index 81220e324..682dc02ff 100644 --- a/tex/context/base/pack-obj.mkiv +++ b/tex/context/base/pack-obj.mkiv @@ -41,7 +41,7 @@ % function objects.register(name) % objects.n = objects.n + 1 % local list = texbox.objectbox -% nodes.process_page(list) +% nodes.handlers.finalize(list) % data[name] = { % codeinjections.restore(list), % texdimen.objectwd, @@ -353,8 +353,8 @@ % no undefined test ! ! ! ! (pdftex fails on undefined objects) -\def\doregisterobjectreference#1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobobjects.save("#1::#2",#3,\noexpand\the\realpageno)}}} -\def\dooverloadobjectreference#1#2#3{\ctxlua{jobobjects.set("#1::#2",#3,\the\realpageno)}} +\def\doregisterobjectreference#1#2#3{\normalexpanded{\noexpand\ctxlatelua{job.objects.save("#1::#2",#3,\noexpand\the\realpageno)}}} +\def\dooverloadobjectreference#1#2#3{\ctxlua{job.objects.set("#1::#2",#3,\the\realpageno)}} \def\dosetobjectreference {\ifcase\crossreferenceobject @@ -370,8 +370,8 @@ \def\defaultobjectreference#1#2{0} % driver dependent \def\defaultobjectpage #1#2{\realfolio} -\def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{jobobjects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}} -\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{jobobjects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}} +\def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{job.objects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}} +\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{job.objects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}} \def\setobject {\driverreferenced\dosetobject1} \def\settightobject{\driverreferenced\dosetobject0} @@ -394,6 +394,6 @@ \expandafter\secondoftwoarguments \fi} -\def\doifobjectreferencefoundelse#1#2{\ctxlua{jobobjects.doifelse("#1::#2")}} +\def\doifobjectreferencefoundelse#1#2{\ctxlua{job.objects.doifelse("#1::#2")}} \protect \endinput diff --git a/tex/context/base/page-flt.lua b/tex/context/base/page-flt.lua index b0f332993..6b6755c22 100644 --- a/tex/context/base/page-flt.lua +++ b/tex/context/base/page-flt.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['page-flt'] = { license = "see context related readme files" } +-- floats -> managers.floats + local setdimen, setbox, setcount, texbox = tex.setdimen, tex.setbox, tex.setcount, tex.box local insert, remove = table.insert, table.remove local texwrite, texsprint, ctxcatcodes = tex.write, tex.sprint, tex.ctxcatcodes @@ -19,7 +21,8 @@ local report_floats = logs.new("floats") -- we use floatbox, floatwidth, floatheight -- text page leftpage rightpage (todo: top, bottom, margin, order) -floats = floats or { } +floats = floats or { } +local floats = floats local noffloats, last, default, pushed = 0, nil, "text", { } @@ -204,7 +207,7 @@ end function floats.thecheckedpagefloat(packed) local result = "" - if structure.pages.is_odd() then + if structures.pages.is_odd() then if #stacks.rightpage > 0 then result = "rightpage" elseif #stacks.page > 0 then diff --git a/tex/context/base/page-ini.mkiv b/tex/context/base/page-ini.mkiv index 497551f46..111a10511 100644 --- a/tex/context/base/page-ini.mkiv +++ b/tex/context/base/page-ini.mkiv @@ -798,12 +798,12 @@ \let\poparrangedpages\relax \let\pusharrangedpage\relax -\ifx\shiftprintpagebox\undefined +\ifdefined\shiftprintpagebox \else \let\shiftprintpagebox\gobbleoneargument \let\shiftpaperpagebox\gobbleoneargument \fi -\ifx\registerpageposition\undefined +\ifdefined\registerpageposition \else \let\registerpageposition\gobbleoneargument \fi diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua index f8daa84f4..08a10c2dd 100644 --- a/tex/context/base/page-lin.lua +++ b/tex/context/base/page-lin.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['page-lin'] = { license = "see context related readme files" } --- experimental +-- experimental -> will become builders local trace_numbers = false trackers.register("lines.numbers", function(v) trace_numbers = v end) @@ -14,24 +14,31 @@ local report_lines = logs.new("lines") local format = string.format local texsprint, texwrite, texbox = tex.sprint, tex.write, tex.box - local ctxcatcodes = tex.ctxcatcodes -local variables = interfaces.variables -nodes = nodes or { } -nodes.lines = nodes.lines or { } -nodes.lines.data = nodes.lines.data or { } -- start step tag +local attributes, nodes, node = attributes, nodes, node + +nodes.lines = nodes.lines or { } +local lines = nodes.lines + +lines.data = lines.data or { } -- start step tag +local data = lines.data +local last = #data + +lines.scratchbox = lines.scratchbox or 0 -storage.register("lines/data", nodes.lines.data, "nodes.lines.data") +storage.register("lines/data", lines.data, "nodes.lines.data") -- if there is demand for it, we can support multiple numbering streams -- and use more than one attibute -local nodecodes = nodes.nodecodes +local variables = interfaces.variables -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local whatsit = nodecodes.whatsit +local nodecodes = nodes.nodecodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local whatsit_code = nodecodes.whatsit local display_math = attributes.private('display-math') local line_number = attributes.private('line-number') @@ -50,14 +57,9 @@ local hpack_node = node.hpack local insert_node_after = node.insert_after local insert_node_before = node.insert_before -local data = nodes.lines.data -local last = #data - -nodes.lines.scratchbox = nodes.lines.scratchbox or 0 - -- cross referencing -function nodes.lines.number(n) +function lines.number(n) n = tonumber(n) local cr = cross_references[n] or 0 cross_references[n] = nil @@ -67,20 +69,20 @@ end local function resolve(n,m) -- we can now check the 'line' flag (todo) while n do local id = n.id - if id == whatsit then -- why whatsit + if id == whatsit_code then -- why whatsit local a = has_attribute(n,line_reference) if a then cross_references[a] = m end - elseif id == hlist or id == vlist then + elseif id == hlist_code or id == vlist_code then resolve(n.list,m) end n = n.next end end -function nodes.lines.finalize(t) - local getnumber = nodes.lines.number +function lines.finalize(t) + local getnumber = lines.number for _,p in next, t do for _,r in next, p do if r.metadata.kind == "line" then @@ -94,10 +96,10 @@ function nodes.lines.finalize(t) end end -local filters = jobreferences.filters -local helpers = structure.helpers +local filters = structures.references.filters +local helpers = structures.helpers -jobreferences.registerfinalizer(nodes.lines.finalize) +structures.references.registerfinalizer(lines.finalize) filters.line = filters.line or { } @@ -116,12 +118,13 @@ end -- boxed variant, todo: use number mechanism -nodes.lines.boxed = { } +lines.boxed = { } +local boxed = lines.boxed -- todo: cache setups, and free id no longer used -- use interfaces.cachesetup(t) -function nodes.lines.boxed.register(configuration) +function boxed.register(configuration) last = last + 1 data[last] = configuration if trace_numbers then @@ -130,7 +133,7 @@ function nodes.lines.boxed.register(configuration) return last end -function nodes.lines.boxed.setup(n,configuration) +function boxed.setup(n,configuration) local d = data[n] if d then if trace_numbers then @@ -175,13 +178,13 @@ local function check_number(n,a,skip,sameline) end end -function nodes.lines.boxed.stage_one(n) +function boxed.stage_one(n) current_list = { } local head = texbox[n] if head then local list = head.list local last_a, last_v, skip = nil, -1, false - for n in traverse_id(hlist,list) do -- attr test here and quit as soon as zero found + for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found if n.height == 0 and n.depth == 0 then -- skip funny hlists else @@ -214,11 +217,11 @@ function nodes.lines.boxed.stage_one(n) end end -function nodes.lines.boxed.stage_two(n,m) +function boxed.stage_two(n,m) if #current_list > 0 then - m = m or nodes.lines.scratchbox + m = m or lines.scratchbox local t, i = { }, 0 - for l in traverse_id(hlist,texbox[m].list) do + for l in traverse_id(hlist_code,texbox[m].list) do t[#t+1] = copy_node(l) end for i=1,#current_list do diff --git a/tex/context/base/page-lin.mkiv b/tex/context/base/page-lin.mkiv index e9df56aa6..9b08ab07e 100644 --- a/tex/context/base/page-lin.mkiv +++ b/tex/context/base/page-lin.mkiv @@ -473,7 +473,7 @@ % eventually we will do this in lua -\def\currentreferencelinenumber{\ctxlua{jobreferences.filter("linenumber")}} +\def\currentreferencelinenumber{\ctxlua{structures.references.filter("linenumber")}} \def\doifelsesamelinereference#1#2#3% {\doifreferencefoundelse{lr:b:#1} diff --git a/tex/context/base/page-str.lua b/tex/context/base/page-str.lua index 234e5424f..4ee2919d1 100644 --- a/tex/context/base/page-str.lua +++ b/tex/context/base/page-str.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['page-str'] = { license = "see context related readme files" } +-- streams -> managers.streams + -- work in progresss .. unfinished local concat = table.concat @@ -13,16 +15,23 @@ local concat = table.concat local find_tail, write_node, free_node, copy_nodelist = node.slide, node.write, node.free, node.copy_list local vpack_nodelist, hpack_nodelist = node.vpack, node.hpack local texdimen, texbox = tex.dimen, tex.box +local settings_to_array = utilities.parsers.settings_to_array + +local nodes, node = nodes, node + +local nodepool = nodes.pool +local tasks = nodes.tasks -local new_kern = nodes.kern -local new_glyph = nodes.glyph +local new_kern = nodepool.kern +local new_glyph = nodepool.glyph local trace_collecting = false trackers.register("streams.collecting", function(v) trace_collecting = v end) local trace_flushing = false trackers.register("streams.flushing", function(v) trace_flushing = v end) local report_streams = logs.new("streams") -streams = streams or { } +streams = streams or { } -- might move to the builders namespace +local streams = streams local data, name, stack = { }, nil, { } @@ -125,7 +134,7 @@ end function streams.synchronize(list) -- this is an experiment ! -- we don't optimize this as we want to trace in detail - list = aux.settings_to_array(list) + list = settings_to_array(list) local max = 0 if trace_flushing then report_streams("synchronizing list: %s",concat(list," ")) diff --git a/tex/context/base/page-str.mkiv b/tex/context/base/page-str.mkiv index d73643cbe..8cce9945f 100644 --- a/tex/context/base/page-str.mkiv +++ b/tex/context/base/page-str.mkiv @@ -47,7 +47,7 @@ {\ctxlua{streams.initialize()}% \glet\initializeoutputstreams\relax} -\def\enableoutputstream[#1]% +\def\enableoutputstream[#1]% could be \startoutputsubstream {\initializeoutputstreams \the\everyenableoutputstream \inoutputstreamtrue @@ -71,6 +71,16 @@ {\ctxlua{streams.stop()}% \endgroup} +\let\currentoutputsubstream\empty + +\def\startoutputsubstream[#1]% + {\glet\savedcurrentoutputstream\currentoutputstream + \enableoutputstream[#1]} + +\def\stopoutputsubstream + {\glet\currentoutputstream\savedcurrentoutputstream + \enableoutputstream[\savedcurrentoutputstream]} + \def\flushoutputstream [#1]{\ctxlua{streams.flush("#1")}} \def\outputstreamcopy [#1]{\vbox{\ctxlua{streams.flush("#1",true)}}} \def\outputstreambox [#1]{\vbox{\ctxlua{streams.flush("#1")}}} diff --git a/tex/context/base/page-txt.mkiv b/tex/context/base/page-txt.mkiv index bdc7c1bb6..3885b4bce 100644 --- a/tex/context/base/page-txt.mkiv +++ b/tex/context/base/page-txt.mkiv @@ -682,7 +682,7 @@ \def\@@nmpre#1% {\begingroup - \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}% + \setbox\scratchbox\normalhbox{\settrialtypesetting\ignorespaces#1\removeunwantedspaces}% \ifzeropt\wd\scratchbox\else \doifelsenothing\@@nmwidth {\box\scratchbox\tfskip} @@ -692,7 +692,7 @@ \def\@@nmpos#1% {\begingroup - \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}% + \setbox\scratchbox\normalhbox{\settrialtypesetting\ignorespaces#1\removeunwantedspaces}% \ifzeropt\wd\scratchbox\else \doifelsenothing\@@nmwidth {\tfskip\box\scratchbox} diff --git a/tex/context/base/pret-lua.lua b/tex/context/base/pret-lua.lua index 8803971f3..723c019d7 100644 --- a/tex/context/base/pret-lua.lua +++ b/tex/context/base/pret-lua.lua @@ -17,6 +17,10 @@ local byte, sub, find, match = string.byte, string.sub, string.find, string.matc local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes +local buffers = buffers + +local changestate, finishstate = buffers.changestate, buffers.finishstate + local visualizer = buffers.newvisualizer("lua") visualizer.identifiers = { } @@ -112,24 +116,22 @@ local states = { ['--']=4, } -local change_state, finish_state = buffers.change_state, buffers.finish_state - local function flush_lua_word(state, word) if word then local id = known_words[word] if id then - state = change_state(2,state) + state = changestate(2,state) if styles[id] then texsprint(ctxcatcodes,styles[id]) end texwrite(word) - state = finish_state(state) + state = finishstate(state) else - state = finish_state(state) -- ? + state = finishstate(state) -- ? texwrite(word) end else - state = finish_state(state) + state = finishstate(state) end return state end @@ -145,10 +147,10 @@ end local function written(state,c,i) if c == " " then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") elseif c == "\t" then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") if buffers.visualizers.enabletab then texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) @@ -172,9 +174,9 @@ function visualizer.flush_line(str, nested) for c in utfcharacters(comment) do if c == " " then texsprint(ctxcatcodes,"\\obs") else texwrite(c) end end - state = change_state(states['--'], state) + state = changestate(states['--'], state) texwrite("]]") - state = finish_state(state) + state = finishstate(state) incomment = false else for c in utfcharacters(str) do @@ -203,10 +205,10 @@ function visualizer.flush_line(str, nested) texwrite(c) inesc = false else - state = change_state(states[c],state) + state = changestate(states[c],state) instr = false texwrite(c) - state = finish_state(state) + state = finishstate(state) end s = nil else @@ -224,9 +226,9 @@ function visualizer.flush_line(str, nested) end if p == "[" then inlongstring = true - state = change_state(states["[["],state) + state = changestate(states["[["],state) texwrite(p,c) - state = finish_state(state) + state = finishstate(state) p = nil else if p then @@ -241,9 +243,9 @@ function visualizer.flush_line(str, nested) end if p == "]" then inlongstring = false - state = change_state(states["]]"],state) + state = changestate(states["]]"],state) texwrite(p,c) - state = finish_state(state) + state = finishstate(state) p = nil else if p then @@ -253,9 +255,9 @@ function visualizer.flush_line(str, nested) end else if p then - state = change_state(states[p],state) + state = changestate(states[p],state) texwrite(p) - state = finish_state(state) + state = finishstate(state) p = nil end if c == " " or c == "\t" then @@ -272,19 +274,19 @@ if word then word = nil end instr = true - state = change_state(states[c],state) + state = changestate(states[c],state) state, i = written(state,c,i) - state = finish_state(state) + state = finishstate(state) s = c elseif find(c,"^[%a]$") then - state = finish_state(state) + state = finishstate(state) if word then word = word .. c else word = c end elseif word and (#word > 1) and find(c,"^[%d%.%_]$") then if word then word = word .. c else word = c end else state = flush_lua_word(state,word) word = nil - state = change_state(states[c],state) + state = changestate(states[c],state) texwrite(c) instr = (c == '"') end @@ -297,9 +299,9 @@ end end state = flush_lua_word(state,word) if post then - state = change_state(states['--'], state) + state = changestate(states['--'], state) texwrite("--") - state = finish_state(state) + state = finishstate(state) for c in utfcharacters(post) do state, i = written(state,c,i) end @@ -307,13 +309,13 @@ end end if comment then incomment = true - state = change_state(states['--'], state) + state = changestate(states['--'], state) texwrite("[[") - state = finish_state(state) + state = finishstate(state) -- texwrite(comment) -- maybe also split and for c in utfcharacters(comment) do state, i = written(state,c,i) end end - state = finish_state(state) + state = finishstate(state) end diff --git a/tex/context/base/pret-mp.lua b/tex/context/base/pret-mp.lua index 782adf5f5..2e89588be 100644 --- a/tex/context/base/pret-mp.lua +++ b/tex/context/base/pret-mp.lua @@ -13,6 +13,10 @@ local utfbyte, utffind = utf.byte, utf.find local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes +local buffers = buffers + +local changestate, finishstate = buffers.changestate, buffers.finishstate + local visualizer = buffers.newvisualizer("mp") visualizer.identifiers = { } @@ -141,15 +145,13 @@ for k,v in next, visualizer.identifiers do end end -local change_state, finish_state = buffers.change_state, buffers.finish_state - local function flush_mp_word(state, word, intex) if word then if intex then if word == 'etex' then - state = change_state(2,state) + state = changestate(2,state) texwrite(word) - state = finish_state(state) + state = finishstate(state) return state, false else texwrite(word) @@ -158,21 +160,21 @@ local function flush_mp_word(state, word, intex) else local id = known_words[word] if id then - state = change_state(2,state) + state = changestate(2,state) if styles[id] then texsprint(ctxcatcodes,styles[id]) end texwrite(word) - state = finish_state(state) + state = finishstate(state) return state, (word == 'btex') or (word == 'verbatimtex') else - state = finish_state(state) + state = finishstate(state) texwrite(word) return state, intex end end else - state = finish_state(state) + state = finishstate(state) return state, intex end end @@ -193,16 +195,16 @@ function visualizer.flush_line(str,nested) elseif incomment then texwrite(c) elseif c == '%' then - state = change_state(states[c], state) + state = changestate(states[c], state) incomment = true texwrite(c) - state = finish_state(state) + state = finishstate(state) elseif instr then if c == '"' then - state = change_state(states[c],state) + state = changestate(states[c],state) instr = false texwrite(c) - state = finish_state(state) + state = finishstate(state) else texwrite(c) end @@ -215,22 +217,22 @@ function visualizer.flush_line(str,nested) if intex then texwrite(c) else - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) end end elseif utffind(c,"^[%a]$") then - state = finish_state(state) + state = finishstate(state) if word then word = word .. c else word = c end else state, intex = flush_mp_word(state, word, intex) word = nil - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) - state = finish_state(state) + state = finishstate(state) instr = (c == '"') end end state, intex = flush_mp_word(state, word, intex) - state = finish_state(state) + state = finishstate(state) end diff --git a/tex/context/base/pret-tex.lua b/tex/context/base/pret-tex.lua index 5d128fa3b..851155122 100644 --- a/tex/context/base/pret-tex.lua +++ b/tex/context/base/pret-tex.lua @@ -14,6 +14,10 @@ local rep = string.rep local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes, vrbcatcodes = tex.ctxcatcodes, tex.vrbcatcodes +local buffers = buffers + +local changestate, finishstate = buffers.changestate, buffers.finishstate + local visualizer = buffers.newvisualizer("tex") local colors = { @@ -31,8 +35,6 @@ local states = { -- some day I'll make an lpeg -local change_state, finish_state = buffers.change_state, buffers.finish_state - local chardata = characters.data local is_letter = characters.is_letter @@ -42,11 +44,11 @@ function visualizer.flush_line(str,nested) for c in utfcharacters(str) do i = i + 1 if c == " " then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") first = false elseif c == "\t" then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") if buffers.visualizers.enabletab then texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) @@ -57,7 +59,7 @@ function visualizer.flush_line(str,nested) state = 1 texwrite(c) if not utffind(c,"^[%a%!%?%@]$") then - state = finish_state(state) + state = finishstate(state) end first = false elseif state == 1 then @@ -65,23 +67,23 @@ function visualizer.flush_line(str,nested) texwrite(c) first = false elseif c == "\\" then - state = change_state(1, state) + state = changestate(1, state) texwrite(c) first = true else - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) first = false end elseif c == "\\" then first = true - state = change_state(1, state) + state = changestate(1, state) texwrite(c) else - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) first = false end end - state = finish_state(state) + state = finishstate(state) end diff --git a/tex/context/base/pret-xml.lua b/tex/context/base/pret-xml.lua index b11dccb99..e449d9d98 100644 --- a/tex/context/base/pret-xml.lua +++ b/tex/context/base/pret-xml.lua @@ -12,13 +12,16 @@ if not modules then modules = { } end modules ['pret-xml'] = { -- built in parser) local utf = unicode.utf8 - local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local utfbyte, utffind = utf.byte, utf.find local rep = string.rep local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes +local buffers = buffers + +local changestate, finishstate = buffers.changestate, buffers.finishstate + local visualizer = buffers.newvisualizer("xml") local colors = { @@ -33,8 +36,6 @@ local states = { ["-"]=1, ["?"]=1, ["!"]=1, [":"]=1, ["_"]=1, ["/"]=1, } -local change_state, finish_state = buffers.change_state, buffers.finish_state - local state, intag, dotag, inentity, inquote function visualizer.reset() @@ -46,26 +47,26 @@ function visualizer.flush_line(str,nested) for c in utfcharacters(str) do if c == "&" then inentity = true -- no further checking - state = change_state(3, state) + state = changestate(3, state) texwrite(c) elseif c == ";" then if inentity then inentity = false - state = change_state(3, state) + state = changestate(3, state) texwrite(c) - state = finish_state(state) + state = finishstate(state) else texwrite(c) end elseif inentity then - state = change_state(3, state) + state = changestate(3, state) texwrite(c) elseif c == " " then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") intag = false elseif c == "\t" then - state = finish_state(state) + state = finishstate(state) texsprint(ctxcatcodes,"\\obs") if buffers.visualizers.enabletab then texsprint(ctxcatcodes,rep("\\obs ",i%buffers.visualizers.tablength)) @@ -73,64 +74,64 @@ function visualizer.flush_line(str,nested) intag = false elseif c == "<" then if intag then - state = finish_state(state) + state = finishstate(state) -- error else intag = 1 dotag = true - state = change_state(1, state) + state = changestate(1, state) end texwrite(c) elseif c == ">" then if intag then texwrite(c) - state = finish_state(state) + state = finishstate(state) intag, dotag = false, false elseif dotag then - state = change_state(1, state) + state = changestate(1, state) texwrite(c) - state = finish_state(state) + state = finishstate(state) intag, dotag = false, false else - state = finish_state(state) + state = finishstate(state) texwrite(c) end elseif intag then if utffind(c,"^[%S]$") then - state = change_state(1, state) + state = changestate(1, state) texwrite(c) intag = intag + 1 else intag = false - state = finish_state(state) + state = finishstate(state) texwrite(c) end elseif dotag then if c == "'" or c == '"' then if inquote then if c == inquote then - state = change_state(states[c], state) -- 2 + state = changestate(states[c], state) -- 2 texwrite(c) - state = finish_state(state) + state = finishstate(state) inquote = false else texwrite(c) end else inquote = c - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) - state = finish_state(state) + state = finishstate(state) end elseif inquote then texwrite(c) else - state = change_state(states[c], state) + state = changestate(states[c], state) texwrite(c) end else texwrite(c) end end - state = finish_state(state) + state = finishstate(state) end diff --git a/tex/context/base/prop-mis.mkiv b/tex/context/base/prop-eff.mkiv index 37c1d7973..7207b9df4 100644 --- a/tex/context/base/prop-mis.mkiv +++ b/tex/context/base/prop-eff.mkiv @@ -1,8 +1,8 @@ %D \module -%D [ file=prop-mis, +%D [ file=prop-eff, %D version=2004.05.29, % some code moved from private modules %D title=\CONTEXT\ Property Macros, -%D subtitle=Miscelaneous, +%D subtitle=Effects, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] @@ -11,38 +11,10 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\writestatus{loading}{ConTeXt Property Macros / Miscelaneous} - -%D This module contains some code that has been in use in some -%D private modules (p-*). These features depend on the fact -%D that pdftex writes the page content as one stream. - -%D EXPERIMENTAL +\writestatus{loading}{ConTeXt Property Macros / Effects} \unprotect -% D Overprint cum suis. -% -% \defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command] -% \defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command] -% -% \definepropertyhandler \v!overprint {\dotriggeroverprint\v!overprint} -% \definepropertyhandler \v!knockout {\dotriggeroverprint\v!knockout } -% -% \unexpanded\def\startoverprintproperty{\dotriggeroverprint\v!overprint} -% \unexpanded\def\stopoverprintproperty {\dotriggeroverprint\v!knockout } - -%D Negative cum suis. - -\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command] -\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command] - -\definepropertyhandler \v!negative {\dotriggernegative\v!negative} -\definepropertyhandler \v!positive {\dotriggernegative\v!positive} - -\unexpanded\def\startnegativeproperty{\dotriggernegative\v!negative} -\unexpanded\def\stopnegativeproperty {\dotriggernegative\v!positive} - %D Special font effects. \setupproperty diff --git a/tex/context/base/prop-lay.mkiv b/tex/context/base/prop-lay.mkiv index 7711dae52..7d9d17870 100644 --- a/tex/context/base/prop-lay.mkiv +++ b/tex/context/base/prop-lay.mkiv @@ -103,7 +103,7 @@ kind = 0, % 1 == frozen printable = "\v!yes" }}% - \edef\layoutcomponentboxattribute{attr \viewerlayerattribute \ctxlua{tex.write(viewerlayers.register('#1:#2',true))}\relax}% + \edef\layoutcomponentboxattribute{attr \viewerlayerattribute \ctxlua{tex.write(attributes.viewerlayers.register('#1:#2',true))}\relax}% \expandafter\glet\csname\??ly>#1:#2\endcsname\layoutcomponentboxattribute} \def\dosetlayoutcomponentattribute#1#2% make this faster @@ -120,7 +120,7 @@ \let\layoutcomponentboxattribute \empty \def\showlayoutcomponents - {\ctxlua{viewerlayers.enable()}% + {\ctxlua{attributes.viewerlayers.enable()}% \let\setlayoutcomponentattribute \dosetlayoutcomponentattribute \let\resetlayoutcomponentattribute\doresetlayoutcomponentattribute} diff --git a/tex/context/base/prop-neg.mkiv b/tex/context/base/prop-neg.mkiv new file mode 100644 index 000000000..37e45833c --- /dev/null +++ b/tex/context/base/prop-neg.mkiv @@ -0,0 +1,40 @@ +%D \module +%D [ file=prop-neg, +%D version=2004.05.29, % some code moved from private modules +%D title=\CONTEXT\ Property Macros, +%D subtitle=Negation, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Property Macros / Negation} + +\unprotect + +% D Overprint cum suis. +% +% \defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command] +% \defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command] +% +% \definepropertyhandler \v!overprint {\dotriggeroverprint\v!overprint} +% \definepropertyhandler \v!knockout {\dotriggeroverprint\v!knockout } +% +% \unexpanded\def\startoverprintproperty{\dotriggeroverprint\v!overprint} +% \unexpanded\def\stopoverprintproperty {\dotriggeroverprint\v!knockout } + +%D Negative cum suis. + +\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command] +\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command] + +\definepropertyhandler \v!negative {\dotriggernegative\v!negative} +\definepropertyhandler \v!positive {\dotriggernegative\v!positive} + +\unexpanded\def\startnegativeproperty{\dotriggernegative\v!negative} +\unexpanded\def\stopnegativeproperty {\dotriggernegative\v!positive} + +\protect \endinput diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua index 837397607..6c4d787c1 100644 --- a/tex/context/base/regi-ini.lua +++ b/tex/context/base/regi-ini.lua @@ -18,12 +18,18 @@ local ctxcatcodes = tex.ctxcatcodes runtime.</p> --ldx]]-- -regimes = regimes or { } -regimes.data = regimes.data or { } -regimes.utf = regimes.utf or { } +regimes = regimes or { } +local regimes = regimes + +regimes.data = regimes.data or { } +local data = regimes.data + +regimes.utf = regimes.utf or { } + regimes.synonyms = regimes.synonyms or { } +local synonyms = regimes.synonyms -storage.register("regimes/synonyms", regimes.synonyms, "regimes.synonyms") +storage.register("regimes/synonyms", synonyms, "regimes.synonyms") -- setmetatable(regimes.data,_empty_table_) @@ -38,20 +44,20 @@ function regimes.number(n) end function regimes.setsynonym(synonym,target) - regimes.synonyms[synonym] = target + synonyms[synonym] = target end function regimes.truename(regime) - texsprint(ctxcatcodes,(regime and regimes.synonyms[synonym] or regime) or regimes.currentregime) + texsprint(ctxcatcodes,(regime and synonyms[synonym] or regime) or regimes.currentregime) end function regimes.load(regime) - regime = regimes.synonyms[regime] or regime - if not regimes.data[regime] then + regime = synonyms[regime] or regime + if not data[regime] then environment.loadluafile("regi-"..regime, 1.001) - if regimes.data[regime] then + if data[regime] then regimes.utf[regime] = { } - for k,v in next, regimes.data[regime] do + for k,v in next, data[regime] do regimes.utf[regime][char(k)] = utfchar(v) end end @@ -59,7 +65,7 @@ function regimes.load(regime) end function regimes.translate(line,regime) - regime = regimes.synonyms[regime] or regime + regime = synonyms[regime] or regime if regime and line then local rur = regimes.utf[regime] if rur then @@ -70,8 +76,8 @@ function regimes.translate(line,regime) end function regimes.enable(regime) - regime = regimes.synonyms[regime] or regime - if regimes.data[regime] then + regime = synonyms[regime] or regime + if data[regime] then regimes.currentregime = regime local translate = regimes.translate resolvers.install_text_filter('input',function(s) diff --git a/tex/context/base/s-set-31.tex b/tex/context/base/s-set-31.tex new file mode 100644 index 000000000..53037a78d --- /dev/null +++ b/tex/context/base/s-set-31.tex @@ -0,0 +1,118 @@ +% show missing translations + +\startluacode +function interfaces.show_missing(whatinterfaces) + whatinterfaces = whatinterfaces or interfaces.interfaces + local list = dofile(resolvers.find_file("mult-def.lua")) + local NC, NR, HL = context.NC, context.NR, context.HL + for k,v in table.sortedhash(list) do + context.title(k) + context.starttabulate { string.rep("|",#whatinterfaces+1) } + for i=1,#whatinterfaces do + NC() + context(whatinterfaces[i]) + end + NC() NR() HL() + for kk, vv in next, v do + if not string.find(kk,"subsub") then + local okay = true + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + if not str or (int ~= "en" and str == vv.en) then + okay = false + break + end + end + if not okay then + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + context.NC() + if not str then + -- nothing + elseif int == "en" then + context.color( { "darkgreen" }, str ) + elseif str == vv.en then + context.color( { "darkred" }, str ) + elseif int == "pe" then + context("\\righttoleft " .. str) + else + context(str) + end + end + NC() NR() + end + end + end + context.stoptabulate() + end +end + +function interfaces.show_missing_messages(whatinterfaces) + whatinterfaces = whatinterfaces or interfaces.interfaces + local list = dofile(resolvers.find_file("mult-mes.lua")) + local NC, NR, HL = context.NC, context.NR, context.HL + for k,v in table.sortedhash(list) do + context.title("message: " .. k) + context.starttabulate { "|l|" .. string.rep("pl|",#whatinterfaces) } + NC() + for i=1,#whatinterfaces do + NC() + context(whatinterfaces[i]) + end + NC() NR() HL() + local sorted = table.sortedkeys(v) + for i=1,#sorted do + local kk = sorted[i] + local vv = v[kk] + if kk ~= "files" then + local okay = true + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + if not str or (int ~= "en" and str == vv.en) then + okay = false + break + end + end + if not okay then + context.NC() + context(kk) + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + NC() + if not str then + -- nothing + elseif int == "en" then + context.color( { "darkgreen" }, str ) + elseif str == vv.en then + context.color( { "darkred" }, str ) + elseif int == "pe" then + context("\\righttoleft " .. str) + else + context(str) + end + end + NC() NR() + end + end + end + context.stoptabulate() + end +end +\stopluacode + +\starttext + +\setupbodyfont[dejavu,7pt,tt] +\setuppapersize[A4,landscape][A4,landscape] +\setuplayout[backspace=.5cm,width=middle,topspace=.5cm,height=middle,header=1cm,footer=0cm] + +\startluacode + interfaces.show_missing() -- { "en","nl" } + interfaces.show_missing_messages() -- { "en","nl" } +\stopluacode + +\stoptext diff --git a/tex/context/base/scrn-int.lua b/tex/context/base/scrn-int.lua index 7036bbf6a..d01669aa4 100644 --- a/tex/context/base/scrn-int.lua +++ b/tex/context/base/scrn-int.lua @@ -9,11 +9,22 @@ if not modules then modules = { } end modules ['scrn-int'] = { local format = string.format local texsprint, texcount, ctxcatcodes = tex.sprint, tex.count, tex.ctxcatcodes -interactions = interactions or { } +interactions = interactions or { } +local interactions = interactions -local attachments = { } +interactions.attachments = interactions.attachments or { } +interactions.soundclips = interactions.soundclips or { } +interactions.renderings = interactions.renderings or { } +interactions.linkedlists = interactions.linkedlists or { } -function interactions.registerattachment(specification) +local attachments = interactions.attachments +local soundclips = interactions.soundclips +local renderings = interactions.renderings +local linkedlists = interactions.linkedlists + +local jobpasses = job.passes + +function attachments.register(specification) if specification.label then specification.filename = specification.filename or specification.label specification.newname = specification.newname or specification.filename @@ -24,24 +35,22 @@ function interactions.registerattachment(specification) end end -function interactions.attachment(label) +function attachments.attachment(label) local at = attachments[label] if not at then interfaces.showmessage("interactions",6,label) - return interactions.registerattachment { label = label } + return attachments.register { label = label } else return at end end -function interactions.attachmentvar(label,key) +function attachments.var(label,key) local at = attachments[label] texsprint(ctxcatcodes,at and at[key] or "") end -local soundclips = { } - -function interactions.registersoundclip(specification) +function soundclips.register(specification) if specification.label then specification.filename = specification.filename or specification.label soundclips[specification.label] = specification @@ -49,47 +58,45 @@ function interactions.registersoundclip(specification) end end -function interactions.soundclip(label) +function soundclips.soundclip(label) local sc = soundclips[label] if not sc then -- todo: message - return interactions.registersoundclip { label = label } + return soundclips.register { label = label } else return sc end end -local renderings = { } - -function interactions.registerrendering(specification) +function renderings.register(specification) if specification.label then renderings[specification.label] = specification return specification end end -function interactions.rendering(label) +function renderings.rendering(label) local rn = renderings[label] if not rn then -- todo: message - return interactions.registerrendering { label = label } + return renderings.register { label = label } else return rn end end -function interactions.renderingvar(label,key) +function renderings.var(label,key) local rn = renderings[label] texsprint(ctxcatcodes,rn and rn[key] or "") end -- linked lists -function interactions.definelinkedlist(name) +function linkedlists.define(name) -- no need end -function interactions.addlinktolist(name) +function linkedlists.add(name) local tobesaved = jobpasses.gettobesaved(name) local collected = jobpasses.getcollected(name) or { } local currentlink = #tobesaved + 1 @@ -102,10 +109,9 @@ function interactions.addlinktolist(name) texsprint(ctxcatcodes,format("\\setlinkproperties{%s}{%s}{%s}{%s}{%s}{%s}",currentlink,noflinks,f,p,n,l)) end -function interactions.enhancelinkoflist(name,n) +function linkedlists.enhance(name,n) local ll = jobpasses.gettobesaved(name) if ll then ll[n] = texcount.realpageno end end - diff --git a/tex/context/base/scrn-int.mkiv b/tex/context/base/scrn-int.mkiv index 11734e0d7..70382249c 100644 --- a/tex/context/base/scrn-int.mkiv +++ b/tex/context/base/scrn-int.mkiv @@ -137,7 +137,7 @@ \unexpanded\def\setuplinkedlists{\dosingleargument\dosetuplinkedlists} \def\dodefinelinkedlist[#1][#2]% - {\ctxlua{interactions.definelinkedlist("#1")}% + {\ctxlua{interactions.linkedlists.define("#1")}% \getparameters[\??lk#1][\s!parent=\??lk,#2]} \def\dosetuplinkedlist[#1][#2]% @@ -161,8 +161,8 @@ \edef\currentlinkedlist{#1}% \ifcsname\??lk\currentlinkedlist\s!parent\endcsname \hskip\linkedlistparameter\c!distance - \ctxlua{interactions.addlinktolist("\currentlinkedlist")}% - \expanded{\ctxlatelua{interactions.enhancelinkoflist("\currentlinkedlist",\currentlink)}}% + \ctxlua{interactions.linklists.add("\currentlinkedlist")}% + \expanded{\ctxlatelua{interactions.linklists.enhance("\currentlinkedlist",\currentlink)}}% \dogotosomepage {\??lk\currentlinkedlist}\gotobegincharacter \firstlink \ifnum\noflinks>\plustwo \dogotosomepage{\??lk\currentlinkedlist}\gobackwardcharacter\previouslink @@ -412,13 +412,13 @@ \def\douseattachment[#1][#2][#3][#4]% tag title newname filename {\iffourthargument - \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#3", filename="#4" }}% + \ctxlua{interactions.attachments.register{ label="#1", title="#2", newname="#3", filename="#4" }}% \else\ifthirdargument - \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#2", filename="#3" }}% + \ctxlua{interactions.attachments.register{ label="#1", title="#2", newname="#2", filename="#3" }}% \else\ifsecondargument - \ctxlua{interactions.registerattachment{ label="#1", title="#2", newname="#2", filename="#2" }}% + \ctxlua{interactions.attachments.register{ label="#1", title="#2", newname="#2", filename="#2" }}% \else - \ctxlua{interactions.registerattachment{ label="#1", title="#1", newname="#1", filename="#1" }}% + \ctxlua{interactions.attachments.register{ label="#1", title="#1", newname="#1", filename="#1" }}% \fi\fi\fi} \def\attachment @@ -483,11 +483,11 @@ {\dodoubleargument\douseexternalsoundtrack} \def\douseexternalsoundtrack[#1][#2]% - {\ctxlua{interactions.registersound{ label="#1", filename="#2" }}} + {\ctxlua{interactions.soundclips.register{ label="#1", filename="#2" }}} \def\checksoundtrack#1% yet untested in mkiv (also move management to lua) {\iflocation - \ctxlua{codeinjections.insertsound{ + \ctxlua{nodeinjections.insertsound{ label = "#1", repeat = "\@@sdoption", % not entirely ok but works }}% @@ -516,7 +516,7 @@ \def\setinternalrendering{\dodoubleempty \dosetinternalrendering} \def\douseexternalrendering[#1][#2][#3][#4]% tag mime file options - {\ctxlua{interactions.registerrendering { + {\ctxlua{interactions.renderings.register { kind = "external", label = "#1", mime = "#2", @@ -527,7 +527,7 @@ \def\dosetinternalrendering[#1][#2]% tag options {content} {\bgroup \dowithnextbox - {\ctxlua{interactions.registerrendering { + {\ctxlua{interactions.renderings.register { kind = "internal", label = "#1", mime = "IRO", @@ -539,8 +539,8 @@ \egroup}% \hbox} -\def\renderingtype #1{\ctxlua{interactions.renderingvar("#1","kind")}} -\def\renderingoptions#1{\ctxlua{interactions.renderingvar("#1","options")}} +\def\renderingtype #1{\ctxlua{interactions.renderings.var("#1","kind")}} +\def\renderingoptions#1{\ctxlua{interactions.renderings.var("#1","options")}} \def\renderingwidth {8cm} \def\renderingheight {6cm} diff --git a/tex/context/base/scrn-men.mkiv b/tex/context/base/scrn-men.mkiv index 246d31bfd..29085d87a 100644 --- a/tex/context/base/scrn-men.mkiv +++ b/tex/context/base/scrn-men.mkiv @@ -389,11 +389,11 @@ {\analyzecurrentreference % we need to act on the state \ifcase\referencepagestate % something else than a page reference - \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \ctxlua{structures.references.injectcurrentset(nil,nil)}% \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2]{#3}}% \else\ifcase\csname\??am:\c!location:\menuparameter\c!samepage\endcsname\relax % yes: same page or not ... todo - \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \ctxlua{structures.references.injectcurrentset(nil,nil)}% \ifnum\referencepagestate=\plusone % same page \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2,\c!color=\menuparameter\c!contrastcolor]{#3}}% \else % elsewhere diff --git a/tex/context/base/scrn-nav.mkiv b/tex/context/base/scrn-nav.mkiv index 04b404a78..207530b83 100644 --- a/tex/context/base/scrn-nav.mkiv +++ b/tex/context/base/scrn-nav.mkiv @@ -96,15 +96,15 @@ {\iflocation \donefalse \ifx\@@iaopenaction\empty \else \donetrue - \ctxlua{jobreferences.checkopendocumentactions("\@@iaopenaction")}% - \ctxlua{jobreferences.expandcurrent()}% + \ctxlua{structures.references.checkopendocumentactions("\@@iaopenaction")}% + \ctxlua{structures.references.expandcurrent()}% \fi \ifx\@@iacloseaction\empty \else \donetrue - \ctxlua{jobreferences.checkclosedocumentactions("\@@iacloseaction")}% - \ctxlua{jobreferences.expandcurrent()}% + \ctxlua{structures.references.checkclosedocumentactions("\@@iacloseaction")}% + \ctxlua{structures.references.expandcurrent()}% \fi \ifdone - \ctxlua{jobreferences.flushdocumentactions()}% + \ctxlua{structures.references.flushdocumentactions()}% \fi \global\let\dolocationstartup\relax \fi} @@ -113,15 +113,15 @@ {\iflocation \donefalse \ifx\@@iaopenpageaction\empty \else \donetrue - \ctxlua{jobreferences.checkopenpageactions("\@@iaopenpageaction")}% - \ctxlua{jobreferences.expandcurrent()}% + \ctxlua{structures.references.checkopenpageactions("\@@iaopenpageaction")}% + \ctxlua{structures.references.expandcurrent()}% \fi \ifx\@@iaclosepageaction\empty \else \donetrue - \ctxlua{jobreferences.checkclosepageactions("\@@iaclosepageaction")}% - \ctxlua{jobreferences.expandcurrent()}% + \ctxlua{structures.references.checkclosepageactions("\@@iaclosepageaction")}% + \ctxlua{structures.references.expandcurrent()}% \fi \ifdone - \ctxlua{jobreferences.flushpageactions()}% + \ctxlua{structures.references.flushpageactions()}% \fi \fi} @@ -197,7 +197,7 @@ \def\enableinteractivereferences {\ifproductionrun - \ctxlua{jobreferences.enable_interaction()}% + \ctxlua{structures.references.enable_interaction()}% \globallet\enableinteractivereferences\relax \fi} diff --git a/tex/context/base/scrp-cjk.lua b/tex/context/base/scrp-cjk.lua index 6ac6c5b11..e17d4e967 100644 --- a/tex/context/base/scrp-cjk.lua +++ b/tex/context/base/scrp-cjk.lua @@ -7,15 +7,21 @@ if not modules then modules = { } end modules ['scrp-cjk'] = { } local has_attribute = node.has_attribute -local make_glue_node = nodes.glue -local make_penalty_node = nodes.penalty local insert_node_after = node.insert_after local insert_node_before = node.insert_before local remove_node = nodes.remove -local glyph = node.id('glyph') -local glue = node.id('glue') -local penalty = node.id('penalty') +local nodepool = nodes.pool + +local new_glue = nodepool.glue +local new_penalty = nodepool.penalty + +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes + +local glyph_code = nodecodes.glyph + +local userskip_code = skipcodes.userskip local preproc = attributes.private('preproc') local prestat = attributes.private('prestat') @@ -50,123 +56,123 @@ end -- at font definition time and/or just assume a correct font local function nobreak(head,current) - insert_node_before(head,current,make_penalty_node(10000)) + insert_node_before(head,current,new_penalty(10000)) end local function stretch_break(head,current) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function shrink_break(head,current) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end local function nobreak_stretch(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function korean_break(head,current) - insert_node_before(head,current,make_penalty_node(inter_char_hangul_penalty)) + insert_node_before(head,current,new_penalty(inter_char_hangul_penalty)) end local function nobreak_shrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end local function nobreak_autoshrink(head,current) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end end local function nobreak_stretch_nobreak_shrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end local function nobreak_stretch_nobreak_autoshrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end end local function nobreak_shrink_nobreak_stretch(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function nobreak_autoshrink_nobreak_stretch(head,current) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function nobreak_shrink_break_stretch(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function nobreak_autoshrink_break_stretch(head,current) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function nobreak_shrink_break_stretch_nobreak_shrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end local function nobreak_autoshrink_break_stretch_nobreak_autoshrink(head,current) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end end local function nobreak_autoshrink_break_stretch_nobreak_shrink(head,current) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end local function nobreak_shrink_break_stretch_nobreak_autoshrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) if true then - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) end end local function nobreak_stretch_break_shrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end local function nobreak_stretch_break_autoshrink(head,current) - insert_node_before(head,current,make_penalty_node(10000)) - insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0)) + insert_node_before(head,current,new_penalty(10000)) + insert_node_before(head,current,new_glue(userskip_code,inter_char_stretch,0)) if true then - insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink)) + insert_node_before(head,current,new_glue(userskip_code,0,inter_char_half_shrink)) end end @@ -318,7 +324,7 @@ local function process(head,first,last) local lastfont, previous, originals, last = nil, "start", nil, nil while true do local upcoming, id = first.next, first.id - if id == glyph then + if id == glyph_code then local a = has_attribute(first,prestat) local current = number_to_kind[a] local action = injectors[previous] @@ -338,7 +344,7 @@ local function process(head,first,last) local p, n = first.prev, upcoming if p and n then local pid, nid = p.id, n.id - if pid == glyph and nid == glyph then + if pid == glyph_code and nid == glyph_code then local pa, na = has_attribute(p,prestat), has_attribute(n,prestat) local pcjk, ncjk = pa and number_to_kind[pa], na and number_to_kind[na] if not pcjk or not ncjk @@ -521,7 +527,7 @@ local function process(head,first,last) local lastfont, previous, originals, last = nil, "start", nil, nil while true do local upcoming, id = first.next, first.id - if id == glyph then + if id == glyph_code then local a = has_attribute(first,prestat) local current = number_to_kind[a] local action = injectors[previous] @@ -541,7 +547,7 @@ local function process(head,first,last) local p, n = first.prev, upcoming if p and n then local pid, nid = p.id, n.id - if pid == glyph and nid == glyph then + if pid == glyph_code and nid == glyph_code then local pa, na = has_attribute(p,prestat), has_attribute(n,prestat) local pcjk, ncjk = pa and number_to_kind[pa], na and number_to_kind[na] if not pcjk or not ncjk diff --git a/tex/context/base/scrp-ini.lua b/tex/context/base/scrp-ini.lua index 292f1e779..bff12def8 100644 --- a/tex/context/base/scrp-ini.lua +++ b/tex/context/base/scrp-ini.lua @@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['scrp-ini'] = { license = "see context related readme files" } +local attributes, nodes, node = attributes, nodes, node + +local texwrite = tex.write + local trace_analyzing = false trackers.register("scripts.analyzing", function(v) trace_analyzing = v end) local trace_injections = false trackers.register("scripts.injections", function(v) trace_injections = v end) @@ -16,31 +20,41 @@ local has_attribute = node.has_attribute local first_character = node.first_character local traverse_id = node.traverse_id -local glyph = node.id('glyph') -local glue = node.id('glue') -local penalty = node.id('penalty') +local nodecodes = nodes.nodecodes +local unsetvalue = attributes.unsetvalue + +local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue -local fcs = (fonts.color and fonts.color.set) or function() end -local fcr = (fonts.color and fonts.color.reset) or function() end +local state = attributes.private('state') +local preproc = attributes.private('preproc') +local prestat = attributes.private('prestat') -local state = attributes.private('state') -local preproc = attributes.private('preproc') -local prestat = attributes.private('prestat') +local fontdata = fonts.ids -local fontdata = fonts.ids +local fcs = (fonts.color and fonts.color.set) or function() end +local fcr = (fonts.color and fonts.color.reset) or function() end + +scripts = scripts or { } +local scripts = scripts -scripts = scripts or { } scripts.handlers = scripts.handlers or { } +local handlers = scripts.handlers + +scripts.names = scripts.names or { } +local names = scripts.names -scripts.names = scripts.names or { } -scripts.numbers = scripts.numbers or { } -scripts.hash = scripts.hash or { } +scripts.numbers = scripts.numbers or { } +local numbers = scripts.numbers -storage.register("scripts/hash", scripts.hash, "scripts.hash") +scripts.hash = scripts.hash or { } +local hash = scripts.hash -if not next(scripts.hash) then +storage.register("scripts/hash", hash, "scripts.hash") - local hash = { +if not next(hash) then + + hash = { -- no local -- -- half width opening parenthesis [0x0028] = "half_width_open", @@ -165,6 +179,8 @@ if not next(scripts.hash) then end +-- the following tables will become a proper installer + scripts.colors = { -- todo: just named colors korean = "font:isol", chinese = "font:rest", @@ -177,10 +193,11 @@ scripts.colors = { -- todo: just named colors jamo_initial = "font:init", jamo_medial = "font:medi", jamo_final = "font:fina", - } -scripts.number_to_kind = { +local colors = scripts.colors + +local number_to_kind = { "korean", "chinese", "full_width_open", @@ -194,7 +211,7 @@ scripts.number_to_kind = { "jamo_final", } -scripts.kind_to_number = { +local kind_to_number = { korean = 1, chinese = 2, full_width_open = 3, @@ -208,20 +225,14 @@ scripts.kind_to_number = { jamo_final = 11, } -local kind_to_number = scripts.kind_to_number -local number_to_kind = scripts.number_to_kind +scripts.kind_to_number = kind_to_number +scripts.number_to_kind = number_to_kind -- no, this time loading the lua always precedes the definitions -- -- storage.register("scripts/names", scripts.names, "scripts.names") -- storage.register("scripts/numbers", scripts.numbers, "scripts.numbers") -local handlers = scripts.handlers -local names = scripts.names -local numbers = scripts.numbers -local hash = scripts.hash -local colors = scripts.colors - -- maybe also process function scripts.install(handler) @@ -236,13 +247,13 @@ function scripts.install(handler) end function scripts.define(name) - tex.write(names[name] or attributes.unsetvalue) + texwrite(names[name] or unsetvalue) end -- some time i will make a fonts.originals[id] local function colorize(start,stop) - for n in traverse_id(glyph,start) do + for n in traverse_id(glyph_code,start) do local kind = number_to_kind[has_attribute(n,prestat)] if kind then local ac = colors[kind] @@ -279,7 +290,7 @@ function scripts.preprocess(head) local done, first, last, ok = false, nil, nil, false while start do local id = start.id - if id == glyph then + if id == glyph_code then local a = has_attribute(start,preproc) if a then if a ~= last_a then @@ -349,7 +360,7 @@ function scripts.preprocess(head) end first, last = nil, nil end - elseif id == glue then + elseif id == glue_code then if ok then -- continue elseif first then diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index 567ba42e8..38c28aaa6 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -22,41 +22,45 @@ local trace_tests = false trackers.register("sorters.tests", function(v) trace_ local report_sorters = logs.new("sorters") -sorters = { } -sorters.comparers = { } -sorters.splitters = { } -sorters.entries = { } -sorters.mappings = { } -sorters.replacements = { } - -sorters.ignored_offset = 0x10000 -sorters.replacement_offset = 0x10000 -sorters.digits_offset = 0x20000 -sorters.digits_maximum = 0xFFFFF - -local ignored_offset = sorters.ignored_offset -local digits_offset = sorters.digits_offset -local digits_maximum = sorters.digits_maximum +local comparers = { } +local splitters = { } +local entries = { } +local mappings = { } +local replacements = { } +local ignored_offset = 0x10000 +local replacement_offset = 0x10000 +local digits_offset = 0x20000 +local digits_maximum = 0xFFFFF + +sorters = { + comparers = comparers, + splitters = splitters, + entries = entries, + mappings = mappings, + replacements = replacements, + ignored_offset = ignored_offset, + replacement_offset = replacement_offset, + digits_offset = digits_offset, + digits_maximum = digits_maximum, +} -local mappings = sorters.mappings -local entries = sorters.entries -local replacements = sorters.replacements +local ssorters = sorters -local language, defaultlanguage, dummy = 'en', 'en', { } +local language, defaultlanguage = 'en', 'en' -local currentreplacements, currentmappings, currententries +local currentreplacements, currentmappings, currententries = { }, { }, { } function sorters.setlanguage(lang) language = lang or language or defaultlanguage - currentreplacements = replacements[language] or replacements[defaultlanguage] or dummy - currentmappings = mappings [language] or mappings [defaultlanguage] or dummy - currententries = entries [language] or entries [defaultlanguage] or dummy - report_sorters("setting language '%s'",language) + currentreplacements = replacements[language] or replacements[defaultlanguage] or { } + currentmappings = mappings [language] or mappings [defaultlanguage] or { } + currententries = entries [language] or entries [defaultlanguage] or { } + if trace_tests then + report_sorters("setting language '%s'",language) + end return currentreplacements, currentmappings, currententries end -sorters.setlanguage() - -- maybe inline code if it's too slow local function basicsort(sort_a,sort_b) @@ -105,7 +109,7 @@ local function basicsort(sort_a,sort_b) end end -function sorters.comparers.basic(a,b) +function comparers.basic(a,b) local ea, eb = a.split, b.split local na, nb = #ea, #eb if na == 0 and nb == 0 then @@ -176,7 +180,7 @@ sorters.firstofsplit = firstofsplit -- beware, numbers get spaces in front -function sorters.splitters.utf(str) +function splitters.utf(str) if #currentreplacements > 0 then for k=1,#currentreplacements do local v = currentreplacements[k] @@ -198,7 +202,7 @@ end -- but for the moment we do it this way as it is more -- handy for tracing --- function sorters.splitters.utf(str) +-- function splitters.utf(str) -- if #currentreplacements > 0 then -- for k=1,#currentreplacements do -- local v = currentreplacements[k] diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua index ed7e8ba35..227b3ee7c 100644 --- a/tex/context/base/sort-lan.lua +++ b/tex/context/base/sort-lan.lua @@ -15,6 +15,8 @@ local utf = unicode.utf8 local uc = utf.char local ub = utf.byte +local sorters = sorters + local mappings = sorters.mappings local entries = sorters.entries local replacements = sorters.replacements @@ -317,3 +319,30 @@ mappings['sl'] = { add_uppercase_entries ("sl") add_uppercase_mappings("sl") -- cf. MM + +sorters.replacements["pl"] = { + -- no replacements +} + +sorters.entries["pl"] = { + ["a"] = "a", ["ą"] = "ą", ["b"] = "b", ["c"] = "c", ["ć"] = "ć", + ["d"] = "d", ["e"] = "e", ["ę"] = "ę", ["f"] = "f", ["g"] = "g", + ["h"] = "h", ["i"] = "i", ["j"] = "j", ["k"] = "k", ["l"] = "l", + ["ł"] = "ł", ["m"] = "m", ["n"] = "n", ["ń"] = "ń", ["o"] = "o", + ["ó"] = "ó", ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s", + ["ś"] = "ś", ["t"] = "t", ["u"] = "u", ["v"] = "v", ["w"] = "w", + ["x"] = "x", ["y"] = "y", ["z"] = "z", ["ź"] = "ź", ["ż"] = "ż", +} + +sorters.mappings["pl"] = { + ["a"] = 1, ["ą"] = 2, ["b"] = 3, ["c"] = 4, ["ć"] = 5, + ["d"] = 6, ["e"] = 7, ["ę"] = 8, ["f"] = 9, ["g"] = 10, + ["h"] = 11, ["i"] = 12, ["j"] = 13, ["k"] = 14, ["l"] = 15, + ["ł"] = 16, ["m"] = 17, ["n"] = 18, ["ń"] = 19, ["o"] = 20, + ["ó"] = 21, ["p"] = 22, ["q"] = 23, ["r"] = 24, ["s"] = 25, + ["ś"] = 26, ["t"] = 27, ["u"] = 28, ["v"] = 29, ["w"] = 30, + ["x"] = 31, ["y"] = 32, ["z"] = 33, ["ź"] = 34, ["ż"] = 35, +} + +add_uppercase_entries ('pl') +add_uppercase_mappings('pl',1) diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 571e9f3ca..aa166a2f7 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -20,25 +20,29 @@ if not modules then modules = { } end modules ['spac-ver'] = { -- todo: strip baselineskip around display math local next, type, tonumber = next, type, tonumber -local format, gmatch, concat, match = string.format, string.gmatch, table.concat, string.match -local ceil, floor, max, min, round = math.ceil, math.floor, math.max, math.min, math.round +local format, gmatch, concat, match, rep = string.format, string.gmatch, table.concat, string.match, string.rep +local ceil, floor, max, min, round, abs = math.ceil, math.floor, math.max, math.min, math.round, math.abs local texsprint, texlists, texdimen, texbox = tex.sprint, tex.lists, tex.dimen, tex.box local lpegmatch = lpeg.match local unpack = unpack or table.unpack +local points = number.points + +local nodes, node, trackers, attributes = nodes, node, trackers, attributes local ctxcatcodes = tex.ctxcatcodes -local variables = interfaces.variables +local variables = interfaces.variables -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming -- vertical space handler -local trace_vbox_vspacing = false trackers.register("nodes.vbox_vspacing", function(v) trace_vbox_vspacing = v end) -local trace_page_vspacing = false trackers.register("nodes.page_vspacing", function(v) trace_page_vspacing = v end) -local trace_collect_vspacing = false trackers.register("nodes.collect_vspacing", function(v) trace_collect_vspacing = v end) -local trace_vspacing = false trackers.register("nodes.vspacing", function(v) trace_vspacing = v end) -local trace_vsnapping = false trackers.register("nodes.vsnapping", function(v) trace_vsnapping = v end) -local trace_vpacking = false trackers.register("nodes.vpacking", function(v) trace_vpacking = v end) +local trace_vbox_vspacing = false trackers.register("builders.vbox_vspacing", function(v) trace_vbox_vspacing = v end) +local trace_page_vspacing = false trackers.register("builders.page_vspacing", function(v) trace_page_vspacing = v end) +local trace_collect_vspacing = false trackers.register("builders.collect_vspacing", function(v) trace_collect_vspacing = v end) +local trace_vspacing = false trackers.register("builders.vspacing", function(v) trace_vspacing = v end) +local trace_vsnapping = false trackers.register("builders.vsnapping", function(v) trace_vsnapping = v end) +local trace_vpacking = false trackers.register("builders.vpacking", function(v) trace_vpacking = v end) local report_vspacing = logs.new("vspacing") local report_collapser = logs.new("collapser") @@ -50,7 +54,7 @@ local skip_order = attributes.private('skip-order') local snap_category = attributes.private('snap-category') local display_math = attributes.private('display-math') local snap_method = attributes.private('snap-method') -local snap_done = attributes.private('snap-done') +local snap_vbox = attributes.private('snap-vbox') local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute @@ -63,31 +67,39 @@ local traverse_nodes_id = node.traverse_id local insert_node_before = node.insert_before local insert_node_after = node.insert_after local remove_node = nodes.remove -local make_penalty_node = nodes.penalty -local make_kern_node = nodes.kern -local make_rule_node = nodes.rule local count_nodes = nodes.count local node_ids_to_string = nodes.ids_to_string local hpack_node = node.hpack local vpack_node = node.vpack local writable_spec = nodes.writable_spec +local list_to_utf = nodes.list_to_utf -local nodecodes = nodes.nodecodes +local nodepool = nodes.pool + +local new_penalty = nodepool.penalty +local new_kern = nodepool.kern +local new_rule = nodepool.rule + +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes +local fillcodes = nodes.fillcodes + +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local whatsit_code = nodecodes.whatsit -local glyph = nodecodes.glyph -local penalty = nodecodes.penalty -local kern = nodecodes.kern -local glue = nodecodes.glue -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist -local adjust = nodecodes.adjust +local userskip_code = skipcodes.userskip -vspacing = vspacing or { } -vspacing.data = vspacing.data or { } +builders.vspacing = builders.vspacing or { } +local vspacing = builders.vspacing +vspacing.data = vspacing.data or { } vspacing.data.snapmethods = vspacing.data.snapmethods or { } -storage.register("vspacing/data/snapmethods", vspacing.data.snapmethods, "vspacing.data.snapmethods") +storage.register("builders/vspacing/data/snapmethods", vspacing.data.snapmethods, "builders.vspacing.data.snapmethods") local snapmethods = vspacing.data.snapmethods --maybe some older code can go @@ -170,14 +182,92 @@ end --~ end --~ end -local function snap_hlist(current,method,height,depth) -- method.strut is default - local snapht, snapdp +local reference = nodes.reference + +local function validvbox(parentid,list) + if parentid == hlist_code then + local id = list.id + if id == whatsit_code then -- check for initial par subtype + list = list.next + if not next then + return nil + end + end + local done = nil + for n in traverse_nodes(list) do + local id = n.id + if id == vlist_code or id == hlist_code then + if done then + return nil + else + done = n + end + elseif id == penalty_code or id == glue_code then + -- go on + else + return nil -- whatever + end + end + if done and done.id == hlist_code then + return validvbox(done.id,done.list) + end + return done -- only one vbox + end +end + +local function already_done(parentid,list,snap_method) -- todo: done when only boxes and all snapped + -- problem: any snapped vbox ends up in a line + if list and parentid == hlist_code then + local id = list.id + if id == whatsit_code then -- check for initial par subtype + list = list.next + if not next then + return false + end + end +--~ local i = 0 + for n in traverse_nodes(list) do + local id = n.id +--~ i = i + 1 print(i,nodecodes[id],has_attribute(n,snap_method)) + if id == hlist_code or id == vlist_code then + local a = has_attribute(n,snap_method) + if not a then + -- return true -- not snapped at all + elseif a == 0 then + return true -- already snapped + end + elseif id == penalty_code or id == glue_code then -- whatsit is weak spot + -- go on + else + return false -- whatever + end + end + end + return false +end + +local function snap_hlist(where,current,method,height,depth) -- method.strut is default + local list = current.list --~ print(table.serialize(method)) + local t = trace_vsnapping and { } + if t then + t[#t+1] = format("list content: %s",nodes.toutf(list)) + t[#t+1] = format("parent id: %s",reference(current)) + t[#t+1] = format("snap method: %s",method.name) + t[#t+1] = format("specification: %s",method.specification) + end + local snapht, snapdp if method["local"] then -- snapping is done immediately here snapht, snapdp = texdimen.bodyfontstrutheight, texdimen.bodyfontstrutdepth + if t then + t[#t+1] = format("local: snapht %s snapdp %s",points(snapht),points(snapdp)) + end elseif method["global"] then snapht, snapdp = texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth + if t then + t[#t+1] = format("global: snapht %s snapdp %s",points(snapht),points(snapdp)) + end else -- maybe autolocal -- snapping might happen later in the otr @@ -186,110 +276,203 @@ local function snap_hlist(current,method,height,depth) -- method.strut is defaul if snapht ~= lsnapht and snapdp ~= lsnapdp then snapht, snapdp = lsnapht, lsnapdp end + if t then + t[#t+1] = format("auto: snapht %s snapdp %s",points(snapht),points(snapdp)) + end end local h, d = height or current.height, depth or current.depth local hr, dr, ch, cd = method.hfraction or 1, method.dfraction or 1, h, d local tlines, blines = method.tlines or 1, method.blines or 1 local done, plusht, plusdp = false, snapht, snapdp local snaphtdp = snapht + snapdp + if method.none then plusht, plusdp = 0, 0 + if t then + t[#t+1] = format("none: plusht 0pt plusdp 0pt") + end end - if method.halfline then + if method.halfline then -- extra halfline plusht, plusdp = plusht + snaphtdp/2, plusdp + snaphtdp/2 + if t then + t[#t+1] = format("halfline: plusht %s plusdp %s",points(plusht),points(plusdp)) + end end - if method.line then + if method.line then -- extra line plusht, plusdp = plusht + snaphtdp, plusdp + snaphtdp + if t then + t[#t+1] = format("line: plusht %s plusdp %s",points(plusht),points(plusdp)) + end end if method.first then - if current.id == vlist then - local list, lh, ld = current.list - for n in traverse_nodes_id(hlist,list) do + local thebox = current + local id = thebox.id + if id == hlist_code then + thebox = validvbox(id,thebox.list) + id = thebox and thebox.id + end + if thebox and id == vlist_code then + local list, lh, ld = thebox.list + for n in traverse_nodes_id(hlist_code,list) do lh, ld = n.height, n.depth break end if lh then - local x = max(ceil((lh-hr*snapht)/snaphtdp),0)*snaphtdp + plusht - local n = make_kern_node(x-lh) - n.next, list.prev, current.list = list, n, n - ch = x + snaphtdp - cd = max(ceil((d+h-lh-dr*snapdp-hr*snapht)/snaphtdp),0)*snaphtdp + plusdp + local ht, dp = thebox.height, thebox.depth + if t then + t[#t+1] = format("first line: height %s depth %s",points(lh),points(ld)) + t[#t+1] = format("dimensions: height %s depth %s",points(ht),points(dp)) + end + local delta = h - lh + ch, cd = lh, delta + d +--~ ch = ch + plusht +--~ cd = cd + plusdp +h, d = ch, cd + local shifted = hpack_node(current.list) + shifted.shift = delta + current.list = shifted done = true + if t then + t[#t+1] = format("first: height %s depth %s shift %s",points(ch),points(cd),points(delta)) + end + elseif t then + t[#t+1] = "first: not done, no content" end + elseif t then + t[#t+1] = "first: not done, no vbox" end elseif method.last then - if current.id == vlist then - local list, lh, ld = current.list - for n in traverse_nodes_id(hlist,list) do + local thebox = current + local id = thebox.id + if id == hlist_code then + thebox = validvbox(id,thebox.list) + id = thebox and thebox.id + end + if thebox and id == vlist_code then + local list, lh, ld = thebox.list + for n in traverse_nodes_id(hlist_code,list) do lh, ld = n.height, n.depth end if lh then - local baseline_till_top = h + d - ld - local x = max(ceil((baseline_till_top-hr*snapht)/snaphtdp),0)*snaphtdp + plusht - local n = make_kern_node(x-baseline_till_top) - n.next, list.prev, current.list = list, n, n - ch = x - cd = max(ceil((ld-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + local ht, dp = thebox.height, thebox.depth + if t then + t[#t+1] = format("last line: height %s depth %s",points(lh),points(ld)) + t[#t+1] = format("dimensions: height %s depth %s",points(ht),points(dp)) + end + local delta = d - ld + cd, ch = ld, delta + h +--~ ch = ch + plusht +--~ cd = cd + plusdp +h, d = ch, cd + local shifted = hpack_node(current.list) + shifted.shift = delta + current.list = shifted done = true + if t then + t[#t+1] = format("last: height %s depth %s shift %s",points(ch),points(cd),points(delta)) + end + elseif t then + t[#t+1] = "last: not done, no content" end + elseif t then + t[#t+1] = "last: not done, no vbox" end end - if done then - -- first or last - elseif method.minheight then +--~ if done then +--~ -- first or last +--~ else + if method.minheight then ch = max(floor((h-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + if t then + t[#t+1] = format("minheight: %s",points(ch)) + end elseif method.maxheight then ch = max(ceil((h-hr*snapht)/snaphtdp),0)*snaphtdp + plusht + if t then + t[#t+1] = format("maxheight: %s",points(ch)) + end else ch = plusht + if t then + t[#t+1] = format("set height: %s",points(ch)) + end end - if done then - -- first or last - elseif method.mindepth then +--~ if done then +--~ -- first or last +--~ else + if method.mindepth then cd = max(floor((d-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + if t then + t[#t+1] = format("mindepth: %s",points(cd)) + end elseif method.maxdepth then cd = max(ceil((d-dr*snapdp)/snaphtdp),0)*snaphtdp + plusdp + if t then + t[#t+1] = format("maxdepth: %s",points(cd)) + end else cd = plusdp + if t then + t[#t+1] = format("set depth: %s",points(cd)) + end end if method.top then ch = ch + tlines * snaphtdp + if t then + t[#t+1] = format("top height: %s",points(ch)) + end end if method.bottom then cd = cd + blines * snaphtdp + if t then + t[#t+1] = format("bottom depth: %s",points(cd)) + end end local offset = method.offset if offset then -- we need to set the attr - local shifted = vpack_node(current.list) + if t then + t[#t+1] = format("before offset: %s (width %s height %s depth %s)", + points(offset),points(current.width),points(current.height),points(current.depth)) + end + local shifted = hpack_node(current.list) shifted.shift = offset current.list = shifted + if t then + t[#t+1] = format("after offset: %s (width %s height %s depth %s)", + points(offset),points(current.width),points(current.height),points(current.depth)) + end + set_attribute(shifted,snap_method,0) + set_attribute(current,snap_method,0) end if not height then current.height = ch + if t then + t[#t+1] = format("forced height: %s",points(ch)) + end end if not depth then current.depth = cd + if t then + t[#t+1] = format("forced depth: %s",points(cd)) + end + end + local lines = (ch+cd)/snaphtdp + if t then + local original = (h+d)/snaphtdp + t[#t+1] = format("final lines: %s -> %s",original,lines) + t[#t+1] = format("final height: %s -> %s",points(h),points(ch)) + t[#t+1] = format("final depth: %s -> %s",points(d),points(cd)) end - -- set_attribute(current,snap_method,0) - return h, d, ch, cd, (ch+cd)/snaphtdp + if t then + report_snapper("trace: %s type %s\n\t%s",where,nodecodes[current.id],concat(t,"\n\t")) + end + return h, d, ch, cd, lines end ---~ local function snap_topskip(current,method) ---~ local spec = current.spec ---~ local w = spec.width ---~ local wd = w ---~ if spec then ---~ wd = 0 ---~ spec = writable_spec(current) ---~ spec.width = wd ---~ end ---~ return w, wd ---~ end - local function snap_topskip(current,method) local spec = current.spec local w = spec.width @@ -338,8 +521,8 @@ end vspacing.data.map = vspacing.data.map or { } vspacing.data.skip = vspacing.data.skip or { } -storage.register("vspacing/data/map", vspacing.data.map, "vspacing.data.map") -storage.register("vspacing/data/skip", vspacing.data.skip, "vspacing.data.skip") +storage.register("builders/vspacing/data/map", vspacing.data.map, "builders.vspacing.data.map") +storage.register("builders/vspacing/data/skip", vspacing.data.skip, "builders.vspacing.data.skip") do -- todo: interface.variables @@ -443,15 +626,14 @@ local trace_list, tracing_info, before, after = { }, false, "", "" local function glue_to_string(glue) local spec = glue.spec - local t = { } - t[#t+1] = aux.strip_zeros(number.topoints(spec.width)) + local t = { points(spec.width) } if spec.stretch_order and spec.stretch_order ~= 0 then - t[#t+1] = format("plus -%sfi%s",spec.stretch/65536,string.rep("l",math.abs(spec.stretch_order)-1)) + t[#t+1] = format("plus %s%s",spec.stretch/65536,fillcodes[spec.stretch_order]) elseif spec.stretch and spec.stretch ~= 0 then t[#t+1] = format("plus %s",aux.strip_zeros(number.topoints(spec.stretch))) end if spec.shrink_order and spec.shrink_order ~= 0 then - t[#t+1] = format("minus -%sfi%s",spec.shrink/65536,string.rep("l",math.abs(spec.shrink_order)-1)) + t[#t+1] = format("minus %s%s",spec.shrink/65536,fillcodes[spec.shrink_order]) elseif spec.shrink and spec.shrink ~= 0 then t[#t+1] = format("minus %s",aux.strip_zeros(number.topoints(spec.shrink))) end @@ -463,11 +645,11 @@ local function nodes_to_string(head) while current do local id = current.id local ty = node.type(id) - if id == penalty then + if id == penalty_code then t[#t+1] = format("%s:%s",ty,current.penalty) - elseif id == glue then + elseif id == glue_code then t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width))) - elseif id == kern then + elseif id == kern_code then t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.kern))) else t[#t+1] = ty @@ -506,7 +688,7 @@ local function trace_node(what) end local function trace_done(str,data) - if data.id == penalty then + if data.id == penalty_code then trace_list[#trace_list+1] = { "penalty", format("%s | %s", str, data.penalty) } else trace_list[#trace_list+1] = { "glue", format("%s | %s", str, glue_to_string(data)) } @@ -555,20 +737,30 @@ function vspacing.snap_box(n,how) if sv then local box = texbox[n] local list = box.list ---~ if list and (list.id == hlist or list.id == vlist) then if list then local s = has_attribute(list,snap_method) if s == 0 then if trace_vsnapping then - -- report_snapper("hlist not snapped, already done") + -- report_snapper("box list not snapped, already done") end else - local h, d, ch, cd, lines = snap_hlist(box,sv,box.height,box.depth) - box.height, box.depth = ch, cd - if trace_vsnapping then - report_snapper("hlist snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines)",h,d,ch,cd,sv.name,sv.specification,"direct",lines) + local ht, dp = box.height, box.depth + if false then -- todo: already_done + -- assume that the box is already snapped + if trace_vsnapping then + report_snapper("box list already snapped at (%s,%s): %s", + ht,dp,list_to_utf(list)) + end + else + local h, d, ch, cd, lines = snap_hlist("box",box,sv,ht,dp) + box.height, box.depth = ch, cd + if trace_vsnapping then + report_snapper("box list snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines): %s", + h,d,ch,cd,sv.name,sv.specification,"direct",lines,list_to_utf(list)) + end + set_attribute(box, snap_method,0) -- + set_attribute(list,snap_method,0) -- yes or no end - set_attribute(list,snap_method,0) end end end @@ -576,14 +768,14 @@ end local function forced_skip(head,current,width,where,trace) if where == "after" then - head, current = insert_node_after(head,current,make_rule_node(0,0,0)) - head, current = insert_node_after(head,current,make_kern_node(width)) - head, current = insert_node_after(head,current,make_rule_node(0,0,0)) + head, current = insert_node_after(head,current,new_rule(0,0,0)) + head, current = insert_node_after(head,current,new_kern(width)) + head, current = insert_node_after(head,current,new_rule(0,0,0)) else local c = current - head, current = insert_node_before(head,current,make_rule_node(0,0,0)) - head, current = insert_node_before(head,current,make_kern_node(width)) - head, current = insert_node_before(head,current,make_rule_node(0,0,0)) + head, current = insert_node_before(head,current,new_rule(0,0,0)) + head, current = insert_node_before(head,current,new_kern(width)) + head, current = insert_node_before(head,current,new_rule(0,0,0)) current = c end if trace then @@ -592,7 +784,7 @@ local function forced_skip(head,current,width,where,trace) return head, current end -local function collapser(head,where,what,trace,snap) -- maybe also pass tail +local function collapser(head,where,what,trace,snap,snap_method) -- maybe also pass tail if trace then reset_tracing(head) end @@ -605,7 +797,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail -- local function flush(why) if penalty_data then - local p = make_penalty_node(penalty_data) + local p = new_penalty(penalty_data) if trace then trace_done("flushed due to " .. why,p) end head = insert_node_before(head,current,p) end @@ -634,27 +826,38 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail if trace then trace_info("start analyzing",where,what) end while current do local id, subtype = current.id, current.subtype - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then -- needs checking, why so many calls if snap then + local list = current.list local s = has_attribute(current,snap_method) if not s then -- if trace_vsnapping then - -- report_snapper("hlist not snapped") + -- report_snapper("mvl list not snapped") -- end elseif s == 0 then if trace_vsnapping then - -- report_snapper("hlist not snapped, already done") + report_snapper("mvl %s not snapped, already done: %s",nodecodes[id],list_to_utf(list)) end else local sv = snapmethods[s] if sv then - local h, d, ch, cd, lines = snap_hlist(current,sv) - if trace_vsnapping then - report_snapper("hlist snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines)",h,d,ch,cd,sv.name,sv.specification,where,lines) +-- check if already snapped + if list and already_done(id,list,snap_method) then + local ht, dp = current.height, current.depth + -- assume that the box is already snapped + if trace_vsnapping then + report_snapper("mvl list already snapped at (%s,%s): %s",ht,dp,list_to_utf(list)) + end + else + local h, d, ch, cd, lines = snap_hlist("mvl",current,sv) + if trace_vsnapping then + report_snapper("mvl %s snapped from (%s,%s) to (%s,%s) using method '%s' (%s) for '%s' (%s lines): %s", + nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,list_to_utf(list)) + end end elseif trace_vsnapping then - report_snapper("hlist not snapped due to unknown snap specification") + report_snapper("mvl %s not snapped due to unknown snap specification: %s",nodecodes[id],list_to_utf(list)) end set_attribute(current,snap_method,0) end @@ -664,19 +867,19 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail -- tex.prevdepth = 0 flush("list") current = current.next - elseif id == penalty then + elseif id == penalty_code then --~ natural_penalty = current.penalty --~ if trace then trace_done("removed penalty",current) end --~ head, current = remove_node(head, current, true) current = current.next - elseif id == kern then + elseif id == kern_code then if snap and trace_vsnapping and current.kern ~= 0 then --~ current.kern = 0 report_snapper("kern of %s (kept)",current.kern) end flush("kern") current = current.next - elseif id ~= glue then + elseif id ~= glue_code then flush("something else") current = current.next elseif subtype == userskip_code then -- todo, other subtypes, like math @@ -702,7 +905,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail else -- not look back across head local previous = current.prev - if previous and previous.id == glue and previous.subtype == 0 then + if previous and previous.id == glue_code and previous.subtype == userskip_code then local ps = previous.spec if ps.writable then local cs = current.spec @@ -928,7 +1131,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail local tail if penalty_data then tail = find_node_tail(head) - local p = make_penalty_node(penalty_data) + local p = new_penalty(penalty_data) if trace then trace_done("result",p) end head, tail = insert_node_after(head,tail,p) end @@ -970,7 +1173,7 @@ local function report(message,lst) report_vspacing(message,count_nodes(lst,true),node_ids_to_string(lst)) end -function nodes.handle_page_spacing(newhead,where) +function nodes.handlers.pagespacing(newhead,where) --~ local newhead = texlists.contrib_head if newhead then --~ starttiming(vspacing) @@ -979,8 +1182,8 @@ function nodes.handle_page_spacing(newhead,where) stackhack = true -- todo: only when grid snapping once enabled for n in traverse_nodes(newhead) do -- we could just look for glue nodes local id = n.id - if id == glue then - if n.subtype == 0 then + if id == glue_code then + if n.subtype == userskip_code then if has_attribute(n,skip_category) then stackhack = true else @@ -1004,8 +1207,8 @@ function nodes.handle_page_spacing(newhead,where) if stackhack then stackhack = false if trace_collect_vspacing then report("processing %s nodes: %s",newhead) end ---~ texlists.contrib_head = collapser(newhead,"page",where,trace_page_vspacing,true) -newhead = collapser(newhead,"page",where,trace_page_vspacing,true) +--~ texlists.contrib_head = collapser(newhead,"page",where,trace_page_vspacing,true,snap_method) + newhead = collapser(newhead,"page",where,trace_page_vspacing,true,snap_method) else if trace_collect_vspacing then report("flushing %s nodes: %s",newhead) end --~ texlists.contrib_head = newhead @@ -1034,44 +1237,45 @@ local ignore = table.tohash { -- "vbox", } -function nodes.handle_vbox_spacing(head,where) +function nodes.handlers.vboxspacing(head,where) if head and not ignore[where] and head.next then -- starttiming(vspacing) - head = collapser(head,"vbox",where,trace_vbox_vspacing,false) + head = collapser(head,"vbox",where,trace_vbox_vspacing,true,snap_vbox) -- todo: local snapper -- stoptiming(vspacing) end return head end -function nodes.collapse_vbox(n) -- for boxes +function nodes.collapse_vbox(n) -- for boxes but using global snap_method local list = texbox[n].list if list then -- starttiming(vspacing) - texbox[n].list = vpack_node(collapser(list,"snapper","vbox",trace_vbox_vspacing,true)) + texbox[n].list = vpack_node(collapser(list,"snapper","vbox",trace_vbox_vspacing,true,snap_method)) -- stoptiming(vspacing) end end --- we will split this module hence the locals +-- We will split this module so a few locals are repeated. Also this will be +-- rewritten. local attribute = attributes.private('graphicvadjust') local nodecodes = nodes.nodecodes -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist local remove_node = nodes.remove local hpack_node = node.hpack local vpack_node = node.vpack local has_attribute = node.has_attribute -function nodes.repackage_graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only +function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only if groupcode == "" then -- mvl only local h, p, done = head, nil, false while h do local id = h.id - if id == hlist or id == vlist then + if id == hlist_code or id == vlist_code then local a = has_attribute(h,attribute) if a then if p then @@ -1104,7 +1308,7 @@ function nodes.repackage_graphicvadjust(head,groupcode) -- we can make an action end end ---~ function nodes.repackage_graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only +--~ function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only --~ if groupcode == "" then -- mvl only --~ return head, false --~ else @@ -1112,13 +1316,13 @@ end --~ end --~ end ---~ tasks.appendaction("finalizers", "lists", "nodes.repackage_graphicvadjust") +--~ nodes.tasks.appendaction("finalizers", "lists", "nodes.handlers.graphicvadjust") nodes.builders = nodes.builder or { } local builders = nodes.builders -local actions = tasks.actions("vboxbuilders",5) +local actions = nodes.tasks.actions("vboxbuilders",5) function nodes.builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction) local done = false @@ -1146,7 +1350,7 @@ end -- and we operate on the mlv. Also, we need to do the -- vspacing last as it removes items from the mvl. -local actions = tasks.actions("mvlbuilders",1) +local actions = nodes.tasks.actions("mvlbuilders",1) function nodes.builders.buildpage_filter(groupcode) starttiming(builders) diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index 70abd4f16..e7d54975a 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -1336,7 +1336,7 @@ \definesystemattribute[skip-order] \chardef\skiporderattribute \dogetattributeid{skip-order} \definesystemattribute[display-math] \chardef\displaymathattribute \dogetattributeid{display-math} \definesystemattribute[snap-method] \chardef\snapmethodattribute \dogetattributeid{snap-method} -\definesystemattribute[snap-done] \chardef\snapdoneattribute \dogetattributeid{snap-done} +\definesystemattribute[snap-vbox] \chardef\snapvboxattribute \dogetattributeid{snap-vbox} %definesystemattribute[snap-category] \chardef\snapcategoryattribute \dogetattributeid{snap-category} @@ -1350,6 +1350,17 @@ \newdimen \globalbodyfontstrutheight \newdimen \globalbodyfontstrutdepth +\def\snappedvboxattribute{\ifgridsnapping attr \snapvboxattribute \attribute\snapmethodattribute\fi} +\def\setlocalgridsnapping{\ifgridsnapping \attribute \snapvboxattribute \attribute\snapmethodattribute\fi} + +\def\dosetlocalgridsnapping#1% + {\ifgridsnapping + \doifsomething{#1}% + {\autosetsnapvalue{#1}% + \attribute \snapvboxattribute \attribute\snapmethodattribute}% + \fi} + + % \appendtoks % \dosetupgridsnapping % \to \everysetupbodyfont @@ -1357,7 +1368,7 @@ \def\installsnapvalues#1#2% todo: a proper define {\edef\currentsnapper{#1:#2}% \ifcsname\currentsnapper\endcsname \else - \setevalue\currentsnapper{\ctxlua{vspacing.define_snap_method("#1","#2")}}% + \setevalue\currentsnapper{\ctxlua{builders.vspacing.define_snap_method("#1","#2")}}% \fi \setevalue{\??gr:#1}{\attribute\snapmethodattribute\csname\currentsnapper\endcsname\space}} @@ -1472,7 +1483,7 @@ {} % gone, unless we set an attribute \def\doplaceongrid[#1]% - {\snaptogrid[#1]\vbox} + {\snaptogrid[#1]\vbox} % mark as done \def\dosnaptogrid[#1]% list or predefined {\ifgridsnapping @@ -1489,21 +1500,12 @@ % eventually there will always be a line snap \def\dododosnaptogrid#1% - {\ifvbox\nextbox - \ctxlua{nodes.collapse_vbox(\number\nextbox)}% + {\ifvbox\nextbox % this will go away + \ctxlua{nodes.collapse_vbox(\number\nextbox)}% isn't that already done? \fi \doifelsenothing{#1}{\setsnapvalue\v!normal}{\autosetsnapvalue{#1}}% - \ctxlua{vspacing.snap_box(\number\nextbox,\number\attribute\snapmethodattribute)}% -% \ifzeropt\ht\nextbox -% \ifzeropt\dp\nextbox -% \box\nextbox % here, else empty and zero -% \kern-\bodyfontlineheight -% \else -% \box\nextbox -% \fi -% \else - \box\nextbox -% \fi + \ctxlua{builders.vspacing.snap_box(\number\nextbox,\number\attribute\snapmethodattribute)}% + \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% \egroup} \def\docheckgridsnapping @@ -1638,7 +1640,7 @@ % % \defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi} -% todo, in grid mode: vspacing.fixed = false +% todo, in grid mode: builders.vspacing.fixed = false \let\saveouterspacing \relax % for old times sake \let\restoreouterspacing\relax % for old times sake @@ -1739,11 +1741,11 @@ {\dotripleempty\dodefinevspacingamount} % \def\dodefinevspacingamount[#1][#2][#3]% -% {\ctxlua{vspacing.setskip("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} +% {\ctxlua{builders.vspacing.setskip("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} \def\dodefinevspacingamount[#1][#2][#3]% can be combined {\setvalue{\??vs:#1}{\ifgridsnapping#3\else#2\fi}% - \ctxlua{vspacing.setskip("#1")}} + \ctxlua{builders.vspacing.setskip("#1")}} \def\addpredefinedblankskip#1#2% {\settrue\someblankdone @@ -1757,7 +1759,7 @@ {\dodoubleempty\dodefinevspacing} \def\dodefinevspacing[#1][#2]% - {\ctxlua{vspacing.setmap("#1","#2")}} + {\ctxlua{builders.vspacing.setmap("#1","#2")}} \unexpanded\def\vspacing {\dosingleempty\dovspacing} @@ -1774,8 +1776,8 @@ \fi\fi} \def\dovspacingyes[#1]% - %{\ifmmode\else\ctxlua{vspacing.analyse("\iffirstargument#1\else\s!default\fi")}\fi} - {\ifmmode\else\ctxlua{vspacing.analyse("\iffirstargument#1\else\currentvspacing\fi")}\fi} + %{\ifmmode\else\ctxlua{builders.vspacing.analyse("\iffirstargument#1\else\s!default\fi")}\fi} + {\ifmmode\else\ctxlua{builders.vspacing.analyse("\iffirstargument#1\else\currentvspacing\fi")}\fi} \def\dovspacingnop[#1]% {\ifmmode\else\par\fi} @@ -1868,13 +1870,13 @@ % \appendtoks % \writestatus\m!systems{! ! enabling vspacing ! !}% % \settrue\vspacingenabled -% \ctxlua{vspacing.enable()}% +% \ctxlua{builders.vspacing.enable()}% % \to \everyenablevspacing % % \appendtoks % \writestatus\m!systems{! ! disabling vspacing ! !}% % \setfalse\vspacingenabled -% \ctxlua{vspacing.disable()}% +% \ctxlua{builders.vspacing.disable()}% % \to \everydisablevspacing \let\blank \vspacing diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua index 5fe9325a6..77d616260 100644 --- a/tex/context/base/strc-bkm.lua +++ b/tex/context/base/strc-bkm.lua @@ -11,18 +11,29 @@ if not modules then modules = { } end modules ['strc-bkm'] = { -- this should become proper separated backend code +-- we should hook the placement into everystoptext ... needs checking + local format, concat, gsub = string.format, table.concat, string.gsub local texsprint, utfvalues = tex.sprint, string.utfvalues - local ctxcatcodes = tex.ctxcatcodes +local settings_to_hash = utilities.parsers.settings_to_hash + +local codeinjections = backends.codeinjections + +local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) -local lists = structure.lists -local levelmap = structure.sections.levelmap -local variables = interfaces.variables +local report_bookmarks = logs.new("bookmarks") -structure.bookmarks = structure.bookmarks or { } +local structures = structures -local bookmarks = structure.bookmarks +structures.bookmarks = structures.bookmarks or { } + +local bookmarks = structures.bookmarks +local sections = structures.sections +local lists = structures.lists + +local levelmap = sections.levelmap +local variables = interfaces.variables bookmarks.method = "internal" -- or "page" @@ -32,7 +43,7 @@ function bookmarks.register(settings) local force = settings.force == variables.yes local number = settings.number == variables.yes local allopen = settings.opened == variables.all - for k, v in next, aux.settings_to_hash(settings.names or "") do + for k, v in next, settings_to_hash(settings.names or "") do names[k] = true if force then forced[k] = true @@ -45,7 +56,7 @@ function bookmarks.register(settings) end end if not allopen then - for k, v in next, aux.settings_to_hash(settings.opened or "") do + for k, v in next, settings_to_hash(settings.opened or "") do opened[k] = true end end @@ -84,7 +95,7 @@ end local numberspec = { } -function structure.bookmarks.setup(spec) +function bookmarks.setup(spec) -- table.merge(numberspec,spec) for k, v in next, spec do numberspec[k] = v @@ -116,11 +127,11 @@ function bookmarks.place() end end if numbered[name] then - local sectiondata = jobsections.collected[li.references.section] + local sectiondata = sections.collected[li.references.section] local numberdata = li.numberdata if sectiondata and numberdata and not numberdata.hidenumber then -- we could typeset the number and convert it - title = concat(structure.sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata)) .. " " .. title + title = concat(sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata)) .. " " .. title end end levels[#levels+1] = { @@ -132,17 +143,49 @@ function bookmarks.place() end end end +--~ print(table.serialize(levels)) bookmarks.finalize(levels) end function bookmarks.place() end -- prevent second run end end +function bookmarks.flatten(levels) + -- This function promotes leading structurelements with a higher level + -- to the next lower level. Such situations are the result of lack of + -- structure: a subject preceding a chapter in a sectionblock. So, the + -- following code runs over section blocks as well. (bookmarks-007.tex) + local noflevels = #levels + if noflevels > 1 then + local skip, start, one = false, 1, levels[1] + local first, block = one[1], one[3].block + for i=2,noflevels do + local li = levels[i] + local new, newblock = li[1], li[3].block + if newblock ~= block then + first, block, start, skip = new, newblock, i, false + elseif skip then + -- go on + elseif new > first then + skip = true + elseif new < first then + for j=start,i-1 do + local lj = levels[j] + local old = lj[1] + lj[1] = new + if trace_bookmarks then + report_bookmarks("promoting entry %s from level %s to %s: %s",j,old,new,lj[2]) + end + end + skip = true + end + end + end +end + function bookmarks.finalize(levels) -- This function can be overloaded by an optional converter -- that uses nodes.toutf on a typeset stream. This is something -- that we will support when the main loop has become a coroutine. - backends.codeinjections.addbookmarks(levels,bookmarks.method) + codeinjections.addbookmarks(levels,bookmarks.method) end - -lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1,"bookmarks") diff --git a/tex/context/base/strc-bkm.mkiv b/tex/context/base/strc-bkm.mkiv index f0cfa2a2f..b7a5bc805 100644 --- a/tex/context/base/strc-bkm.mkiv +++ b/tex/context/base/strc-bkm.mkiv @@ -50,7 +50,7 @@ \def\dobookmark[#1]#2% {\begingroup \simplifycommands - \ctxlua{structure.bookmarks.overload("#1",\!!bs\detokenize\expandafter{\normalexpanded{#2}}\!!es)}% + \ctxlua{structures.bookmarks.overload("#1",\!!bs\detokenize\expandafter{\normalexpanded{#2}}\!!es)}% \endgroup} %D Placement \unknown\ look how simple compared to \MKII: @@ -66,6 +66,10 @@ \unexpanded\def\placebookmarks {\dotripleempty\doplacebookmarks} +% Use force to get titles in the bookmarklist. This is somewhat tricky as one +% does not want "Contents" in a table of contents but it has to be in the +% bookmark list. + \def\doplacebookmarks[#1][#2][#3]% {\iflocation \begingroup @@ -82,7 +86,7 @@ \else\ifsecondargument \doifassignmentelse{#2}{\let\askedopened\empty\getparameters[\??bm][#2]}\donothing \fi\fi - \ctxlua{structure.bookmarks.register { + \ctxlua{structures.bookmarks.register { names = "\askednames", opened = "\askedopened", force = "\bookmarkparameter\c!force", @@ -96,7 +100,7 @@ \c!number=\v!yes] % might become v!no \appendtoks - \ctxlua{structure.bookmarks.setup { + \ctxlua{structures.bookmarks.setup { separatorset = "\bookmarkparameter\c!numberseparatorset", conversionset = "\bookmarkparameter\c!numberconversionset", starter = \!!bs\bookmarkparameter\c!numberstarter\!!es, @@ -105,8 +109,8 @@ }}% \to \everysetupbookmarks -% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext % too late -% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everylastbackendshipout % okay but not nice +% \prependtoks\ctxlua{structures.bookmarks.place()}\to\everystoptext % too late +% \prependtoks\ctxlua{structures.bookmarks.place()}\to\everylastbackendshipout % okay but not nice \protect \endinput diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua index 25c4f2cae..dc2abf17e 100644 --- a/tex/context/base/strc-blk.lua +++ b/tex/context/base/strc-blk.lua @@ -10,13 +10,17 @@ if not modules then modules = { } end modules ['strc--blk'] = { local texprint, format, gmatch, find = tex.print, string.format, string.gmatch, string.find local lpegmatch = lpeg.match +local settings_to_set, settings_to_array = utilities.parsers.settings_to_set, utilities.parsers.settings_to_array local ctxcatcodes = tex.ctxcatcodes -structure = structure or { } -structure.blocks = structure.blocks or { } +local structures = structures -local blocks = structure.blocks +structures.blocks = structures.blocks or { } + +local blocks = structures.blocks +local sections = structures.sections +local lists = structures.lists blocks.collected = blocks.collected or { } blocks.tobesaved = blocks.tobesaved or { } @@ -28,7 +32,7 @@ local function initializer() collected, tobesaved = blocks.collected, blocks.tobesaved end -job.register('structure.blocks.collected', structure.blocks.tobesaved, initializer) +job.register('structures.blocks.collected', blocks.tobesaved, initializer) local printer = (lpeg.patterns.textline/texprint)^0 -- can be shared @@ -58,7 +62,7 @@ end function blocks.setstate(state,name,tag) local all = tag == "" - local tags = not all and aux.settings_to_array(tag) + local tags = not all and settings_to_array(tag) for n in gmatch(name,"%s*([^,]+)") do local sn = states[n] if not sn then @@ -76,12 +80,12 @@ end function blocks.select(state,name,tag,criterium) criterium = criterium or "text" if find(tag,"=") then tag = "" end - local names = aux.settings_to_set(name) + local names = settings_to_set(name) local all = tag == "" - local tags = not all and aux.settings_to_set(tag) + local tags = not all and settings_to_set(tag) local hide = state == "process" - local n = structure.sections.number_at_depth(criterium) - local result = structure.lists.filter_collected("all", criterium, n, collected, { }) + local n = sections.number_at_depth(criterium) + local result = lists.filter_collected("all", criterium, n, collected, { }) for i=1,#result do local ri = result[i] local metadata = ri.metadata @@ -103,7 +107,7 @@ end function blocks.save(name,tag,buffer) -- wrong, not yet adapted local data = buffers.data[buffer] - local tags = aux.settings_to_set(tag) + local tags = settings_to_set(tag) local plus, minus = false, false if tags['+'] then plus = true tags['+'] = nil end if tags['-'] then minus = true tags['-'] = nil end @@ -115,7 +119,7 @@ function blocks.save(name,tag,buffer) -- wrong, not yet adapted minus = minus, }, references = { - section = structure.sections.currentid(), + section = sections.currentid(), }, data = data or "error", } diff --git a/tex/context/base/strc-blk.mkiv b/tex/context/base/strc-blk.mkiv index 8aa856840..1f8bbd212 100644 --- a/tex/context/base/strc-blk.mkiv +++ b/tex/context/base/strc-blk.mkiv @@ -41,13 +41,13 @@ \c!inner=, \c!style=, \c!file=]% todo - \ctxlua{structure.blocks.define("#1")}% + \ctxlua{structures.blocks.define("#1")}% \setvalue{\e!begin#1}{\dodoubleempty\dobeginofblock[#1]}% \letvalue{\e!end#1}\relax} \long\def\dobeginofblock[#1][#2]% {\normalexpanded{\noexpand\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}} - {}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after + {}{\ctxlua{structures.blocks.save("#1","#2","@block@")}}}% before after \def\dostarthiddenblock {\startnointerference @@ -82,17 +82,17 @@ \egroup} \def\dosetblockstate[#1][#2][#3]% state name tag - {\ctxlua{structure.blocks.setstate("#1","#2","#3")}} + {\ctxlua{structures.blocks.setstate("#1","#2","#3")}} \def\doselectblocks[#1][#2][#3][#4]% state name tag setups {\bgroup \doifassignmentelse{#3} {\getparameters[\??tb\??tb][\c!criterium=\v!text,#3]% \def\doblocksetups##1{\getparameters[\??tb##1][#3]}% - \ctxlua{structure.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} + \ctxlua{structures.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} {\getparameters[\??tb\??tb][\c!criterium=\v!text,#4]% \def\doblocksetups##1{\getparameters[\??tb##1][#4]}% - \ctxlua{structure.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% + \ctxlua{structures.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% \egroup} % hide: save, if [+] also hidden execute diff --git a/tex/context/base/strc-des.mkiv b/tex/context/base/strc-des.mkiv index d528ffae9..0a5f197de 100644 --- a/tex/context/base/strc-des.mkiv +++ b/tex/context/base/strc-des.mkiv @@ -338,7 +338,7 @@ \fi \setbox\descriptionheadbox\hbox {\forgetall\dontcomplain - \trialtypesettingtrue + \settrialtypesetting \doifelsenothing{\descriptionparameter\c!sample} {\dodescriptionhandler\currentdescriptiontext}% {\dodescriptionhandler\currentdescriptionsample}}% @@ -529,7 +529,7 @@ \fi#1} \def\@@dododescriptiontext - {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} + {\ctxlua{structures.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} \def\@@dodescriptiontext {\begingroup @@ -650,13 +650,13 @@ \let\@@doenumerationhandler\@@dodescriptionhandler % \def\currentenumerationfullnumber -% {\ctxlua{structure.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} +% {\ctxlua{structures.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} \def\@@doenumerationnumber - {\ctxlua{structure.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} + {\ctxlua{structures.lists.savedprefixednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}} \def\@@dodoenumerationtext - {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} + {\ctxlua{structures.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}} \def\doenumerationnumber {\descriptionparameter\c!left @@ -726,7 +726,7 @@ \fi \fi} \def\skipenumerationcoupling[#1]% e.g. for questions with no answer - {\ctxlua{jobreferences.setnextorder("description","#1")}} + {\ctxlua{structures.references.setnextorder("description","#1")}} \def\showdnpuretext{\strut\descriptionparameter\c!text} % geen spatie \def\showdnlisttext{\descriptionparameter\c!listtext} % space in default @@ -752,7 +752,7 @@ \newif\ifnodescriptioncaption \def\doifelsedescriptioncomponent - {\ctxlua{structure.lists.doifstoredelse(currentdescriptionnumberentry)}} + {\ctxlua{structures.lists.doifstoredelse(currentdescriptionnumberentry)}} \def\dodescriptioncomponent {\doifelsedescriptioncomponent\nododescriptioncomponent\dododescriptioncomponent} @@ -828,11 +828,11 @@ \else %\setnextinternalreference \setnextinternalreferences{description}\currentdescriptionname % plural - \xdef\currentdescriptionnumberentry{\ctxlua{structure.lists.push{ + \xdef\currentdescriptionnumberentry{\ctxlua{structures.lists.push{ metadata = { kind = "description", name = "\currentdescriptionname", - level = structure.sections.currentlevel(), + level = structures.sections.currentlevel(), catcodes = \the\catcodetable, % \currentdirectionparameters }, @@ -842,7 +842,7 @@ reference = "\currentdescriptionreference", referenceprefix = "\referenceprefix", block = "\currentstructureblock", - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, titledata = { label = \!!bs\detokenize\expandafter{\currentdescriptionlabel }\!!es, @@ -865,7 +865,7 @@ connector = \!!bs\descriptionparameter\c!prefixconnector\!!es, }, numberdata = { - numbers = structure.counters.compact("\currentdescriptionnumber",nil,true), % ! number can be cloned + numbers = structures.counters.compact("\currentdescriptionnumber",nil,true), % ! number can be cloned separatorset = "\descriptionparameter\c!numberseparatorset", conversion = "\descriptionparameter\c!numberconversion", conversionset = "\descriptionparameter\c!numberconversionset", @@ -874,11 +874,11 @@ segments = "\descriptionparameter\c!numbersegments", }, \fi - userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#2}\!!es) } }}% - \xdef\currentdescriptionattribute {\ctxlua {tex.write(jobreferences.setinternalreference("\referenceprefix","\currentdescriptionreference",\nextinternalreference,"\@@iafocus"))}}% - \xdef\currentdescriptionsynchronize{\ctxlatelua{structure.lists.enhance(\currentdescriptionnumberentry)}}% + \xdef\currentdescriptionattribute {\ctxlua {tex.write(structures.references.setinternalreference("\referenceprefix","\currentdescriptionreference",\nextinternalreference,"\@@iafocus"))}}% + \xdef\currentdescriptionsynchronize{\ctxlatelua{structures.lists.enhance(\currentdescriptionnumberentry)}}% \fi \endgroup} @@ -887,8 +887,8 @@ % macros. \def\reinstatedescriptionnumberentry#1% - {\xdef\currentdescriptionattribute {\ctxlua {tex.write(jobreferences.getinternalreference(#1))}}% - \xdef\currentdescriptionsynchronize{\ctxlatelua{structure.lists.enhance(#1)}}} + {\xdef\currentdescriptionattribute {\ctxlua {tex.write(structures.references.getinternalreference(#1))}}% + \xdef\currentdescriptionsynchronize{\ctxlatelua{structures.lists.enhance(#1)}}} \installstructurelistprocessor{description}{\usestructurelistprocessor{number+title}} diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index 3b696fbb0..a40c69b99 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -21,23 +21,20 @@ local variables = interfaces.variables --~ if not trackers then trackers = { register = function() end } end -local trace_sectioning = false trackers.register("structure.sectioning", function(v) trace_sectioning = v end) -local trace_detail = false trackers.register("structure.detail", function(v) trace_detail = v end) +local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end) +local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end) local report_structure = logs.new("structure") -structure = structure or { } -structure.helpers = structure.helpers or { } -structure.documents = structure.documents or { } -structure.sections = structure.sections or { } -structure.sets = structure.sets or { } -structure.processors = structure.processors or { } +local structures = structures -local helpers = structure.helpers -local documents = structure.documents -local sections = structure.sections -local sets = structure.sets -local processors = structure.processors +local helpers = structures.helpers +local documents = structures.documents +local sections = structures.sections +local lists = structures.lists +local counters = structures.counters +local sets = structures.sets +local processors = structures.processors local sprintprocessor = processors.sprint local ignoreprocessor = processors.ignore @@ -73,17 +70,16 @@ documents.initialize() -- -- -- sections -- -- -- -jobsections = jobsections or { } -jobsections.collected = jobsections.collected or { } -jobsections.tobesaved = jobsections.tobesaved or { } +sections.collected = sections.collected or { } +sections.tobesaved = sections.tobesaved or { } -local collected, tobesaved = jobsections.collected, jobsections.tobesaved +local collected, tobesaved = sections.collected, sections.tobesaved --~ local function initializer() ---~ collected, tobesaved = jobsections.collected, jobsections.tobesaved +--~ collected, tobesaved = sections.collected, sections.tobesaved --~ end ---~ job.register('jobsections.collected', jobsections.tobesaved, initializer) +--~ job.register('structures.sections.collected', sections.tobesaved, initializer) function sections.currentid() return #tobesaved @@ -106,7 +102,7 @@ end function sections.load() setmetatable(collected,nil) - local l = structure.lists.collected + local l = lists.collected for i=1,#l do local li = l[i] local lm = li.metadata @@ -129,11 +125,11 @@ setmetatable(collected, { -- -structure.sections.levelmap = structure.sections.levelmap or { } +sections.levelmap = sections.levelmap or { } -local levelmap = structure.sections.levelmap +local levelmap = sections.levelmap -storage.register("structure/sections/levelmap", structure.sections.levelmap, "structure.sections.levelmap") +storage.register("structures/sections/levelmap", sections.levelmap, "structures.sections.levelmap") sections.verbose = true @@ -166,7 +162,7 @@ function sections.setblock(name) end function sections.pushblock(name) - structure.counters.check(0) -- we assume sane usage of \page between blocks + counters.check(0) -- we assume sane usage of \page between blocks local block = name or data.block data.blocks[#data.blocks+1] = block data.block = block @@ -250,7 +246,7 @@ function sections.somelevel(given) status[i] = nil end end - structure.counters.check(newdepth) + counters.check(newdepth) ownnumbers[newdepth] = given.numberdata.ownnumber or "" given.numberdata.ownnumber = nil data.depth = newdepth @@ -460,7 +456,7 @@ end -- -function structure.currentsectionnumber() -- brr, namespace wrong +function structures.currentsectionnumber() -- brr, namespace wrong local sc = sections.current() return sc and sc.numberdata end @@ -736,7 +732,7 @@ function sections.findnumber(depth,what) local data = data.status[depth or data.depth] if data then local index = data.references.section - local collected = jobsections.collected + local collected = sections.collected local sectiondata = collected[index] if sectiondata and sectiondata.hidenumber ~= true then -- can be nil if what == variables.first then diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv index b1f18e91b..154466dfe 100644 --- a/tex/context/base/strc-doc.mkiv +++ b/tex/context/base/strc-doc.mkiv @@ -63,6 +63,7 @@ \xdef\currentstructurelabel {\structureparameter\c!label}% \xdef\currentstructurereference {\structureparameter\c!reference}% \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}% + \xdef\currentstructurebackreference {\structureparameter\c!backreference}% \xdef\currentstructureshownumber {\structureparameter\c!number}% \xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}% \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}% @@ -102,12 +103,13 @@ \fi \setnextinternalreference \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly - structure.sections.somelevel { + structures.sections.somelevel { references = { internal = \nextinternalreference, block = "\currentstructureblock", reference = "\currentstructurereference", referenceprefix = "\currentstructurereferenceprefix", + backreference = "\currentstructurebackreference", }, directives = { resetset = "\structureparameter\c!sectionresetset", @@ -159,10 +161,10 @@ segments = "\structureparameter\c!sectionsegments", ownnumber = "\currentstructureownnumber", }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#2}\!!es) } }}% - \xdef\currentstructurelistnumber{\ctxlua{structure.lists.push(structure.sections.current())}}% + \xdef\currentstructurelistnumber{\ctxlua{structures.lists.push(structures.sections.current())}}% % \currentstructuresynchronize has to be called someplace, since it introduces a node \setstructuresynchronization\currentstructurelistnumber \structureparameter\c!command @@ -173,10 +175,10 @@ \let\previousstructurecounter\!!zerocount \def\setstructuresynchronization#1% - {\xdef\currentstructureattribute {\ctxlua {tex.write(jobreferences.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\@@iafocus"))}}% - \xdef\currentstructuresynchronize{\ctxlatelua{structure.lists.enhance(#1)}}} + {\xdef\currentstructureattribute {\ctxlua {tex.write(structures.references.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\@@iafocus"))}}% + \xdef\currentstructuresynchronize{\ctxlatelua{structures.lists.enhance(#1)}}} -\def\reportcurrentstructure{\ctxlua{structure.sections.writestatus()}} +\def\reportcurrentstructure{\ctxlua{structures.sections.writestatus()}} % Beware: we need to flush the data to the list explicitly. This is because % node in inserted and we may want control over when that happens. @@ -206,11 +208,11 @@ % \stopchapter % \stoptext -\def\structurevariable #1{\ctxlua{structure.sections.structuredata(nil,"#1")}} -\def\structureuservariable #1{\ctxlua{structure.sections.userdata(nil,"#1")}} -\def\structurenumber {\ctxlua{structure.sections.fullnumber()}} -\def\structurecatcodedget #1{\ctxlua{structure.sections.structuredata(nil,"#1",nil,true)}} % bad name -\def\structuregivencatcodedget#1#2{\ctxlua{structure.sections.structuredata(nil,"#1",nil,\number#2)}} % bad name -\def\structureautocatcodedget #1#2{\ctxlua{structure.sections.structuredata(nil,"#1",nil,"#2")}} +\def\structurevariable #1{\ctxlua{structures.sections.structuredata(nil,"#1")}} +\def\structureuservariable #1{\ctxlua{structures.sections.userdata(nil,"#1")}} +\def\structurenumber {\ctxlua{structures.sections.fullnumber()}} +\def\structurecatcodedget #1{\ctxlua{structures.sections.structuredata(nil,"#1",nil,true)}} % bad name +\def\structuregivencatcodedget#1#2{\ctxlua{structures.sections.structuredata(nil,"#1",nil,\number#2)}} % bad name +\def\structureautocatcodedget #1#2{\ctxlua{structures.sections.structuredata(nil,"#1",nil,"#2")}} \protect \endinput diff --git a/tex/context/base/strc-flt.mkiv b/tex/context/base/strc-flt.mkiv index 1d5114390..fe9ddfea3 100644 --- a/tex/context/base/strc-flt.mkiv +++ b/tex/context/base/strc-flt.mkiv @@ -26,7 +26,7 @@ \let\currentfloat\empty -\def\letfloatparameter #1{\expandafter\csname\??fl\currentfloat#1\endcsname} +\def\letfloatparameter #1{\expandafter\let\csname\??fl\currentfloat#1\endcsname} \def\floatparameter #1{\csname\dofloatparameter{\??fl\currentfloat}#1\endcsname} \def\floatsharedparameter#1{\csname \??fl #1\endcsname} @@ -306,7 +306,7 @@ % {\ifnofloatcaption \else \ifnofloatnumber \else % % \labeltexts\currentfloat{\convertedstructurecounter[\currentfloat]}% ! ! todo: use a lua call instead % \ifx\currentfloatnumber\relax\else -% \labeltexts\currentfloat{\ctxlua{structure.lists.savednumber("\currentfloat",\currentfloatnumber)}}% +% \labeltexts\currentfloat{\ctxlua{structures.lists.savednumber("\currentfloat",\currentfloatnumber)}}% % \fi % \fi \fi} @@ -314,7 +314,7 @@ {\ifnofloatcaption \else \ifnofloatnumber \else \ifx\currentfloatnumber\relax\else \dostarttagged\t!floattag\empty - \labeltexts\currentfloat{\ctxlua{structure.lists.savedprefixednumber("\currentfloat",\currentfloatnumber)}}% + \labeltexts\currentfloat{\ctxlua{structures.lists.savedprefixednumber("\currentfloat",\currentfloatnumber)}}% \dostoptagged \fi \fi \fi} @@ -323,7 +323,7 @@ {\ifnofloatcaption \else \ifx\currentfloatnumber\relax\else \dostarttagged\t!floattext\empty - \ctxlua{structure.lists.savedtitle("\currentfloat",\currentfloatnumber)}% + \ctxlua{structures.lists.savedtitle("\currentfloat",\currentfloatnumber)}% \dostoptagged \fi \fi} @@ -472,7 +472,7 @@ \long\def\docheckcaptioncontent#1#2% {\ifnofloatcaption \else \setbox\tempcaptionbox\hbox - {\trialtypesettingtrue + {\settrialtypesetting \notesenabledfalse \putcompletecaption{#1}{#2}}% % new, \placefigure{\XMLflush{somecaption}}{} passes earlier empty check @@ -630,7 +630,7 @@ \postponenotes} % new {\doifsomething{\floatparameter\c!criterium} {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax - \edef\forcedfloatmethod{\floatvariable\c!fallback}% + \edef\forcedfloatmethod{\floatparameter\c!fallback}% \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi \fi}% \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done @@ -937,14 +937,14 @@ \ifextrafloatactions \ifdim\sidefloatdownshift=\zeropoint\else \global\setbox\floatbox\vbox - {\vskip\sidefloatdownshift\nointerlineskip\box\floatbox}% + {\vskip\sidefloatdownshift\nointerlineskip\box\floatbox}% \fi \doifsomething{\floatparameter\c!minwidth} {\scratchdimen\floatparameter\c!minwidth\relax \ifdim\wd\floatbox<\scratchdimen \global\setbox\floatbox\hbox to \scratchdimen {\doifnot{\floatparameter\c!location}\v!left \hss - \box\floatbox% + \box\floatbox \doifnot{\floatparameter\c!location}\v!right\hss}% \fi}% % todo: rand / rug @@ -956,8 +956,7 @@ \doifsomething{\floatparameter\c!maxwidth} {\scratchdimen\floatparameter\c!maxwidth\relax \ifdim\wd\floatbox>\scratchdimen - \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge - \v!inleft,\v!leftmargin,\v!leftedge}{#1} + \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge,\v!inleft,\v!leftmargin,\v!leftedge}{#1} {\global\sidefloatmaximum\scratchdimen} {\global\setbox\floatbox\hbox to \scratchdimen {\doifcommonelse{\v!right,\v!left}{#1} @@ -1357,7 +1356,7 @@ \ifdim\captionhsize>\hsize % float is wider than \hsize \dosettempcaptionbox - {\trialtypesettingtrue + {\settrialtypesetting \hsize\captionhsize \notesenabledfalse \putcompletecaption{#2}{#3}}% @@ -1381,7 +1380,7 @@ \edef\captionhsize{\the\scratchdimen}% \fi \setbox\scratchbox\vbox % test with overshoot - {\trialtypesettingtrue + {\settrialtypesetting \scratchdimen\captionhsize \advance\scratchdimen \captionovershoot \advance\scratchdimen 3em % an average word length diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua index f36f79672..85917375a 100644 --- a/tex/context/base/strc-ini.lua +++ b/tex/context/base/strc-ini.lua @@ -24,16 +24,18 @@ local format, concat, match = string.format, table.concat, string.match local count, texwrite, texprint, texsprint = tex.count, tex.write, tex.print, tex.sprint local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match +local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array, utilities.parsers.settings_to_hash local ctxcatcodes, xmlcatcodes, notcatcodes = tex.ctxcatcodes, tex.xmlcatcodes, tex.notcatcodes -- tricky as we're in notcatcodes -local trace_processors = false trackers.register("structure.processors", function(v) trace_processors = v end) +local trace_processors = false trackers.register("structures.processors", function(v) trace_processors = v end) local report_processors = logs.new("processors") -- move this commands = commands or { } +local commands = commands function commands.first_in_list(str) local first = match(str,"^([^,]+),") @@ -42,32 +44,40 @@ end -- -- -- namespace -- -- -- -structure = structure or { } - --- -- -- cache -- -- -- - -structure.shares = structure.shares or { } -structure.shares.cache = structure.shares.cache or { } - -local shares = structure.shares -local cache = shares.cache - -function shares.put(data) - cache[#cache+1] = data - return #cache -end - -function shares.get(n) -- n can be string - n = tonumber(n) or -1 - return cache[n] -end +-- This is tricky: we have stored and initialized already some of +-- the job.registered tables so we have a forward reference! + +structures = structures or { } +local structures = structures + +structures.blocks = structures.blocks or { } +structures.sections = structures.sections or { } +structures.pages = structures.pages or { } +structures.registers = structures.registers or { } +structures.references = structures.references or { } +structures.lists = structures.lists or { } +structures.helpers = structures.helpers or { } +structures.processors = structures.processors or { } +structures.documents = structures.documents or { } +structures.notes = structures.notes or { } +structures.descriptions = structures.descriptions or { } +structures.itemgroups = structures.itemgroups or { } +structures.specials = structures.specials or { } +structures.counters = structures.counters or { } +structures.tags = structures.tags or { } +structures.formulas = structures.formulas or { } +structures.sets = structures.sets or { } +structures.marks = structures.marks or { } +structures.floats = structures.floats or { } + +--~ table.print(structures) -- -- -- specials -- -- -- -- we can store information and get back a reference; this permits -- us to store rather raw data in references -local specials = { } structure.specials = specials +local specials = structures.specials specials.collected = specials.collected or { } specials.tobesaved = specials.collected or { } @@ -79,7 +89,7 @@ local function initializer() end if job then - job.register('structure.specials.collected', structure.specials.tobesaved, initializer) + job.register('structures.specials.collected', specials.tobesaved, initializer) end function specials.store(class,data) @@ -105,12 +115,10 @@ end -- -- -- helpers -- -- -- -structure.helpers = structure.helpers or { } - -local helpers = structure.helpers +local helpers = structures.helpers function helpers.touserdata(str) - local hash = str and str ~= "" and aux.settings_to_hash(str) + local hash = str and str ~= "" and settings_to_hash(str) if hash and next(hash) then return hash end @@ -186,7 +194,7 @@ end -- -- -- processors -- -- -- syntax: processor->data -local processors = { } structure.processors = processors +local processors = structures.processors local registered = { } @@ -239,12 +247,12 @@ end -- -- -- sets -- -- -- -structure.sets = structure.sets or { } -structure.sets.setlist = structure.sets.setlist or { } +local sets = structures.sets + +sets.setlist = sets.setlist or { } -storage.register("structure/sets/setlist", structure.sets.setlist, "structure.sets.setlist") +storage.register("structures/sets/setlist", structures.sets.setlist, "structures.sets.setlist") -local sets = structure.sets local setlist = sets.setlist function sets.define(namespace,name,values,default,numbers) @@ -256,7 +264,7 @@ function sets.define(namespace,name,values,default,numbers) if values == "" then dn[name] = { { }, default } else - local split = aux.settings_to_array(values) + local split = settings_to_array(values) if numbers then -- convert to numbers (e.g. for reset) for i=1,#split do diff --git a/tex/context/base/strc-ini.mkiv b/tex/context/base/strc-ini.mkiv index 5ed7b423c..c2d882f7c 100644 --- a/tex/context/base/strc-ini.mkiv +++ b/tex/context/base/strc-ini.mkiv @@ -76,10 +76,10 @@ \unexpanded\def\definestructureconversionset{\dotripleempty\dodefinestructureconversionset} \unexpanded\def\definestructureprefixset {\dotripleempty\dodefinestructureprefixset} -\def\dodefinestructureresetset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:resets", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}",true)}} -\def\dodefinestructureseparatorset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:separators", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} -\def\dodefinestructureconversionset[#1][#2][#3]{\ctxlua{structure.sets.define("structure:conversions","#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} -\def\dodefinestructureprefixset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:prefixes", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} +\def\dodefinestructureresetset [#1][#2][#3]{\ctxlua{structures.sets.define("structure:resets", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}",true)}} +\def\dodefinestructureseparatorset [#1][#2][#3]{\ctxlua{structures.sets.define("structure:separators", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} +\def\dodefinestructureconversionset[#1][#2][#3]{\ctxlua{structures.sets.define("structure:conversions","#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} +\def\dodefinestructureprefixset [#1][#2][#3]{\ctxlua{structures.sets.define("structure:prefixes", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}} % \definestructureseparatorset [weird][!,?,*][:] % tex content % \definestructureconversionset[weird][numbers,characters,romannumerals][numbers] % symbolic names diff --git a/tex/context/base/strc-itm.lua b/tex/context/base/strc-itm.lua index e776f326d..53e0d56bf 100644 --- a/tex/context/base/strc-itm.lua +++ b/tex/context/base/strc-itm.lua @@ -6,10 +6,12 @@ if not modules then modules = { } end modules ['strc-itm'] = { license = "see context related readme files" } -structure = structure or { } -structure.itemgroups = structure.itemgroups or { } +local structures = structures -local itemgroups = structure.itemgroups +structures.itemgroups = structures.itemgroups or { } +local itemgroups = structures.itemgroups + +local jobpasses = job.passes function itemgroups.register(name,nofitems,maxwidth) jobpasses.savedata("itemgroup", { nofitems, maxwidth }) diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv index 40a515a34..9bb631e78 100644 --- a/tex/context/base/strc-itm.mkiv +++ b/tex/context/base/strc-itm.mkiv @@ -59,19 +59,19 @@ \def\dolistreference {\iftrialtypesetting \else % no need for different treatment of \continuelistitems - \ctxlua{structure.itemgroups.register("\currentitemgroup",\number\noflistelements,"\getitemparameter\currentitemlevel\c!maxwidth")}% + \ctxlua{structures.itemgroups.register("\currentitemgroup",\number\noflistelements,"\getitemparameter\currentitemlevel\c!maxwidth")}% \fi} \def\checkcurrentnofitems % we could do this at the lua end and save a call - {\edef\currentnofitems {\ctxlua{structure.itemgroups.nofitems("\currentitemgroup",\number\currentnoflists)}}% - \edef\currentitemmaxwidth{\ctxlua{structure.itemgroups.maxwidth("\currentitemgroup",\number\currentnoflists)}\scaledpoint}} + {\edef\currentnofitems {\ctxlua{structures.itemgroups.nofitems("\currentitemgroup",\number\currentnoflists)}}% + \edef\currentitemmaxwidth{\ctxlua{structures.itemgroups.maxwidth("\currentitemgroup",\number\currentnoflists)}\scaledpoint}} % todo: \dodosetreference -> \dostructurecountercomponent (to be checked) \def\dohandleitemreference % we will make a decent number helper {\ifx\currentitemreference \empty \else \setnextinternalreference - \ctxlua {jobreferences.setandgetattribute("\s!full", "\referenceprefix","\currentitemreference", + \ctxlua {structures.references.setandgetattribute("\s!full", "\referenceprefix","\currentitemreference", { metadata = { kind = "item",% ? @@ -80,9 +80,9 @@ }, references = { internal = \nextinternalreference, - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, - prefixdata = structure.helpers.simplify { + prefixdata = structures.helpers.simplify { prefix = "\structurecounterparameter\currentitemgroupcounter\c!prefix", separatorset = "\structurecounterparameter\currentitemgroupcounter\c!prefixseparatorset", conversion = \!!bs\structurecounterparameter\currentitemgroupcounter\c!prefixconversion\!!es, @@ -92,8 +92,8 @@ % segments = "\askedprefixsegments", connector = \!!bs\structurecounterparameter\currentitemgroupcounter\c!prefixconnector\!!es, }, - numberdata = structure.helpers.simplify { - numbers = structure.counters.compact("\currentitemgroupcounter",nil,true), + numberdata = structures.helpers.simplify { + numbers = structures.counters.compact("\currentitemgroupcounter",nil,true), separatorset = "\structurecounterparameter\currentitemgroupcounter\c!numberseparatorset", conversion = "\structurecounterparameter\currentitemgroupcounter\c!numberconversion", conversionset = "\structurecounterparameter\currentitemgroupcounter\c!numberconversionset", @@ -1311,7 +1311,7 @@ \def\sym#1% {\noindent \begingroup - \setbox\scratchbox\hbox{\trialtypesettingtrue#1}% + \setbox\scratchbox\hbox{\settrialtypesetting#1}% \setbox\scratchbox\hbox \ifdim\wd\scratchbox<1em to 1.5\else spread 1\fi em{#1\hfil}% \normalexpanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}% diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index c2c3c41b8..4a46cc130 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -16,31 +16,33 @@ local tonumber = tonumber local texsprint, texprint, texwrite, texcount = tex.sprint, tex.print, tex.write, tex.count local concat, insert, remove = table.concat, table.insert, table.remove local lpegmatch = lpeg.match +local simple_hash_to_string, settings_to_hash = utilities.parsers.simple_hash_to_string, utilities.parsers.settings_to_hash -local trace_lists = false trackers.register("structure.lists", function(v) trace_lists = v end) +local trace_lists = false trackers.register("structures.lists", function(v) trace_lists = v end) local report_lists = logs.new("lists") local ctxcatcodes = tex.ctxcatcodes -structure.lists = structure.lists or { } -structure.sections = structure.sections or { } -structure.helpers = structure.helpers or { } -structure.documents = structure.documents or { } -structure.pages = structure.pages or { } - -local lists = structure.lists -local sections = structure.sections -local helpers = structure.helpers -local documents = structure.documents -local pages = structure.pages - -lists.collected = lists.collected or { } -lists.tobesaved = lists.tobesaved or { } -lists.enhancers = lists.enhancers or { } -lists.internals = lists.internals or { } -lists.ordered = lists.ordered or { } -lists.cached = lists.cached or { } +local structures = structures + +structures.lists = structures.lists or { } + +local lists = structures.lists +local sections = structures.sections +local helpers = structures.helpers +local documents = structures.documents +local pages = structures.pages +local references = structures.references + +lists.collected = lists.collected or { } +lists.tobesaved = lists.tobesaved or { } +lists.enhancers = lists.enhancers or { } +lists.internals = lists.internals or { } +lists.ordered = lists.ordered or { } +lists.cached = lists.cached or { } + +references.specials = references.specials or { } local cached, pushed = lists.cached, { } @@ -51,7 +53,7 @@ local function initializer() -- create a cross reference between internal references -- and list entries local collected = lists.collected - local internals = jobreferences.internals + local internals = references.internals local ordered = lists.ordered for i=1,#collected do local c = collected[i] @@ -83,7 +85,7 @@ local function initializer() end if job then - job.register('structure.lists.collected', structure.lists.tobesaved, initializer) + job.register('structures.lists.collected', lists.tobesaved, initializer) end function lists.push(t) @@ -169,11 +171,11 @@ local function filter_collected(names, criterium, number, collected, forced, nes criterium = gsub(criterium," ","") -- not needed forced = forced or { } -- todo: also on other branched, for the moment only needed for bookmarks if type(names) == "string" then - names = aux.settings_to_hash(names) + names = settings_to_hash(names) end local all = not next(names) or names[variables.all] or false if trace_lists then - report_lists("filtering names: %s, criterium: %s, number: %s",aux.simple_hash_to_string(names),criterium,number or "-") + report_lists("filtering names: %s, criterium: %s, number: %s",simple_hash_to_string(names),criterium,number or "-") end if criterium == variables.intro then -- special case, no structure yet @@ -192,7 +194,7 @@ local function filter_collected(names, criterium, number, collected, forced, nes local metadata = v.metadata if metadata then local name = metadata.name or false - local sectionnumber = (r.section == 0) or jobsections.collected[r.section] + local sectionnumber = (r.section == 0) or sections.collected[r.section] if forced[name] or (sectionnumber and not metadata.nolist and (all or names[name])) then -- and not sectionnumber.hidenumber then result[#result+1] = v end @@ -207,7 +209,7 @@ local function filter_collected(names, criterium, number, collected, forced, nes local v = collected[i] local r = v.references if r then - local sectionnumber = jobsections.collected[r.section] + local sectionnumber = sections.collected[r.section] if sectionnumber then -- and not sectionnumber.hidenumber then local cnumbers = sectionnumber.numbers local metadata = v.metadata @@ -239,7 +241,7 @@ local function filter_collected(names, criterium, number, collected, forced, nes local v = collected[i] local r = v.references if r then - local sectionnumber = jobsections.collected[r.section] + local sectionnumber = sections.collected[r.section] if sectionnumber then -- and not sectionnumber.hidenumber then local cnumbers = sectionnumber.numbers local metadata = v.metadata @@ -271,7 +273,7 @@ local function filter_collected(names, criterium, number, collected, forced, nes local v = collected[i] local r = v.references if r then - local sectionnumber = jobsections.collected[r.section] + local sectionnumber = sections.collected[r.section] if sectionnumber then -- and not sectionnumber.hidenumber then local cnumbers = sectionnumber.numbers local metadata = v.metadata @@ -317,7 +319,7 @@ local function filter_collected(names, criterium, number, collected, forced, nes local v = collected[i] local r = v.references if r then - local sectionnumber = jobsections.collected[r.section] + local sectionnumber = sections.collected[r.section] if sectionnumber then local metadata = v.metadata local cnumbers = sectionnumber.numbers @@ -392,7 +394,7 @@ end function lists.sectionnumber(name,n,spec) local data = lists.result[n] - local sectiondata = jobsections.collected[data.references.section] + local sectiondata = sections.collected[data.references.section] -- hm, prefixnumber? sections.typesetnumber(sectiondata,"prefix",spec,sectiondata) -- data happens to contain the spec too end @@ -494,7 +496,7 @@ end local splitter = lpeg.splitat(":") -function jobreferences.specials.order(var,actions) -- jobreferences.specials ! +function references.specials.order(var,actions) -- references.specials ! local operation = var.operation if operation then local kind, name, n = lpegmatch(splitter,operation) @@ -505,7 +507,7 @@ function jobreferences.specials.order(var,actions) -- jobreferences.specials ! if r then actions.realpage = r var.operation = r -- brrr, but test anyway - return jobreferences.specials.page(var,actions) + return references.specials.page(var,actions) end end end diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv index 5db22d1d7..a09d61c55 100644 --- a/tex/context/base/strc-lst.mkiv +++ b/tex/context/base/strc-lst.mkiv @@ -74,40 +74,40 @@ {\begingroup \edef\currentlistname{#1}% \setnextinternalreference - \edef\currentlistnumber{\ctxlua{structure.lists.push{ + \edef\currentlistnumber{\ctxlua{structures.lists.push{ references = { internal = \nextinternalreference, - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, metadata = { kind = "#2", name = "\currentlistname", - level = structure.sections.currentlevel(), + level = structures.sections.currentlevel(), catcodes = \the\catcodetable, }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) }}}% \edef\structurelistsynchronize{\getvalue{\??li::inject::#2::synchronize}}% \ifx\structurelistsynchronize\v!yes % this injects nodes ! - \expanded{\ctxlatelua{structure.lists.enhance(\currentlistnumber)}}% + \expanded{\ctxlatelua{structures.lists.enhance(\currentlistnumber)}}% % new from here - \xdef\currentstructurelistattribute{\ctxlua{tex.write(jobreferences.setinternalreference(nil,nil,\nextinternalreference))}}% + \xdef\currentstructurelistattribute{\ctxlua{tex.write(structures.references.setinternalreference(nil,nil,\nextinternalreference))}}% \xdef\currentdestinationattribute{\number\lastdestinationattribute}% %begingroup\attribute\destinationattribute\currentdestinationattribute\dontleavehmode\hbox{}\endgroup % todo \dontleavehmode\hbox attr \destinationattribute \currentdestinationattribute{}% todo % end of new \else - \ctxlua{structure.lists.enhance(\currentlistnumber)}% direct injection + \ctxlua{structures.lists.enhance(\currentlistnumber)}% direct injection \fi \endgroup} \def\structurelistlocation - {\ctxlua{structure.lists.location(\currentlistindex)}} + {\ctxlua{structures.lists.location(\currentlistindex)}} \def\structurelistpagenumber {\dostarttagged\t!listpage\empty - \ctxlua{structure.lists.prefixedpage( + \ctxlua{structures.lists.prefixedpage( "\currentlist", \currentlistindex, { @@ -127,21 +127,21 @@ \dostoptagged} \def\structurelistrealpagenumber - {\ctxlua{structure.lists.realpage("\currentlist",\currentlistindex)}} + {\ctxlua{structures.lists.realpage("\currentlist",\currentlistindex)}} \def\structurelistfirst {\dostarttagged\t!listdata{first} % ot always ok - \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}% + \ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"first")}% \dostoptagged} \def\structurelistsecond {\dostarttagged\t!listdata{second}% - \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}% + \ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"second")}% \dostoptagged} \def\structurelistuservariable#1% {\dostarttagged\t!listdata{#1}% - \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"#1")}% + \ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"#1")}% \dostoptagged} % \appendtoks @@ -149,17 +149,17 @@ \unexpanded\def\placestructurelist#1#2#3% hm ... [][][] {\dostarttagged\t!list\empty - \ctxlua{structure.lists.process("#1","#2","#3")}% + \ctxlua{structures.lists.process("#1","#2","#3")}% \dostoptagged} \unexpanded\def\analysestructurelist#1#2#3% - {\ctxlua{structure.lists.analyze("#1","#2","#3")}} + {\ctxlua{structures.lists.analyze("#1","#2","#3")}} \def\firststructureelementinlist#1% {\ctxlua{commands.first_in_list("#1")}} \def\structurelistsize - {\ctxlua{structure.lists.size()}} + {\ctxlua{structures.lists.size()}} \def\@@structurelistprocess{structurelist:process:} @@ -181,7 +181,7 @@ % \stoptext \unexpanded\def\processlistofstructure#1#2#3% name, method, n - {\ctxlua{structure.lists.pushnesting(#3)}% + {\ctxlua{structures.lists.pushnesting(#3)}% \edef\currentlist {#1}% \edef\currentlistmethod{#2}% \edef\currentlistindex {#3}% @@ -193,13 +193,13 @@ \s!default \fi\fi\fi \endcsname \dostoptagged - \ctxlua{structure.lists.popnesting()}} + \ctxlua{structures.lists.popnesting()}} % \installstructcurelistprocessor{pubs:userdata} -% {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"bibref")}} +% {\ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"bibref")}} \installstructurelistprocessor{command} - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"command")}} + {\ctxlua{structures.lists.userdata("\currentlist",\currentlistindex,"command")}} \installstructurelistprocessor{section} {\dodolistelement @@ -922,12 +922,12 @@ \def\structurelistgenerictitle {\dostarttagged\t!listcontent\empty - \ctxlua{structure.lists.title("\currentlist",\currentlistindex)}% + \ctxlua{structures.lists.title("\currentlist",\currentlistindex)}% \dostoptagged} \def\structurelistgenericnumber {\dostarttagged\t!listtag\empty - \ctxlua{structure.lists.prefixednumber("\currentlist",\currentlistindex, { + \ctxlua{structures.lists.prefixednumber("\currentlist",\currentlistindex, { prefix = "\listparameter\c!prefix", separatorset = "\listparameter\c!prefixseparatorset", conversionset = "\listparameter\c!prefixconversionset", diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua index 8ee814d77..fd97836e6 100644 --- a/tex/context/base/strc-mar.lua +++ b/tex/context/base/strc-mar.lua @@ -6,13 +6,17 @@ if not modules then modules = { } end modules ['strc-mar'] = { license = "see context related readme files" } -structure.marks = structure.marks or { } +local structures = structures -function structure.marks.title(tag,n) - structure.lists.savedtitle(tag,n,"marking") +structures.marks = structures.marks or { } +local marks = structures.marks +local lists = structures.lists + +function marks.title(tag,n) + lists.savedtitle(tag,n,"marking") end -function structure.marks.number(tag,n) -- no spec +function marks.number(tag,n) -- no spec -- no prefix (as it is the prefix) - structure.lists.savednumber(tag,n) + lists.savednumber(tag,n) end diff --git a/tex/context/base/strc-mat.lua b/tex/context/base/strc-mat.lua index 291cc8845..d9cca2717 100644 --- a/tex/context/base/strc-mat.lua +++ b/tex/context/base/strc-mat.lua @@ -6,19 +6,15 @@ if not modules then modules = { } end modules ['strc-mat'] = { license = "see context related readme files" } -structure = structure or { } -structure.helpers = structure.helpers or { } -structure.lists = structure.lists or { } -structure.lists.enhancers = structure.lists.enhancers or { } -structure.sections = structure.sections or { } -structure.helpers = structure.helpers or { } -structure.formulas = structure.formulas or { } - -local lists = structure.lists -local sections = structure.sections -local floats = structure.floats -local helpers = structure.helpers -local formulas = structure.formulas +local structures = structures + +local lists = structures.lists +local sections = structures.sections +local floats = structures.floats +local helpers = structures.helpers +local formulas = structures.formulas + +lists.enhancers = lists.enhancers or { } -- maybe we want to do clever things with formulas, the store might go away diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua index f0bf6cab3..94a252539 100644 --- a/tex/context/base/strc-not.lua +++ b/tex/context/base/strc-not.lua @@ -12,31 +12,31 @@ local texsprint, texwrite, texcount = tex.sprint, tex.write, tex.count local ctxcatcodes = tex.ctxcatcodes -local trace_notes = false trackers.register("structure.notes", function(v) trace_notes = v end) +local trace_notes = false trackers.register("structures.notes", function(v) trace_notes = v end) local report_notes = logs.new("notes") -structure = structure or { } -structure.helpers = structure.helpers or { } -structure.lists = structure.lists or { } -structure.sections = structure.sections or { } -structure.counters = structure.counters or { } -structure.notes = structure.notes or { } +local structures = structures -structure.notes.states = structure.notes.states or { } -structure.lists.enhancers = structure.lists.enhancers or { } +structures.notes = structures.notes or { } -storage.register("structure/notes/states", structure.notes.states, "structure.notes.states") +local helpers = structures.helpers +local lists = structures.lists +local sections = structures.sections +local counters = structures.counters +local notes = structures.notes +local references = structures.references -local helpers = structure.helpers -local lists = structure.lists -local sections = structure.sections -local counters = structure.counters -local notes = structure.notes +notes.states = notes.states or { } +lists.enhancers = lists.enhancers or { } -local notestates = structure.notes.states +storage.register("structures/notes/states", notes.states, "structures.notes.states") + +local notestates = notes.states local notedata = { } +local variables = interfaces.variables + -- state: store, insert, postpone function notes.store(tag,n) @@ -67,7 +67,7 @@ local function get(tag,n) report_notes("getting note %s of '%s'",n,tag) end -- is this right? - local newdata = structure.lists.collected[nd] + local newdata = lists.collected[nd] return newdata end end @@ -78,8 +78,8 @@ local function getn(tag) return (nd and #nd) or 0 end -nodes.get = get -nodes.getn = getn +notes.get = get +notes.getn = getn -- we could make a special enhancer @@ -169,7 +169,7 @@ local function internal(tag,n) if r then local i = r.internal --~ return i and lists.internals[i] - return i and jobreferences.internals[i] + return i and references.internals[i] end end return nil @@ -221,7 +221,7 @@ function notes.deltapage(tag,n) if li then local metadata, pagenumber = li.metadata, li.pagenumber if metadata and pagenumber then - local symbolpage = metadata.symbolpage or 0 + local symbolpage = references.symbolpage or 0 local notepage = pagenumber.number or 0 if notepage > 0 and symbolpage > 0 then if notepage < symbolpage then @@ -282,7 +282,7 @@ function notes.getnumberpage(tag,n) texwrite(li or 0) end -function notes.flush(tag,whatkind) -- store and postpone +function notes.flush(tag,whatkind,how) -- store and postpone local state = notestates[tag] local kind = state.kind if kind == whatkind then @@ -306,6 +306,16 @@ function notes.flush(tag,whatkind) -- store and postpone end -- todo: as registers: start, stop, inbetween for i=ns,#nd do +-- tricky : trialtypesetting +if how == variables.page then + local rp = get(tag,i) + rp = rp and rp.references + rp = rp and rp.symbolpage or 0 + if rp > texcount.realpageno then + state.start = i + return + end +end if i > ns then texsprint(ctxcatcodes,format("\\betweennoteitself{%s}",tag)) end @@ -350,9 +360,9 @@ function notes.resetpostponed() end function notes.title(tag,n) - structure.lists.savedtitle(tag,notedata[tag][n]) + lists.savedtitle(tag,notedata[tag][n]) end function notes.number(tag,n,spec) - structure.lists.savedprefixednumber(tag,notedata[tag][n]) + lists.savedprefixednumber(tag,notedata[tag][n]) end diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv index 0a631ce0c..55006684f 100644 --- a/tex/context/base/strc-not.mkiv +++ b/tex/context/base/strc-not.mkiv @@ -247,7 +247,7 @@ [\s!parent=\??vn,#2]% % \definestructurecounter % [\currentnote]% - \ctxlua{structure.notes.define("\currentnote","insert",\number\csname\??vn:\currentnote\endcsname)}% + \ctxlua{structures.notes.define("\currentnote","insert",\number\csname\??vn:\currentnote\endcsname)}% \the\everysetupnote \dochecknote} @@ -417,7 +417,7 @@ \dosetnotedistance % play safe \ifnum\noteparameter\s!noteloc=\plusfive - \ctxlua{structure.notes.setstate("\currentnote","store")}% + \ctxlua{structures.notes.setstate("\currentnote","store")}% % text notes (e.g. end notes) but we don't use inserts anyway \global\dimen\currentnoteins\maxdimen \global\count\currentnoteins\zerocount @@ -588,7 +588,7 @@ \unexpanded\def\setnotetext[#1]{\global\settrue\skipnoteplacement\getvalue{#1}} \def\domovednote#1#2#3#4% - {\ifcase\ctxlua{structure.notes.deltapage("#1",#2)}\or\symbol[#3]\or\symbol[#4]\fi} + {\ifcase\ctxlua{structures.notes.deltapage("#1",#2)}\or\symbol[#3]\or\symbol[#4]\fi} \setvalue{\??dd:\v!note:\s!handler:\s!text }{\@@donotetext} \setvalue{\??dd:\v!note:\s!handler:\s!number}{\@@donotenumber} @@ -613,7 +613,7 @@ \doenumerationcheckconditions \let\currentnote\currentdescriptionmain \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#3},\c!list=,\c!bookmark=,][]% - \xdef\currentnotenumber{\ctxlua{structure.notes.store("\currentnote",\currentdescriptionnumberentry)}}% + \xdef\currentnotenumber{\ctxlua{structures.notes.store("\currentnote",\currentdescriptionnumberentry)}}% \settrue\processingnote \ifconditional\skipnoteplacement \globallet\lastnotesymbol\dolastnotesymbol @@ -650,8 +650,8 @@ \def\dotypesetsomenotesymbol#1#2#3% running text (messy: #1 and current mixed) {\dodonotesymbol {\synchronizesomenotesymbol{#1}{#2}{#3}% -% \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry - \ctxlua{structure.notes.number("#1",#2)}% +% \ctxlua{structures.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry + \ctxlua{structures.notes.number("#1",#2)}% \domovednote{#1}{#2}\v!previouspage\v!nextpage}} \unexpanded\def\typesetsomenotesymbol#1#2#3% running text @@ -663,7 +663,7 @@ \nobreak \doifelse{\noteparameter\c!interaction}\v!no {\dotypesetsomenotesymbol{#1}{#2}{#3}} - {\directgotobox{\dotypesetsomenotesymbol{#1}{#2}{#3}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: + {\directgotobox{\dotypesetsomenotesymbol{#1}{#2}{#3}}[page(\ctxlua{structures.notes.getnumberpage("#1",\number#2)})]}% f: \globallet\lastnotesymbol\relax} \unexpanded\def\typesetdummynotesymbol % temp hack @@ -677,7 +677,7 @@ \globallet\lastnotesymbol\relax} \def\currentnotedescriptiontext % todo: can be other number - {\ctxlua{structure.notes.title("\currentnote",\currentdescriptionnumberentry)}} + {\ctxlua{structures.notes.title("\currentnote",\currentdescriptionnumberentry)}} \def\@@donotetext {\ifconditional\enumerationnumberenabled @@ -699,17 +699,17 @@ {\docurrentnoteenumerationfullnumber}% {\directgotobox {\docurrentnoteenumerationfullnumber}% - [page(\ctxlua{structure.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}} + [page(\ctxlua{structures.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}} \def\docurrentnoteenumerationfullnumber {\noteparameter\c!numbercommand {\dosetnoteattributes\c!numberstyle\c!numbercolor - \ctxlua{structure.notes.number("\currentnote",\currentdescriptionnumberentry)}% + \ctxlua{structures.notes.number("\currentnote",\currentdescriptionnumberentry)}% \domovednote\currentdescription\currentdescriptionnumberentry\v!nextpage\v!previouspage}} \def\synchronizesomenotesymbol#1#2#3% called more often than needed {\iftrialtypesetting\else - \normalexpanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2,#3)}}% + \normalexpanded{\noexpand\ctxlatelua{structures.notes.setsymbolpage("#1",#2,#3)}}% \fi} \def\handlenoteinsert#1#2% tg, id @@ -738,7 +738,7 @@ {\edef\currentdescription{#1}% \edef\currentnote{#1}% \edef\currentdescriptionnumberentry{#2}% - \edef\currentdescriptionlistentry{\ctxlua{tex.write(structure.notes.listindex("#1",#2))}}% + \edef\currentdescriptionlistentry{\ctxlua{tex.write(structures.notes.listindex("#1",#2))}}% % as we can have collected notes (e.g. in tables) we need to recover % \currentdescriptionattribute and \currentdescriptionsynchronize \reinstatedescriptionnumberentry\currentdescriptionlistentry % we could store the number in the entry @@ -970,7 +970,7 @@ {\ifconditional\postponingnotes\else \global\settrue\postponingnotes \global\let\flushnotes\doflushnotes - \ctxlua{structure.notes.postpone()}% + \ctxlua{structures.notes.postpone()}% \fi} \let\flushnotes\relax @@ -980,7 +980,7 @@ \begingroup \let\flushnotes \relax \let\postponenotes\relax - \ctxlua{structure.notes.flushpostponed()}% this also resets the states ! + \ctxlua{structures.notes.flushpostponed()}% this also resets the states ! \global\setfalse\postponednote \global\setfalse\postponingnotes \global\let\flushnotes\relax @@ -1025,18 +1025,18 @@ {\doifnot{\noteparameter\c!continue}\v!yes {\savestructurecounter[#1]% \resetstructurecounter[#1]}% - \ctxlua{structure.notes.save("#1","store")}} + \ctxlua{structures.notes.save("#1","store")}} \def\dodostoplocalnotes#1% {\doifnot{\noteparameter\c!continue}\v!yes {\restorestructurecounter[#1]}% - \ctxlua{structure.notes.restore("#1")}} + \ctxlua{structures.notes.restore("#1")}} \unexpanded\def\placelocalnotes {\dodoubleempty\doplacelocalnotes} \def\doplacelocalnotes[#1][#2]% - {\doif{\ctxlua{structure.notes.getstate("#1")}}{store}{\dodoplacelocalnotes{#2}{#1}}} + {\doif{\ctxlua{structures.notes.getstate("#1")}}{store}{\dodoplacelocalnotes{#2}{#1}}} \def\dodoplacelocalnotes#1#2% settings note {\begingroup @@ -1093,7 +1093,7 @@ \def\dodoplacenotes#1#2% settings note {\edef\currentnote{#2}% - \doifelse{\ctxlua{structure.notes.getstate("#2")}}{store} + \doifelse{\ctxlua{structures.notes.getstate("#2")}}{store} \dodoplacelocalnotes \dodoplaceglobalnotes {#1}{#2}} @@ -1111,7 +1111,7 @@ {\setvalue{\??vn:\c!alternative:#1}{#2}} \def\doifnotescollected#1% - {\ctxlua{structure.notes.doifcontent("#1")}} + {\ctxlua{structures.notes.doifcontent("#1")}} \def\dolocalnotealternative#1% {\edef\currentnote{#1}% @@ -1137,7 +1137,8 @@ %D \setupfootnotes[location=text,alternative=none] %D \stoptyping -\def\flushlocalnotes#1{\ctxlua{structure.notes.flush("#1","store")}} +% \def\flushlocalnotes#1{\ctxlua{structures.notes.flush("#1","store")}} +\def\flushlocalnotes#1{\ctxlua{structures.notes.flush("#1","store","\noteparameter\c!criterium")}} \installnotealternative \v!none {\flushlocalnotes\currentnote} @@ -1286,7 +1287,7 @@ \unexpanded\def\setupfootnotedefinition{\setupnotedefinition [\v!footnote]} \unexpanded\def\setupfootnotes {\setupnote [\v!footnote]} %unexpanded\def\footnote {\setnote [\v!footnote]} -\def\footnotetext {\setnotetext [\v!footnote]} +\def\footnotetext {\setnotetext [\v!footnote]} %unexpanded\def\note {\dodoubleempty\notesymbol [\v!footnote]} % alleen footnote \unexpanded\def\placefootnotes {\dodoubleempty\doplacefootnotes [\v!footnote]} \unexpanded\def\placelocalfootnotes {\dodoubleempty\doplacelocalfootnotes[\v!footnote]} @@ -1308,7 +1309,7 @@ %D } %D \stoptyping -\def\doifnoteonsamepageelse[#1]{\ctxlua{structure.notes.doifonsamepageasprevious("#1")}} +\def\doifnoteonsamepageelse[#1]{\ctxlua{structures.notes.doifonsamepageasprevious("#1")}} %D New trickery: diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua index e32b5e781..6f1efec55 100644 --- a/tex/context/base/strc-num.lua +++ b/tex/context/base/strc-num.lua @@ -11,27 +11,22 @@ local next, type = next, type local min, max = math.min, math.max local texsprint, texcount = tex.sprint, tex.count -local trace_counters = false trackers.register("structure.counters", function(v) trace_counters = v end) +local trace_counters = false trackers.register("structures.counters", function(v) trace_counters = v end) local report_counters = logs.new("counters") -structure = structure or { } -structure.helpers = structure.helpers or { } -structure.sections = structure.sections or { } -structure.counters = structure.counters or { } -structure.documents = structure.documents or { } +local structures = structures -structure.counters = structure.counters or { } -structure.counters.data = structure.counters.data or { } -structure.counters.specials = structure.counters.specials or { } - -local helpers = structure.helpers -local sections = structure.sections -local counters = structure.counters -local documents = structure.documents +local helpers = structures.helpers +local sections = structures.sections +local counters = structures.counters +local documents = structures.documents local variables = interfaces.variables +counters.data = counters.data or { } +counters.specials = counters.specials or { } + -- state: start stop none reset local counterdata = counters.data @@ -41,8 +36,8 @@ local counterspecials = counters.specials counters.collected = counters.collected or { } counters.tobesaved = counters.tobesaved or { } -storage.register("structure/counters/data", structure.counters.data, "structure.counters.data") -storage.register("structure/counters/tobesaved", structure.counters.tobesaved, "structure.counters.tobesaved") +storage.register("structures/counters/data", counters.data, "structures.counters.data") +storage.register("structures/counters/tobesaved", counters.tobesaved, "structures.counters.tobesaved") local collected, tobesaved = counters.collected, counters.tobesaved @@ -65,7 +60,7 @@ local function initializer() end if job then - job.register('structure.counters.collected', structure.counters.tobesaved, initializer, finalizer) + job.register('structures.counters.collected', counters.tobesaved, initializer, finalizer) end local function constructor(t,s,name,i) @@ -491,7 +486,7 @@ function counters.analyse(name,counterspecification) if not section then return cd, false, "no section" end - sectiondata = jobsections.collected[references.section] + sectiondata = sections.collected[references.section] if not sectiondata then return cd, false, "no section data" end diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv index 5b5aebe7d..f675e4ac3 100644 --- a/tex/context/base/strc-num.mkiv +++ b/tex/context/base/strc-num.mkiv @@ -57,7 +57,7 @@ [\c!prefixsegments=\autostructureprefixsegments\sharedstructurecounterparameter] \def\autostructureprefixsegments#1% todo: \c!prefixsegments=\v!auto - {2:\thenamedstructureheadlevel{\ctxlua{structure.sections.way("#1\c!way","\v!by")}}} + {2:\thenamedstructureheadlevel{\ctxlua{structures.sections.way("#1\c!way","\v!by")}}} % \letvalue{\??nn\s!empty}\empty @@ -108,7 +108,7 @@ \def\dododefinestructurecounter[#1][#2]% {\getparameters[\??nn#1][\s!counter=,#2]% counter is for internal purposes - \ctxlua{structure.counters.define("#1",tonumber("\structurecounterparameter{#1}\c!start") or 0,"\structurecounterparameter{#1}\s!counter")}% + \ctxlua{structures.counters.define("#1",tonumber("\structurecounterparameter{#1}\c!start") or 0,"\structurecounterparameter{#1}\s!counter")}% \docheckstructurecountersetup{#1}} \def\donodefinestructurecounter[#1][#2]% inherit @@ -123,7 +123,7 @@ \docheckstructurecountersetup{#1}} \def\structurecounterway#1% slow, we need to store it at the tex end - {\ctxlua{structure.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}} + {\ctxlua{structures.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}} \def\thenamedstructurecounterlevel#1% {\thenamedstructureheadlevel{\structurecounterway{#1}}} @@ -139,36 +139,36 @@ \else \edef\currentstructurecounterlevel{\thenamedstructurecounterlevel{#1}}% \ctxlua{ - structure.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start") - structure.counters.setstate("#1","\structurecounterparameter{#1}\c!state") - structure.counters.setlevel("#1",\currentstructurecounterlevel) - structure.sections.setchecker("#1",\currentstructurecounterlevel,structure.counters.reset) + structures.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start") + structures.counters.setstate("#1","\structurecounterparameter{#1}\c!state") + structures.counters.setlevel("#1",\currentstructurecounterlevel) + structures.sections.setchecker("#1",\currentstructurecounterlevel,structures.counters.reset) }% \fi} -\def\doifstructurecounterelse#1{\ctxlua{structure.counters.doifelse("\@@thestructurecounter{#1}")}} -\def\doifstructurecounter #1{\ctxlua{structure.counters.doif ("\@@thestructurecounter{#1}")}} -\def\doifnotstructurecounter #1{\ctxlua{structure.counters.doifnot ("\@@thestructurecounter{#1}")}} - -\def\setstructurecounter [#1]#2{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",1,\number#2)}} -\def\setstructurecounterown [#1]#2{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}} -\def\resetstructurecounter [#1]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",1)}} -\def\restartstructurecounter [#1]#2{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",1,#2)}} -\def\savestructurecounter [#1]{\ctxlua{structure.counters.save ("\@@thestructurecounter{#1}")}} -\def\restorestructurecounter [#1]{\ctxlua{structure.counters.restore("\@@thestructurecounter{#1}")}} -\def\incrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,1)}} -\def\decrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,-1)}} -\def\rawstructurecounter [#1]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",1)}} -\def\laststructurecounter [#1]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",1)}} -\def\firststructurecounter [#1]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",1)}} -\def\nextstructurecounter [#1]{\ctxlua{structure.counters.next ("\@@thestructurecounter{#1}",1)}} -\def\prevstructurecounter [#1]{\ctxlua{structure.counters.prev ("\@@thestructurecounter{#1}",1)}} -\def\structurecountersubs [#1]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",1)}} - -\def\tracestructurecounter [#1]{\ctxlua{structure.counters.trace ("\@@thestructurecounter{#1}")}} - -\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,1))}} -\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,-1))}} +\def\doifstructurecounterelse#1{\ctxlua{structures.counters.doifelse("\@@thestructurecounter{#1}")}} +\def\doifstructurecounter #1{\ctxlua{structures.counters.doif ("\@@thestructurecounter{#1}")}} +\def\doifnotstructurecounter #1{\ctxlua{structures.counters.doifnot ("\@@thestructurecounter{#1}")}} + +\def\setstructurecounter [#1]#2{\ctxlua{structures.counters.set ("\@@thestructurecounter{#1}",1,\number#2)}} +\def\setstructurecounterown [#1]#2{\ctxlua{structures.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}} +\def\resetstructurecounter [#1]{\ctxlua{structures.counters.reset ("\@@thestructurecounter{#1}",1)}} +\def\restartstructurecounter [#1]#2{\ctxlua{structures.counters.restart("\@@thestructurecounter{#1}",1,#2)}} +\def\savestructurecounter [#1]{\ctxlua{structures.counters.save ("\@@thestructurecounter{#1}")}} +\def\restorestructurecounter [#1]{\ctxlua{structures.counters.restore("\@@thestructurecounter{#1}")}} +\def\incrementstructurecounter [#1]{\ctxlua{structures.counters.add ("\@@thestructurecounter{#1}",1,1)}} +\def\decrementstructurecounter [#1]{\ctxlua{structures.counters.add ("\@@thestructurecounter{#1}",1,-1)}} +\def\rawstructurecounter [#1]{\ctxlua{structures.counters.value ("\@@thestructurecounter{#1}",1)}} +\def\laststructurecounter [#1]{\ctxlua{structures.counters.last ("\@@thestructurecounter{#1}",1)}} +\def\firststructurecounter [#1]{\ctxlua{structures.counters.first ("\@@thestructurecounter{#1}",1)}} +\def\nextstructurecounter [#1]{\ctxlua{structures.counters.next ("\@@thestructurecounter{#1}",1)}} +\def\prevstructurecounter [#1]{\ctxlua{structures.counters.prev ("\@@thestructurecounter{#1}",1)}} +\def\structurecountersubs [#1]{\ctxlua{structures.counters.subs ("\@@thestructurecounter{#1}",1)}} + +\def\tracestructurecounter [#1]{\ctxlua{structures.counters.trace ("\@@thestructurecounter{#1}")}} + +\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structures.counters.add("\@@thestructurecounter{#1}",1,1))}} +\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structures.counters.add("\@@thestructurecounter{#1}",1,-1))}} \def\setsubstructurecounter {\dodoubleargument\dosetsubstructurecounter} \def\setsubstructurecounterown {\dodoubleargument\dosetsubstructurecounterown} @@ -178,16 +178,16 @@ \def\decrementsubstructurecounter {\dodoubleargument\dodecrementsubstructurecounter} \def\rawsubstructurecounter {\dodoubleargument\dorawsubstructurecounter} -\def\dosetsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",#2,\number#3)}} -\def\dosetsubstructurecounterown [#1][#2]#3{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}} -\def\doresetsubstructurecounter [#1][#2]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",#2)}} -\def\dorestartsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",#2,#3)}} -\def\doincrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,1)}} -\def\dodecrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,-1)}} -\def\dorawsubstructurecounter [#1][#2]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",#2)}} -\def\dolastsubstructurecounter [#1][#2]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",#2)}} -\def\dofirstsubstructurecounter [#1][#2]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",#2)}} -\def\dosubstructurecountersubs [#1][#2]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",#2)}} +\def\dosetsubstructurecounter [#1][#2]#3{\ctxlua{structures.counters.set ("\@@thestructurecounter{#1}",#2,\number#3)}} +\def\dosetsubstructurecounterown [#1][#2]#3{\ctxlua{structures.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}} +\def\doresetsubstructurecounter [#1][#2]{\ctxlua{structures.counters.reset ("\@@thestructurecounter{#1}",#2)}} +\def\dorestartsubstructurecounter [#1][#2]#3{\ctxlua{structures.counters.restart("\@@thestructurecounter{#1}",#2,#3)}} +\def\doincrementsubstructurecounter [#1][#2]{\ctxlua{structures.counters.add ("\@@thestructurecounter{#1}",#2,1)}} +\def\dodecrementsubstructurecounter [#1][#2]{\ctxlua{structures.counters.add ("\@@thestructurecounter{#1}",#2,-1)}} +\def\dorawsubstructurecounter [#1][#2]{\ctxlua{structures.counters.value ("\@@thestructurecounter{#1}",#2)}} +\def\dolastsubstructurecounter [#1][#2]{\ctxlua{structures.counters.last ("\@@thestructurecounter{#1}",#2)}} +\def\dofirstsubstructurecounter [#1][#2]{\ctxlua{structures.counters.first ("\@@thestructurecounter{#1}",#2)}} +\def\dosubstructurecountersubs [#1][#2]{\ctxlua{structures.counters.subs ("\@@thestructurecounter{#1}",#2)}} % The bypage check needs a multipass reference and therefore % we only check for it when we increment and know that some @@ -200,11 +200,11 @@ \def\incrementstructurecounter[#1]% {\docheckstructurecounterbypage{#1}% - \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}} + \ctxlua{structures.counters.add("\@@thestructurecounter{#1}",1,1)}} \def\doincrementsubstructurecounter[#1][#2]% {\docheckstructurecounterbypage{#1}% - \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}} + \ctxlua{structures.counters.add("\@@thestructurecounter{#1}",#2,1)}} \def\convertedstructurecounter {\dodoubleempty\doconvertedstructurecounter} @@ -212,7 +212,7 @@ \def\doconvertedstructurecounter[#1][#2]% {\begingroup \ifsecondargument\getparameters[\??nn#1][#2]\fi - \ctxlua{structure.counters.prefixedconverted( + \ctxlua{structures.counters.prefixedconverted( "\@@thestructurecounter{#1}", { prefix = "\structurecounterparameter{#1}\c!prefix", @@ -241,7 +241,7 @@ \def\directconvertedstructurecounter#1#2% name, type {\begingroup - \ctxlua{structure.counters.prefixedconverted( + \ctxlua{structures.counters.prefixedconverted( "\@@thestructurecounter{#1}", { prefix = "\structurecounterparameter{#1}\c!prefix", @@ -403,11 +403,11 @@ \edef\currentlabel{#3\c!label}% \edef\currentreference{#3\c!reference}% \setnextinternalreference - \xdef\laststructurecounternumber{\ctxlua{structure.lists.push{ + \xdef\laststructurecounternumber{\ctxlua{structures.lists.push{ metadata = { kind = "#1", name = "\currentname", - level = structure.sections.currentlevel(), + level = structures.sections.currentlevel(), catcodes = \the\catcodetable, }, references = { @@ -415,7 +415,7 @@ reference = "\currentreference", referenceprefix = "\referenceprefix", block = "\currentstructureblock", - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, titledata = { label = \!!bs\detokenize\expandafter{\currentlabel }\!!es, @@ -439,7 +439,7 @@ connector = \!!bs#3\c!prefixconnector\!!es, }, numberdata = { - numbers = structure.counters.compact("\currentcounter",nil,true), + numbers = structures.counters.compact("\currentcounter",nil,true), separatorset = "#3\c!numberseparatorset", conversion = \!!bs#3\c!numberconversion\!!es, conversionset = "#3\c!numberconversionset", @@ -448,11 +448,11 @@ segments = "#3\c!numbersegments", }, \fi - userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#9}\!!es) } }}% - \xdef\laststructurecounterattribute {\ctxlua {tex.write(jobreferences.setinternalreference(nil,nil,\nextinternalreference))}}% - \xdef\laststructurecountersynchronize{\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}% + \xdef\laststructurecounterattribute {\ctxlua {tex.write(structures.references.setinternalreference(nil,nil,\nextinternalreference))}}% + \xdef\laststructurecountersynchronize{\ctxlatelua{structures.lists.enhance(\laststructurecounternumber)}}% \else \glet\laststructurecounternumber \relax \glet\laststructurecounterattribute \attributeunsetvalue diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua index ccaef6d72..e7750815e 100644 --- a/tex/context/base/strc-pag.lua +++ b/tex/context/base/strc-pag.lua @@ -11,33 +11,35 @@ local texcount, format = tex.count, string.format local ctxcatcodes = tex.ctxcatcodes local texsprint, texwrite = tex.sprint, tex.write -local trace_pages = false trackers.register("structure.pages", function(v) trace_pages = v end) +local trace_pages = false trackers.register("structures.pages", function(v) trace_pages = v end) local report_pages = logs.new("pages") -structure.pages = structure.pages or { } +local structures = structures -local helpers = structure.helpers or { } -local sections = structure.sections or { } -local pages = structure.pages or { } -local processors = structure.processors or { } -local sets = structure.sets or { } +structures.pages = structures.pages or { } + +local helpers = structures.helpers or { } +local sections = structures.sections or { } +local pages = structures.pages or { } +local processors = structures.processors or { } +local sets = structures.sets or { } +local counters = structures.counters or { } local variables = interfaces.variables -- storage -jobpages = jobpages or { } -jobpages.collected = jobpages.collected or { } -jobpages.tobesaved = jobpages.tobesaved or { } +pages.collected = pages.collected or { } +pages.tobesaved = pages.tobesaved or { } -local collected, tobesaved = jobpages.collected, jobpages.tobesaved +local collected, tobesaved = pages.collected, pages.tobesaved local function initializer() - collected, tobesaved = jobpages.collected, jobpages.tobesaved + collected, tobesaved = pages.collected, pages.tobesaved end -job.register('jobpages.collected', jobpages.tobesaved, initializer) +job.register('structures.pages.collected', pages.tobesaved, initializer) local specification = { } -- to be checked @@ -62,7 +64,7 @@ function pages.save(prefixdata,numberdata) end end -function structure.counters.specials.userpage() +function counters.specials.userpage() local r = texcount.realpageno if r > 0 then local t = tobesaved[r] @@ -156,7 +158,7 @@ function pages.analyse(entry,pagespecification) return pagedata, false, "pagedata blocks prefix" end -- final verdict - return pagedata, jobsections.collected[references.section], "okay" + return pagedata, sections.collected[references.section], "okay" end function helpers.page(data,pagespec) @@ -207,7 +209,7 @@ function helpers.analyse(entry,specification) if not section then return entry, false, "no section" end - local sectiondata = jobsections.collected[references.section] + local sectiondata = sections.collected[references.section] if not sectiondata then return entry, false, "no section data" end diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv index 0e5f5323e..641acc9dc 100644 --- a/tex/context/base/strc-pag.mkiv +++ b/tex/context/base/strc-pag.mkiv @@ -107,7 +107,7 @@ \let\resetpagenumber\resetuserpagenumber \def\savecurrentpagestate % \normalexpanded? - {\ctxlua{structure.pages.save({ + {\ctxlua{structures.pages.save({ prefix = "\structurecounterparameter\s!userpage\c!prefix", separatorset = "\structurecounterparameter\s!userpage\c!prefixseparatorset", conversion = "\structurecounterparameter\s!userpage\c!prefixconversion", diff --git a/tex/context/base/strc-prc.mkiv b/tex/context/base/strc-prc.mkiv index 2955a396b..68339ed92 100644 --- a/tex/context/base/strc-prc.mkiv +++ b/tex/context/base/strc-prc.mkiv @@ -50,11 +50,11 @@ \def\dodefineprocessor[#1][#2]% {\ifsecondargument \letbeundefined{\??po#1\c!command}% - \ctxlua{structure.processors.register("#1")}% + \ctxlua{structures.processors.register("#1")}% \getparameters[\??po#1][\c!style=,\c!color=,\c!left=,\c!right=,#2]% \else \letbeundefined{\??po#1\c!style}% - \ctxlua{structure.processors.reset("#1")}% + \ctxlua{structures.processors.reset("#1")}% \fi} %D The following command can be used by users but normally it will be diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 03c755f57..3e0fefc51 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -10,7 +10,7 @@ local format, find, gmatch, match, concat = string.format, string.find, string.g local lpegmatch = lpeg.match local texsprint, texwrite, texcount, texsetcount = tex.sprint, tex.write, tex.count, tex.setcount -local trace_referencing = false trackers.register("structure.referencing", function(v) trace_referencing = v end) +local trace_referencing = false trackers.register("structures.referencing", function(v) trace_referencing = v end) local report_references = logs.new("references") @@ -18,56 +18,71 @@ local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables local constants = interfaces.constants +local settings_to_array = utilities.parsers.settings_to_array + -- beware, this is a first step in the rewrite (just getting rid of -- the tuo file); later all access and parsing will also move to lua -- the useddata and pagedata names might change -- todo: pack exported data -jobreferences = jobreferences or { } -jobreferences.tobesaved = jobreferences.tobesaved or { } -jobreferences.collected = jobreferences.collected or { } -jobreferences.defined = jobreferences.defined or { } -- indirect ones -jobreferences.derived = jobreferences.derived or { } -- taken from lists -jobreferences.specials = jobreferences.specials or { } -- system references -jobreferences.runners = jobreferences.runners or { } -jobreferences.internals = jobreferences.internals or { } -jobreferences.exporters = jobreferences.exporters or { } -jobreferences.imported = jobreferences.imported or { } +local structures = structures + +structures.references = structures.references or { } + +local helpers = structures.helpers +local sections = structures.sections +local references = structures.references +local lists = structures.lists +local counters = structures.counters + +references.tobesaved = references.tobesaved or { } +references.collected = references.collected or { } + +references.defined = references.defined or { } -- indirect ones +references.derived = references.derived or { } -- taken from lists +references.specials = references.specials or { } -- system references +references.runners = references.runners or { } +references.internals = references.internals or { } +references.exporters = references.exporters or { } +references.imported = references.imported or { } +references.filters = references.filters or { } + +local filters = references.filters -storage.register("jobreferences/defined", jobreferences.defined, "jobreferences.defined") +storage.register("structures/references/defined", references.defined, "structures.references.defined") -local tobesaved, collected = jobreferences.tobesaved, jobreferences.collected -local defined, derived, specials = jobreferences.defined, jobreferences.derived, jobreferences.specials -local exporters, runners = jobreferences.exporters, jobreferences.runners +local tobesaved, collected = references.tobesaved, references.collected +local defined, derived, specials = references.defined, references.derived, references.specials +local exporters, runners = references.exporters, references.runners local currentreference = nil local initializers = { } local finalizers = { } -function jobreferences.registerinitializer(func) -- we could use a token register instead +function references.registerinitializer(func) -- we could use a token register instead initializers[#initializers+1] = func end -function jobreferences.registerfinalizer(func) -- we could use a token register instead +function references.registerfinalizer(func) -- we could use a token register instead finalizers[#finalizers+1] = func end local function initializer() - tobesaved, collected = jobreferences.tobesaved, jobreferences.collected + tobesaved, collected = references.tobesaved, references.collected for i=1,#initializers do initializers[i](tobesaved,collected) end end local function finalizer() - tobesaved = jobreferences.tobesaved + tobesaved = references.tobesaved for i=1,#finalizers do finalizers[i](tobesaved) end end if job then - job.register('jobreferences.collected', jobreferences.tobesaved, initializer, finalizer) + job.register('structures.references.collected', references.tobesaved, initializer, finalizer) end -- todo: delay split till later as in destinations we split anyway @@ -88,18 +103,18 @@ local function setnextorder(kind,name) texsetcount("global","locationorder",lastorder) end -jobreferences.setnextorder = setnextorder +references.setnextorder = setnextorder -function jobreferences.setnextinternal(kind,name) +function references.setnextinternal(kind,name) setnextorder(kind,name) -- always incremented with internal texsetcount("global","locationcount",texcount.locationcount + 1) end -function jobreferences.currentorder(kind,name) +function references.currentorder(kind,name) texwrite((orders[kind] and orders[kind][name]) or lastorder) end -function jobreferences.set(kind,prefix,tag,data) +function references.set(kind,prefix,tag,data) for ref in gmatch(tag,"[^,]+") do local p, r = match(ref,"^(%-):(.-)$") if p and r then @@ -119,12 +134,12 @@ function jobreferences.set(kind,prefix,tag,data) end end -function jobreferences.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here - jobreferences.set(kind,prefix,tag,data) - texcount.lastdestinationattribute = jobreferences.setinternalreference(prefix,tag,nil,view) or -0x7FFFFFFF +function references.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here + references.set(kind,prefix,tag,data) + texcount.lastdestinationattribute = references.setinternalreference(prefix,tag,nil,view) or -0x7FFFFFFF end -function jobreferences.enhance(prefix,tag,spec) +function references.enhance(prefix,tag,spec) local l = tobesaved[prefix][tag] if l then l.references.realpage = texcount.realpageno @@ -162,34 +177,34 @@ local special_reference = special * lparent * (operation * optional_arguments + local scanner = (reset * outer_reference * (special_reference + inner_reference)^-1 * -1) / function() return result end ---~ function jobreferences.analyse(str) -- overloaded +--~ function references.analyse(str) -- overloaded --~ return lpegmatch(scanner,str) --~ end -function jobreferences.split(str) +function references.split(str) return lpegmatch(scanner,str or "") end ---~ print(table.serialize(jobreferences.analyse(""))) ---~ print(table.serialize(jobreferences.analyse("inner"))) ---~ print(table.serialize(jobreferences.analyse("special(operation{argument,argument})"))) ---~ print(table.serialize(jobreferences.analyse("special(operation)"))) ---~ print(table.serialize(jobreferences.analyse("special()"))) ---~ print(table.serialize(jobreferences.analyse("inner{argument}"))) ---~ print(table.serialize(jobreferences.analyse("outer::"))) ---~ print(table.serialize(jobreferences.analyse("outer::inner"))) ---~ print(table.serialize(jobreferences.analyse("outer::special(operation{argument,argument})"))) ---~ print(table.serialize(jobreferences.analyse("outer::special(operation)"))) ---~ print(table.serialize(jobreferences.analyse("outer::special()"))) ---~ print(table.serialize(jobreferences.analyse("outer::inner{argument}"))) ---~ print(table.serialize(jobreferences.analyse("special(outer::operation)"))) +--~ print(table.serialize(references.analyse(""))) +--~ print(table.serialize(references.analyse("inner"))) +--~ print(table.serialize(references.analyse("special(operation{argument,argument})"))) +--~ print(table.serialize(references.analyse("special(operation)"))) +--~ print(table.serialize(references.analyse("special()"))) +--~ print(table.serialize(references.analyse("inner{argument}"))) +--~ print(table.serialize(references.analyse("outer::"))) +--~ print(table.serialize(references.analyse("outer::inner"))) +--~ print(table.serialize(references.analyse("outer::special(operation{argument,argument})"))) +--~ print(table.serialize(references.analyse("outer::special(operation)"))) +--~ print(table.serialize(references.analyse("outer::special()"))) +--~ print(table.serialize(references.analyse("outer::inner{argument}"))) +--~ print(table.serialize(references.analyse("special(outer::operation)"))) -- -- -- related to strc-ini.lua -- -- -- -jobreferences.resolvers = jobreferences.resolvers or { } +references.resolvers = references.resolvers or { } -function jobreferences.resolvers.section(var) - local vi = structure.lists.collected[var.i[2]] +function references.resolvers.section(var) + local vi = lists.collected[var.i[2]] if vi then var.i = vi var.r = (vi.references and vi.references.realpage) or (vi.pagedata and vi.pagedata.realpage) or 1 @@ -199,12 +214,12 @@ function jobreferences.resolvers.section(var) end end -jobreferences.resolvers.float = jobreferences.resolvers.section -jobreferences.resolvers.description = jobreferences.resolvers.section -jobreferences.resolvers.formula = jobreferences.resolvers.section -jobreferences.resolvers.note = jobreferences.resolvers.section +references.resolvers.float = references.resolvers.section +references.resolvers.description = references.resolvers.section +references.resolvers.formula = references.resolvers.section +references.resolvers.note = references.resolvers.section -function jobreferences.resolvers.reference(var) +function references.resolvers.reference(var) local vi = var.i[2] if vi then var.i = vi @@ -238,22 +253,22 @@ local function register_from_lists(collected,derived) end end -jobreferences.registerinitializer(function() register_from_lists(structure.lists.collected,derived) end) +references.registerinitializer(function() register_from_lists(lists.collected,derived) end) -- urls -jobreferences.urls = jobreferences.urls or { } -jobreferences.urls.data = jobreferences.urls.data or { } +references.urls = references.urls or { } +references.urls.data = references.urls.data or { } -local urls = jobreferences.urls.data +local urls = references.urls.data -function jobreferences.urls.define(name,url,file,description) +function references.urls.define(name,url,file,description) if name and name ~= "" then urls[name] = { url or "", file or "", description or url or file or ""} end end -function jobreferences.urls.get(name,method,space) -- method: none, before, after, both, space: yes/no +function references.urls.get(name,method,space) -- method: none, before, after, both, space: yes/no local u = urls[name] if u then local url, file = u[1], u[2] @@ -271,18 +286,18 @@ end -- files -jobreferences.files = jobreferences.files or { } -jobreferences.files.data = jobreferences.files.data or { } +references.files = references.files or { } +references.files.data = references.files.data or { } -local files = jobreferences.files.data +local files = references.files.data -function jobreferences.files.define(name,file,description) +function references.files.define(name,file,description) if name and name ~= "" then files[name] = { file or "", description or file or ""} end end -function jobreferences.files.get(name,method,space) -- method: none, before, after, both, space: yes/no +function references.files.get(name,method,space) -- method: none, before, after, both, space: yes/no local f = files[name] if f then texsprint(ctxcatcodes,f[1]) @@ -295,7 +310,7 @@ end -- helpers -function jobreferences.checkedfile(whatever) -- return whatever if not resolved +function references.checkedfile(whatever) -- return whatever if not resolved if whatever then local w = files[whatever] if w then @@ -306,7 +321,7 @@ function jobreferences.checkedfile(whatever) -- return whatever if not resolved end end -function jobreferences.checkedurl(whatever) -- return whatever if not resolved +function references.checkedurl(whatever) -- return whatever if not resolved if whatever then local w = urls[whatever] if w then @@ -322,7 +337,7 @@ function jobreferences.checkedurl(whatever) -- return whatever if not resolved end end -function jobreferences.checkedfileorurl(whatever,default) -- return nil, nil if not resolved +function references.checkedfileorurl(whatever,default) -- return nil, nil if not resolved if whatever then local w = files[whatever] if w then @@ -344,25 +359,25 @@ end -- programs -jobreferences.programs = jobreferences.programs or { } -jobreferences.programs.data = jobreferences.programs.data or { } +references.programs = references.programs or { } +references.programs.data = references.programs.data or { } -local programs = jobreferences.programs.data +local programs = references.programs.data -function jobreferences.programs.define(name,file,description) +function references.programs.define(name,file,description) if name and name ~= "" then programs[name] = { file or "", description or file or ""} end end -function jobreferences.programs.get(name) +function references.programs.get(name) local f = programs[name] if f then texsprint(ctxcatcodes,f[1]) end end -function jobreferences.checkedprogram(whatever) -- return whatever if not resolved +function references.checkedprogram(whatever) -- return whatever if not resolved if whatever then local w = programs[whatever] if w then @@ -375,11 +390,11 @@ end -- shared by urls and files -function jobreferences.whatfrom(name) +function references.whatfrom(name) texsprint(ctxcatcodes,(urls[name] and variables.url) or (files[name] and variables.file) or variables.unknown) end ---~ function jobreferences.from(name) +--~ function references.from(name) --~ local u = urls[name] --~ if u then --~ local url, file, description = u[1], u[2], u[3] @@ -404,7 +419,7 @@ end --~ end --~ end -function jobreferences.from(name) +function references.from(name) local u = urls[name] if u then local url, file, description = u[1], u[2], u[3] @@ -483,13 +498,13 @@ local function referencer(data) } end -function jobreferences.export(usedname) +function references.export(usedname) local exported = { } local e_references, e_lists = exporters.references, exporters.lists local g_references, g_lists = e_references.generic, e_lists.generic -- todo: pagenumbers -- todo: some packing - for prefix, references in next, jobreferences.tobesaved do + for prefix, references in next, references.tobesaved do local pe = exported[prefix] if not pe then pe = { } exported[prefix] = pe end for key, data in next, references do local metadata = data.metadata @@ -508,7 +523,7 @@ function jobreferences.export(usedname) end end local pe = exported[""] if not pe then pe = { } exported[""] = pe end - for n, data in next, structure.lists.tobesaved do + for n, data in next, lists.tobesaved do local metadata = data.metadata local exporter = e_lists[metadata.kind] or g_lists if exporter then @@ -533,9 +548,9 @@ function jobreferences.export(usedname) io.savedata(file.replacesuffix(usedname or tex.jobname,"tue"),table.serialize(e,true)) end -function jobreferences.import(usedname) +function references.import(usedname) if usedname then - local imported = jobreferences.imported + local imported = references.imported local jdn = imported[usedname] if not jdn then local filename = files[usedname] @@ -576,20 +591,20 @@ function jobreferences.import(usedname) end end -function jobreferences.load(usedname) +function references.load(usedname) -- gone end -function jobreferences.define(prefix,reference,list) +function references.define(prefix,reference,list) local d = defined[prefix] if not d then d = { } defined[prefix] = d end d[reference] = { "defined", list } end ---~ function jobreferences.registerspecial(name,action,...) +--~ function references.registerspecial(name,action,...) --~ specials[name] = { action, ... } --~ end -function jobreferences.reset(prefix,reference) +function references.reset(prefix,reference) local d = defined[prefix] if d then d[reference] = nil @@ -602,8 +617,6 @@ end -- t.special t.operation t.arguments t.outer t.inner -local settings_to_array = aux.settings_to_array - local function resolve(prefix,reference,args,set) -- we start with prefix,reference texcount.referencehastexstate = 0 if reference and reference ~= "" then @@ -650,13 +663,13 @@ end -- prefix == "" is valid prefix which saves multistep lookup -jobreferences.currentset = nil +references.currentset = nil -local b, e = "\\ctxlua{local jc = jobreferences.currentset;", "}" +local b, e = "\\ctxlua{local jc = references.currentset;", "}" local o, a = 'jc[%s].operation=[[%s]];', 'jc[%s].arguments=[[%s]];' -function jobreferences.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex - local currentset = jobreferences.currentset +function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex + local currentset = references.currentset if currentset and currentset.has_tex then local done = false for i=1,#currentset do @@ -732,7 +745,7 @@ local function identify(prefix,reference) var.error = "unknown special" end elseif outer then - local e = jobreferences.import(outer) + local e = references.import(outer) if e then if inner then local r = e.references @@ -749,7 +762,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = { "reference", r } - jobreferences.resolvers.reference(var) + references.resolvers.reference(var) var.f = outer var.e = true -- external end @@ -771,7 +784,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = r - jobreferences.resolvers[r[1]](var) + references.resolvers[r[1]](var) var.f = outer end end @@ -814,7 +827,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = { "reference", inner } - jobreferences.resolvers.reference(var) + references.resolvers.reference(var) var.f = outer elseif special then local s = specials[special] @@ -857,7 +870,7 @@ local function identify(prefix,reference) i = i and i[inner] if i then var.i = { "reference", i } - jobreferences.resolvers.reference(var) + references.resolvers.reference(var) var.kind = "inner" var.p = prefix else @@ -866,7 +879,7 @@ local function identify(prefix,reference) if i then var.kind = "inner" var.i = i - jobreferences.resolvers[i[1]](var) + references.resolvers[i[1]](var) var.p = prefix else i = collected[prefix] @@ -874,7 +887,7 @@ local function identify(prefix,reference) if i then var.kind = "inner" var.i = { "reference", i } - jobreferences.resolvers.reference(var) + references.resolvers.reference(var) var.p = prefix else local s = specials[inner] @@ -887,7 +900,7 @@ local function identify(prefix,reference) if i then var.kind = "inner" var.i = { "reference", i } - jobreferences.resolvers.reference(var) + references.resolvers.reference(var) var.p = "" else var.error = "unknown inner or special" @@ -901,14 +914,14 @@ local function identify(prefix,reference) bug = bug or var.error set[i] = var end - jobreferences.currentset = set + references.currentset = set --~ print(bug,table.serialize(set)) return set, bug end -jobreferences.identify = identify +references.identify = identify -function jobreferences.doifelse(prefix,reference,highlight,newwindow,layer) +function references.doifelse(prefix,reference,highlight,newwindow,layer) local set, bug = identify(prefix,reference) local unknown = bug or #set == 0 if unknown then @@ -921,7 +934,7 @@ function jobreferences.doifelse(prefix,reference,highlight,newwindow,layer) commands.doifelse(not unknown) end -function jobreferences.setinternalreference(prefix,tag,internal,view) +function references.setinternalreference(prefix,tag,internal,view) local t = { } -- maybe add to current if tag then if prefix and prefix ~= "" then @@ -938,19 +951,19 @@ function jobreferences.setinternalreference(prefix,tag,internal,view) if internal then t[#t+1] = "aut:" .. internal end - local destination = jobreferences.mark(t,nil,nil,view) -- returns an attribute + local destination = references.mark(t,nil,nil,view) -- returns an attribute texcount.lastdestinationattribute = destination return destination end -function jobreferences.getinternalreference(n) -- n points into list (todo: registers) - local l = structure.lists.collected[n] +function references.getinternalreference(n) -- n points into list (todo: registers) + local l = lists.collected[n] texsprint(ctxcatcodes,(l and l.references.internal) or n) end -- -function jobreferences.get_current_metadata(tag) +function references.get_current_metadata(tag) local data = currentreference and currentreference.i data = data and data.metadata and data.metadata[tag] if data then @@ -961,26 +974,20 @@ local function current_metadata(tag) local data = currentreference and currentreference.i return data and data.metadata and data.metadata[tag] end -jobreferences.current_metadata = current_metadata +references.current_metadata = current_metadata -function jobreferences.get_current_prefixspec(default) -- todo: message +function references.get_current_prefixspec(default) -- todo: message texsprint(ctxcatcodes,"\\getreferencestructureprefix{", current_metadata("kind") or "?", "}{", current_metadata("name") or "?", "}{", default or "?", "}") end ---~ function jobreferences.get_current_prefixspec(default) -- we can consider storing the data at the lua end +--~ function references.get_current_prefixspec(default) -- we can consider storing the data at the lua end --~ context.getreferencestructureprefix(current_metadata("kind"),current_metadata("name"),default) --~ end -- -jobreferences.filters = jobreferences.filters or { } - -local filters = jobreferences.filters -local helpers = structure.helpers -local sections = structure.sections - -function jobreferences.filter(name,...) -- number page title ... +function references.filter(name,...) -- number page title ... local data = currentreference and currentreference.i if data then local kind = data.metadata and data.metadata.kind @@ -1120,12 +1127,6 @@ filters.float = { default = filters.generic.number } filters.description = { default = filters.generic.number } filters.item = { default = filters.generic.number } -structure.references = structure.references or { } -structure.helpers = structure.helpers or { } - -local references = structure.references -local helpers = structure.helpers - function references.sectiontitle(n) helpers.sectiontitle(lists.collected[tonumber(n) or 0]) end @@ -1140,14 +1141,14 @@ end -- analyse -jobreferences.testrunners = jobreferences.testrunners or { } -jobreferences.testspecials = jobreferences.testspecials or { } +references.testrunners = references.testrunners or { } +references.testspecials = references.testspecials or { } -local runners = jobreferences.testrunners -local specials = jobreferences.testspecials +local runners = references.testrunners +local specials = references.testspecials -function jobreferences.analyse(actions) - actions = actions or jobreferences.currentset +function references.analyse(actions) + actions = actions or references.currentset if not actions then actions = { realpage = 0 } elseif actions.realpage then @@ -1181,26 +1182,26 @@ function jobreferences.analyse(actions) return actions end -function jobreferences.realpage() -- special case, we always want result - local cs = jobreferences.analyse() +function references.realpage() -- special case, we always want result + local cs = references.analyse() texwrite(cs.realpage or 0) end -- -jobreferences.pages = { - [variables.firstpage] = function() return structure.counters.record("realpage")["first"] end, - [variables.previouspage] = function() return structure.counters.record("realpage")["previous"] end, - [variables.nextpage] = function() return structure.counters.record("realpage")["next"] end, - [variables.lastpage] = function() return structure.counters.record("realpage")["last"] end, +references.pages = { + [variables.firstpage] = function() return counters.record("realpage")["first"] end, + [variables.previouspage] = function() return counters.record("realpage")["previous"] end, + [variables.nextpage] = function() return counters.record("realpage")["next"] end, + [variables.lastpage] = function() return counters.record("realpage")["last"] end, - [variables.firstsubpage] = function() return structure.counters.record("subpage" )["first"] end, - [variables.previoussubpage] = function() return structure.counters.record("subpage" )["previous"] end, - [variables.nextsubpage] = function() return structure.counters.record("subpage" )["next"] end, - [variables.lastsubpage] = function() return structure.counters.record("subpage" )["last"] end, + [variables.firstsubpage] = function() return counters.record("subpage" )["first"] end, + [variables.previoussubpage] = function() return counters.record("subpage" )["previous"] end, + [variables.nextsubpage] = function() return counters.record("subpage" )["next"] end, + [variables.lastsubpage] = function() return counters.record("subpage" )["last"] end, - [variables.forward] = function() return structure.counters.record("realpage")["forward"] end, - [variables.backward] = function() return structure.counters.record("realpage")["backward"] end, + [variables.forward] = function() return counters.record("realpage")["forward"] end, + [variables.backward] = function() return counters.record("realpage")["backward"] end, } -- maybe some day i will merge this in the backend code with a testmode (so each @@ -1221,10 +1222,10 @@ end runners["special operation"] = runners["special"] runners["special operation with arguments"] = runners["special"] -local pages = jobreferences.pages +local pages = references.pages function specials.internal(var,actions) - local v = jobreferences.internals[tonumber(var.operation)] + local v = references.internals[tonumber(var.operation)] local r = v and v.references.realpage if r then actions.realpage = r diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv index 408673f83..4a0231961 100644 --- a/tex/context/base/strc-ref.mkiv +++ b/tex/context/base/strc-ref.mkiv @@ -112,8 +112,8 @@ \newcount\lastreferenceattribute \newcount\lastdestinationattribute -\def\dofinishfullreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2")}}} -\def\dofinishtextreference#1#2{\normalexpanded{\ctxlatelua{jobreferences.enhance("#1","#2",{})}}} +\def\dofinishfullreference#1#2{\normalexpanded{\ctxlatelua{structures.references.enhance("#1","#2")}}} +\def\dofinishtextreference#1#2{\normalexpanded{\ctxlatelua{structures.references.enhance("#1","#2",{})}}} \let\dofinishpagereference\dofinishfullreference \let\dofinishuserreference\dofinishfullreference @@ -147,14 +147,14 @@ \fi \globallet\currentreferencecoding\s!tex \fi - % beware, the jobreferences.set writes a + % beware, the structures.references.set writes a % \setnextinternalreference - \ctxlua{jobreferences.setandgetattribute("\currentreferencekind", "\referenceprefix","\currentreferencelabels", + \ctxlua{structures.references.setandgetattribute("\currentreferencekind", "\referenceprefix","\currentreferencelabels", { references = { % internal = \nextinternalreference, % no need for an internal as we have an explicit block = "\currentstructureblock", - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, metadata = { % we could assume page to have no metadata kind = "#1", @@ -169,7 +169,7 @@ }, \fi \ifx\currentreferenceuserdata\empty\else - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) \fi },"\@@iafocus") }% @@ -186,11 +186,11 @@ \def\dosetsimplepagereference#1% label {\iflocation - \ctxlua{jobreferences.setandgetattribute("\s!page", "\referenceprefix","#1", + \ctxlua{structures.references.setandgetattribute("\s!page", "\referenceprefix","#1", { references = { % block = "\currentstructureblock", - % section = structure.sections.currentid(), + % section = structures.sections.currentid(), }, metadata = { % we could assume page to have no metadata kind = "\s!page", @@ -204,7 +204,7 @@ \def\dogetsimplepagereference#1% {\iflocation - \ctxlua{jobreferences.inject("\referenceprefix","#1",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#1",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% \xdef\currentreferenceattribute{\number\lastreferenceattribute}% \else \xdef\currentreferenceattribute{\number\attributeunsetvalue}% @@ -414,13 +414,13 @@ {\dodoubleempty\dodefinereference} \def\dodefinereference[#1][#2]% - {\ctxlua{jobreferences.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}} + {\ctxlua{structures.references.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}} \def\resetreference[#1]% - {\ctxlua{jobreferences.reset("\referenceprefix","#1")}} + {\ctxlua{structures.references.reset("\referenceprefix","#1")}} \def\setpagereference#1#2% name, specification - {\ctxlua{jobreferences.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}} + {\ctxlua{structures.references.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}} %D Chained references are defined as: %D @@ -450,10 +450,10 @@ \newconditional\gotonewwindow \setfalse\gotonewwindow \def\expandtexincurrentreference % will happen in lua some time - {\ifcase\referencehastexstate\else\ctxlua{jobreferences.expandcurrent()}\fi} + {\ifcase\referencehastexstate\else\ctxlua{structures.references.expandcurrent()}\fi} \def\doifreferencefoundelse#1#2#3% - {\ctxlua{jobreferences.doifelse("\referenceprefix","#1",\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow)}% + {\ctxlua{structures.references.doifelse("\referenceprefix","#1",\luaconditional\highlighthyperlinks,\luaconditional\gotonewwindow)}% {\expandtexincurrentreference#2}% {#3}} @@ -465,7 +465,7 @@ %D be called. \def\analyzecurrentreference - {\ctxlua{jobreferences.analyse()}} + {\ctxlua{structures.references.analyse()}} %D The inner case is simple. Only two cases have to be taken %D care of: @@ -490,11 +490,13 @@ %D file and, when enabled, in the left margin of the text. \def\reportreferenceerror#1#2#3% only once (keep track in lua) - {\ifinpagebody \else - \doifconcepttracing{\doifsomething{#3}{\inleft{\infofont\doboundtext{#3}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}% - \fi - \global\advance#1\plusone - \showmessage\m!references{#2}{[\referenceprefix][#3]}} + {\iftrialtypesetting \else + \ifinpagebody \else + \doifconcepttracing{\doifsomething{#3}{\inleft{\infofont\doboundtext{#3}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}% + \fi + \global\advance#1\plusone + \showmessage\m!references{#2}{[\referenceprefix][#3]}% + \fi} \newcount\nofunknownreferences \newcount\nofillegalreferences @@ -583,14 +585,14 @@ {\global\advance\locationcount\plusone} \def\setnextinternalreferences#1#2% plural - {\ctxlua{jobreferences.setnextinternal("#1","#2")}} + {\ctxlua{structures.references.setnextinternal("#1","#2")}} \def\getinternalorderreference#1#2% - {\ctxlua{jobreferences.currentorder("#1","#2")}} + {\ctxlua{structures.references.currentorder("#1","#2")}} \def\thisissomeinternal#1#2% tag reference (only for old time sake) {\begingroup - \ctxlua{jobreferences.setinternalreference("","#1:#2")}% + \ctxlua{structures.references.setinternalreference("","#1:#2")}% \hbox attr \destinationattribute\lastdestinationattribute{}% \endgroup} @@ -679,7 +681,7 @@ {\settrue \autoglobalfilereferences} {\setfalse\autoglobalfilereferences}} -% \appendtoks\ctxlua{jobreferences.export("whatever")}\to\everystoptext +% \appendtoks\ctxlua{structures.references.export("whatever")}\to\everystoptext % \starttext % \chapter[test]{test} % test \in{IN}[more] and \in{IN}[test] or \at{AT}[more] and \at{AT}[test]\par @@ -688,7 +690,7 @@ % \stoptext \def\exportreferences - {\doif\@@rfexport\v!yes{\ctxlua{jobreferences.export()}}} + {\doif\@@rfexport\v!yes{\ctxlua{structures.references.export()}}} \appendtoks \exportreferences @@ -819,14 +821,14 @@ % \definecommand from {\dospecialfrom} % \definecommand over {\dospecialabout} % needed here, else math problems -\def\currentreferencenumber {\ctxlua{jobreferences.filter("number")}} -\def\currentreferencepage {\ctxlua{jobreferences.filter("page")}} -\def\currentreferencetitle {\ctxlua{jobreferences.filter("title")}} -\def\currentreferencetext {\ctxlua{jobreferences.filter("text")}} -\def\currentreferencedefault {\ctxlua{jobreferences.filter("default")}} -\def\currentreferencerealpage{\ctxlua{jobreferences.realpage()}} +\def\currentreferencenumber {\ctxlua{structures.references.filter("number")}} +\def\currentreferencepage {\ctxlua{structures.references.filter("page")}} +\def\currentreferencetitle {\ctxlua{structures.references.filter("title")}} +\def\currentreferencetext {\ctxlua{structures.references.filter("text")}} +\def\currentreferencedefault {\ctxlua{structures.references.filter("default")}} +\def\currentreferencerealpage{\ctxlua{structures.references.realpage()}} -\def\getreferenceentry#1{\ctxlua{jobreferences.filter("#1")}} % user entry +\def\getreferenceentry#1{\ctxlua{structures.references.filter("#1")}} % user entry \unexpanded\def\dospecialabout[#1]% {\dontleavehmode @@ -1133,17 +1135,24 @@ % The unbox trick is needed in order to permit \par inside a reference. Otherwise % the reference attribute migrates to the outer boxes. +\newcount\lastsavedreferenceattribute + \newbox\referencebox +\def\revivesavedreferenceattribute % sometimes handy as no test etc needed + {\attribute\referenceattribute\lastsavedreferenceattribute} + \def\dodirectgoto#1[#2]% no test for valid references {\dontleavehmode \begingroup \attribute\referenceattribute\attributeunsetvalue +\global\lastsavedreferenceattribute\attributeunsetvalue \iflocation \dostarttagged\t!link\empty % not here - \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% \setlocationattributes\??ia \setstrut % can be option +\global\lastsavedreferenceattribute\lastreferenceattribute \attribute\referenceattribute\lastreferenceattribute #1% \dostoptagged @@ -1155,13 +1164,15 @@ \def\dodirectgotohtdp#1[#2]% no test for valid references {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation \dostarttagged\t!link\empty - \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}% \dostoptagged \setlocationattributes\??ia \attribute\referenceattribute\lastreferenceattribute +\global\lastsavedreferenceattribute\lastreferenceattribute \fi #1% \endgroup} @@ -1170,15 +1181,17 @@ {\dontleavehmode \begingroup %\setbox\referencebox\hbox\bgroup % experiment, might change again to non \par support +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation - \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + \ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}% {\expandtexincurrentreference \dostarttagged\t!link\empty - \ctxlua{jobreferences.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}% + \ctxlua{structures.references.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}% \dostoptagged \setlocationattributes\??ia \setstrut % can be option +\global\lastsavedreferenceattribute\lastreferenceattribute \attribute\referenceattribute\lastreferenceattribute}% {\unknownreference{#3}}% \fi @@ -1189,14 +1202,16 @@ \def\dogotohtdp#1#2[#3]% #2 gobbles spaces after #1 so that \goto{xx} [yy] works ok {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation - \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + \ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}% {\expandtexincurrentreference \dostarttagged\t!link\empty - \ctxlua{jobreferences.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}% + \ctxlua{structures.references.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}% \dostoptagged \setlocationattributes\??ia +\global\lastsavedreferenceattribute\lastreferenceattribute \attribute\referenceattribute\lastreferenceattribute}% {\unknownreference{#3}}% \fi @@ -1206,12 +1221,14 @@ \unexpanded\def\directgotobox#1[#2]% no test for valid references {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation \dostarttagged\t!link\empty - \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% \dostoptagged \setlocationattributes\??ia +\global\lastsavedreferenceattribute\lastreferenceattribute \hbox attr \referenceattribute \lastreferenceattribute {#1}% \else #1% @@ -1221,12 +1238,14 @@ \unexpanded\def\directgotospecbox#1#2[#3]% no test for valid references {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation \dostarttagged\t!link\empty - \ctxlua{jobreferences.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}% \dostoptagged \setlocationcolorspec{#1}% no consequence for strut +\global\lastsavedreferenceattribute\lastreferenceattribute \hbox attr \referenceattribute \lastreferenceattribute {#2}% \else #2% @@ -1236,11 +1255,13 @@ \unexpanded\def\directgotodumbbox#1[#2]% no test for valid references {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation \dostarttagged\t!link\empty - \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% + \ctxlua{structures.references.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% \dostoptagged +\global\lastsavedreferenceattribute\lastreferenceattribute \hbox attr \referenceattribute \lastreferenceattribute {#1}% \else #1% @@ -1250,14 +1271,16 @@ \unexpanded\def\gotobox#1[#2]% no test for valid references {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue \iflocation - \ctxlua{jobreferences.doifelse("\referenceprefix","#2",\extrareferencearguments)}% + \ctxlua{structures.references.doifelse("\referenceprefix","#2",\extrareferencearguments)}% {\expandtexincurrentreference \dostarttagged\t!link\empty - \ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \ctxlua{structures.references.injectcurrentset(nil,nil)}% \dostoptagged \setlocationattributes\??ia +\global\lastsavedreferenceattribute\lastreferenceattribute \hbox attr \referenceattribute \lastreferenceattribute {#1}}% {\unknownreference{#2}}% \else @@ -1268,10 +1291,12 @@ \unexpanded\def\gotowdhtbox#1#2[#3]% fast variant for overlays {\dontleavehmode \begingroup +\global\lastsavedreferenceattribute\attributeunsetvalue \attribute\referenceattribute\attributeunsetvalue - \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% - {\ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \ctxlua{structures.references.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\ctxlua{structures.references.injectcurrentset(nil,nil)}% \setbox\scratchbox\null\wd\scratchbox#1\ht\scratchbox#2% +\global\lastsavedreferenceattribute\lastreferenceattribute \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}% {\unknownreference{#3}}% \endgroup} @@ -1332,10 +1357,10 @@ \let\useexternaldocument\usefile \def\douseurl[#1][#2][#3][#4]% - {\ctxlua{jobreferences.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}} + {\ctxlua{structures.references.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}} \def\dousefile[#1][#2][#3]% - {\ctxlua{jobreferences.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} + {\ctxlua{structures.references.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}} \def\doifurldefinedelse #1{\ctxlua{commands.doifurldefinedelse ("#1")}} \def\doiffiledefinedelse#1{\ctxlua{commands.doiffiledefinedelse("#1")}} @@ -1365,7 +1390,7 @@ \begingroup \dosetfontattribute\??ur\c!style \dosetcolorattribute\??ur\c!color - \hyphenatedurl{\ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}}% + \hyphenatedurl{\ctxlua{structures.references.urls.get("#1","\@@uralternative","\@@urspace")}}% \endgroup} % # fails @@ -1415,7 +1440,7 @@ \def\dodospecialfrom[#1]% {\dontleavehmode - \goto{\ctxlua{jobreferences.from("#1")}}[fileorurl(#1)]} + \goto{\ctxlua{structures.references.from("#1")}}[fileorurl(#1)]} \def\dofromurldescription#1% {#1} @@ -1460,14 +1485,14 @@ {\dotripleargument\dodefineprogram} \def\dodefineprogram[#1][#2][#3]% - {\ctxlua{jobreferences.programs.define("#1","#2","#3")}} + {\ctxlua{structures.references.programs.define("#1","#2","#3")}} \def\program[#1]% incompatible, more consistent, hardy used anyway {\dontleavehmode \begingroup \dosetfontattribute\??pr\c!style \dosetcolorattribute\??pr\c!color - \ctxlua{jobreferences.programs.get("#1","\@@pralternative","\@@prspace")}% + \ctxlua{structures.references.programs.get("#1","\@@pralternative","\@@prspace")}% \endgroup} %D As we can see, we directly use the special reference @@ -1921,16 +1946,16 @@ % \def\getreferencestructureprefixspec#1% we can save one call by moving this to the lua end % {\getreferencestructureprefix -% {\ctxlua{jobreferences.get_current_metadata("kind")}} -% {\ctxlua{jobreferences.get_current_metadata("name")}} +% {\ctxlua{structures.references.get_current_metadata("kind")}} +% {\ctxlua{structures.references.get_current_metadata("name")}} % {#1}} % \def\currentreferencedefault -% {\ctxlua{jobreferences.filter("default",\getreferencestructureprefixspec\v!default)}} +% {\ctxlua{structures.references.filter("default",\getreferencestructureprefixspec\v!default)}} % % this is shortcut for: \def\currentreferencedefault - {\ctxlua{jobreferences.filter("default",\ctxlua{jobreferences.get_current_prefixspec("\v!default")})}} + {\ctxlua{structures.references.filter("default",\ctxlua{structures.references.get_current_prefixspec("\v!default")})}} \protect \endinput diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua index c489ff6b5..1da64d6c1 100644 --- a/tex/context/base/strc-reg.lua +++ b/tex/context/base/strc-reg.lua @@ -11,29 +11,35 @@ local texwrite, texsprint, texcount = tex.write, tex.sprint, tex.count local format, gmatch, concat = string.format, string.gmatch, table.concat local utfchar = utf.char local lpegmatch = lpeg.match +local ctxcatcodes = tex.ctxcatcodes -local trace_registers = false trackers.register("structure.registers", function(v) trace_registers = v end) +local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) local report_registers = logs.new("registers") -local ctxcatcodes = tex.ctxcatcodes +local structures = structures -local variables = interfaces.variables +structures.registers = structures.registers or { } -local helpers = structure.helpers -local sections = structure.sections -local documents = structure.documents -local pages = structure.pages -local processors = structure.processors +local registers = structures.registers +local helpers = structures.helpers +local sections = structures.sections +local documents = structures.documents +local pages = structures.pages +local processors = structures.processors +local references = structures.references -local mappings = sorters.mappings -local entries = sorters.entries -local replacements = sorters.replacements +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements local processor_split = processors.split +local variables = interfaces.variables + local matching_till_depth, number_at_depth = sections.matching_till_depth, sections.number_at_depth + -- some day we will share registers and lists (although there are some conceptual -- differences in the application of keywords) @@ -62,7 +68,7 @@ local function filter_collected(names,criterium,number,collected,prevmode) elseif criterium == variables.current then for i=1,#collected do local v = collected[i] - local sectionnumber = jobsections.collected[v.references.section] + local sectionnumber = sections.collected[v.references.section] if sectionnumber then local cnumbers = sectionnumber.numbers if prevmode then @@ -98,7 +104,7 @@ local function filter_collected(names,criterium,number,collected,prevmode) elseif criterium == variables.previous then for i=1,#collected do local v = collected[i] - local sectionnumber = jobsections.collected[v.references.section] + local sectionnumber = sections.collected[v.references.section] if sectionnumber then local cnumbers = sectionnumber.numbers if (all or hash[v.metadata.name]) and #cnumbers >= depth then @@ -143,7 +149,7 @@ local function filter_collected(names,criterium,number,collected,prevmode) local v = collected[i] local r = v.references if r then - local sectionnumber = jobsections.collected[r.section] + local sectionnumber = sections.collected[r.section] if sectionnumber then local metadata = v.metadata local cnumbers = sectionnumber.numbers @@ -167,21 +173,20 @@ local function filter_collected(names,criterium,number,collected,prevmode) return result end -jobregisters = jobregisters or { } -jobregisters.collected = jobregisters.collected or { } -jobregisters.tobesaved = jobregisters.tobesaved or { } +registers.collected = registers.collected or { } +registers.tobesaved = registers.tobesaved or { } -jobregisters.filter_collected = filter_collected +registers.filter_collected = filter_collected -- we follow a different strategy than by lists, where we have a global -- result table; we might do that here as well but since sorting code is -- older we delay that decision -local tobesaved, collected = jobregisters.tobesaved, jobregisters.collected +local tobesaved, collected = registers.tobesaved, registers.collected local function initializer() - tobesaved, collected = jobregisters.tobesaved, jobregisters.collected - local internals = jobreferences.internals + tobesaved, collected = registers.tobesaved, registers.collected + local internals = references.internals for name, list in next, collected do local entries = list.entries for e=1,#entries do @@ -197,7 +202,7 @@ local function initializer() end end -job.register('jobregisters.collected', jobregisters.tobesaved, initializer) +job.register('structures.registers.collected', registers.tobesaved, initializer) local function allocate(class) local d = tobesaved[class] @@ -215,7 +220,7 @@ local function allocate(class) return d end -jobregisters.define = allocate +registers.define = allocate local entrysplitter = lpeg.Ct(lpeg.splitat('+')) -- & obsolete in mkiv @@ -259,7 +264,7 @@ local function preprocessentries(rawdata) end end -function jobregisters.store(rawdata) -- metadata, references, entries +function registers.store(rawdata) -- metadata, references, entries local data = allocate(rawdata.metadata.name).entries local references = rawdata.references references.realpage = references.realpage or 0 -- just to be sure as it can be refered to @@ -270,14 +275,14 @@ function jobregisters.store(rawdata) -- metadata, references, entries texwrite(#data) end -function jobregisters.enhance(name,n) +function registers.enhance(name,n) local r = tobesaved[name].entries[n] if r then r.references.realpage = texcount.realpageno end end -function jobregisters.extend(name,tag,rawdata) -- maybe do lastsection internally +function registers.extend(name,tag,rawdata) -- maybe do lastsection internally if type(tag) == "string" then tag = tagged[tag] end @@ -286,7 +291,7 @@ function jobregisters.extend(name,tag,rawdata) -- maybe do lastsection internall if r then local rr = r.references rr.lastrealpage = texcount.realpageno - rr.lastsection = structure.sections.currentid() + rr.lastsection = sections.currentid() if rawdata then preprocessentries(rawdata) for k,v in next, rawdata do @@ -310,7 +315,7 @@ end local compare = sorters.comparers.basic -function jobregisters.compare(a,b) +function registers.compare(a,b) local result = compare(a,b) if result ~= 0 then return result @@ -327,11 +332,11 @@ function jobregisters.compare(a,b) return 0 end -function jobregisters.filter(data,options) - data.result = jobregisters.filter_collected(nil,options.criterium,options.number,data.entries,true) +function registers.filter(data,options) + data.result = registers.filter_collected(nil,options.criterium,options.number,data.entries,true) end -function jobregisters.prepare(data) +function registers.prepare(data) -- data has 'list' table local strip = sorters.strip local splitter = sorters.splitters.utf @@ -355,11 +360,11 @@ function jobregisters.prepare(data) end end -function jobregisters.sort(data,options) - sorters.sort(data.result,jobregisters.compare) +function registers.sort(data,options) + sorters.sort(data.result,registers.compare) end -function jobregisters.unique(data,options) +function registers.unique(data,options) local result, prev, equal = { }, nil, table.are_equal local dataresult = data.result for k=1,#dataresult do @@ -389,7 +394,7 @@ function jobregisters.unique(data,options) data.result = result end -function jobregisters.finalize(data,options) +function registers.finalize(data,options) local result = data.result data.metadata.nofsorted = #result local split, lasttag, s, d = { }, nil, nil, nil @@ -411,16 +416,16 @@ function jobregisters.finalize(data,options) data.result = split end -function jobregisters.analysed(class,options) +function registers.analysed(class,options) local data = collected[class] if data and data.entries then options = options or { } sorters.setlanguage(options.language) - jobregisters.filter(data,options) -- filter entries into results (criteria) - jobregisters.prepare(data,options) -- adds split table parallel to list table - jobregisters.sort(data,options) -- sorts results - jobregisters.unique(data,options) -- get rid of duplicates - jobregisters.finalize(data,options) -- split result in ranges + registers.filter(data,options) -- filter entries into results (criteria) + registers.prepare(data,options) -- adds split table parallel to list table + registers.sort(data,options) -- sorts results + registers.unique(data,options) -- get rid of duplicates + registers.finalize(data,options) -- split result in ranges data.metadata.sorted = true return data.metadata.nofsorted or 0 else @@ -430,8 +435,8 @@ end -- todo take conversion from index -function jobregisters.userdata(index,name) - local data = jobreferences.internals[tonumber(index)] +function registers.userdata(index,name) + local data = references.internals[tonumber(index)] data = data and data.userdata and data.userdata[name] if data then texsprint(ctxcatcodes,data) @@ -440,7 +445,7 @@ end -- proc can be wrapped -function jobregisters.flush(data,options,prefixspec,pagespec) +function registers.flush(data,options,prefixspec,pagespec) local equal = table.are_equal texsprint(ctxcatcodes,"\\startregisteroutput") local collapse_singles = options.compress == interfaces.variables.yes @@ -726,12 +731,12 @@ function jobregisters.flush(data,options,prefixspec,pagespec) data.metadata.sorted = false end -function jobregisters.analyse(class,options) - texwrite(jobregisters.analysed(class,options)) +function registers.analyse(class,options) + texwrite(registers.analysed(class,options)) end -function jobregisters.process(class,...) - if jobregisters.analysed(class,...) > 0 then - jobregisters.flush(collected[class],...) +function registers.process(class,...) + if registers.analysed(class,...) > 0 then + registers.flush(collected[class],...) end end diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index dc37423de..4c1c4be96 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -130,7 +130,7 @@ \def\dodefineregister[#1][#2]% #2? {\setupregister[#1][\s!parent=\??id]% - \ctxlua{jobregisters.define('#1')}% + \ctxlua{structures.registers.define('#1')}% \presetheadtext[#1=\Word{#1}]% \setuvalue{#1}{\dodoubleempty\doregister[#1]}% \setuvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}% @@ -223,11 +223,11 @@ % we could consider storing register entries in a list which we % could then sort \xdef\currentregisternumber{\ctxlua{ - jobregisters.store { % 'own' should not be in metadata + structures.registers.store { % 'own' should not be in metadata metadata = { kind = "entry", name = "\currentregister", - level = structure.sections.currentlevel(), + level = structures.sections.currentlevel(), coding = "\currentregistercoding", catcodes = \the\catcodetable, \ifx\currentregisterownnumber\v!yes @@ -240,7 +240,7 @@ }, references = { internal = \nextinternalreference, - section = structure.sections.currentid(), % hm, why then not also lastsection the same way + section = structures.sections.currentid(), % hm, why then not also lastsection the same way label = "\currentregisterlabel", }, % \ifx\currentregisterentries\empty \else @@ -258,14 +258,14 @@ \fi }, % \fi - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) } } }% - \ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% + \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else - \xdef\currentregistersynchronize{\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}}% + \xdef\currentregistersynchronize{\ctxlatelua{structures.registers.enhance("\currentregister",\currentregisternumber)}}% \fi \currentregistersynchronize % here? % needs thinking ... bla\index{bla}. will break before the . but adding a @@ -298,7 +298,7 @@ \fi} \def\dostopregister[#1][#2]% - {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} + {\normalexpanded{\ctxlatelua{structures.registers.extend("#1","#2")}}} \def\setregisterentry {\dotripleempty\dosetregisterentry} \def\finishregisterentry{\dotripleempty\dofinishregisterentry} @@ -330,17 +330,17 @@ \globallet\currentregistercoding\s!tex \fi \ifx\currentregisterentries\empty - \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { + \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", { metadata = { \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) })% }}% \else - \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { + \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", { metadata = { catcodes = \the\catcodetable, coding = "\currentregistercoding", @@ -352,7 +352,7 @@ % we need a special one for xml, this is just a single one \!!bs\currentregisterentries\!!es, \!!bs\currentregisterkeys\!!es }, - userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) }) }}% \fi @@ -389,7 +389,7 @@ {\doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,#3}{#4}}} \def\dostopstructurepageregister[#1][#2]% - {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} + {\normalexpanded{\ctxlatelua{structures.registers.extend("#1","#2")}}} % So far. @@ -418,16 +418,16 @@ \fi \setnextinternalreference % we could consider storing register entries in list - \edef\temp{\ctxlua{ jobregisters.store { + \edef\temp{\ctxlua{ structures.registers.store { metadata = { kind = "see", name = "\currentregister", - level = structure.sections.currentlevel(), + level = structures.sections.currentlevel(), catcodes = \the\catcodetable, }, references = { internal = \nextinternalreference, - section = structure.sections.currentid(), + section = structures.sections.currentid(), }, entries = { % we need a special one for xml, this is just a single one @@ -451,7 +451,7 @@ {\begingroup \edef\currentregister{#1}% \setupregister[\currentregister][#2]% - \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister',{ + \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{structures.registers.analyse('\currentregister',{ language = "\registerparameter\s!language", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", @@ -484,7 +484,7 @@ \c!align=\registerparameter\c!align, \c!tolerance=\registerparameter\c!tolerance]% \startpacked[\v!blank]% - \ctxlua{jobregisters.process('\currentregister',{ + \ctxlua{structures.registers.process('\currentregister',{ language = "\registerparameter\s!language", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", @@ -731,7 +731,7 @@ % \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand] % \stoptext -\def\registerpageuserdata #1#2{\ctxlua{jobregisters.userdata(#1,"#2")}} +\def\registerpageuserdata #1#2{\ctxlua{structures.registers.userdata(#1,"#2")}} \def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1} % not yet ok : new internal handler names diff --git a/tex/context/base/strc-ren.mkiv b/tex/context/base/strc-ren.mkiv index ad972d9e6..ea066569f 100644 --- a/tex/context/base/strc-ren.mkiv +++ b/tex/context/base/strc-ren.mkiv @@ -129,20 +129,44 @@ {\iflocation attr \destinationattribute \currentstructureattribute attr \referenceattribute \currentstructurereferenceattribute - \fi} + \fi} + +% \def\docheckstructureheadreference +% {\edef\currentstructureheadinteraction{\structureheadparameter\c!interaction}% +% \ifx\currentstructureheadinteraction\v!list +% \dogetsimplepagereference{bck:\nextinternalreference}% +% \let\currentstructurereferenceattribute\currentreferenceattribute +% \fi} + +\def\docheckstructureheadreference + {\edef\currentstructureheadinteraction{\structureheadparameter\c!interaction}% + \ifx\currentstructureheadinteraction\v!list + % setuphead[<section>][interaction=list,...] + \dogetsimplepagereference{bck:\nextinternalreference}% + \let\currentstructurereferenceattribute\currentreferenceattribute + \else\ifx\currentstructureheadinteraction\v!reference + % setuphead[<section>][interaction=reference,...] start<section>[backreference=abc,...] + \edef\currentstructureheadbackreference{\structurevariable{references.\c!backreference}}% + \ifx\currentstructureheadbackreference\empty \else + \dogetsimplepagereference\currentstructureheadbackreference + \let\currentstructurereferenceattribute\currentreferenceattribute + \fi + \else + % maybe auto: backreference when given, else list + \fi\fi} \def\doplacestructureheadtext#1#2#3% nodes, text, endstuff {\beginheadplacement \doresettructureheadnumbercontent \ifconditional\structureheadleaveempty - \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint {#1}% + \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint + {\dosetlocalgridsnapping{\structureheadparameter\c!internalgrid}#1}% \makestrutofbox\sectionheadbox \else - \doif{\namedstructureheadparameter\currentstructurehead\c!interaction}\v!list - {\dogetsimplepagereference{bck:\nextinternalreference}% - \let\currentstructurereferenceattribute\currentreferenceattribute}% + \docheckstructureheadreference \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute - {\doresettructureheadnumbercontent + {\dosetlocalgridsnapping{\structureheadparameter\c!internalgrid}% + \doresettructureheadnumbercontent \ifcase\headtimingmode\or#1\fi % outerside font determines distance \dosetfontattribute{\??nh\currentstructurehead}\c!style % but we don't want color to influence user command, todo: get the if-else out of it \structureheadparameter\c!command{}{\doplaceheadtextcomponent{#1}{#2}}}% @@ -156,11 +180,10 @@ \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint{#1}% \makestrutofbox\sectionheadbox \else % = needed - \doif{\namedstructureheadparameter\currentstructurehead\c!interaction}\v!list - {\dogetsimplepagereference{bck:\nextinternalreference}% - \let\currentstructurereferenceattribute\currentreferenceattribute}% + \docheckstructureheadreference \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute - {\ifcase\headtimingmode\or#1\fi + {\dosetlocalgridsnapping{\structureheadparameter\c!internalgrid}% + \ifcase\headtimingmode\or#1\fi \dosetfontattribute{\??nh\currentstructurehead}\c!style \structureheadparameter\c!command{\doplaceheadnumbercomponent{#1}{#2}}{\doplaceheadtextcomponent{#1}{#3}}}% \fi diff --git a/tex/context/base/strc-sbe.mkiv b/tex/context/base/strc-sbe.mkiv index 8497c37bb..75d78d48b 100644 --- a/tex/context/base/strc-sbe.mkiv +++ b/tex/context/base/strc-sbe.mkiv @@ -75,14 +75,14 @@ {\getparameters[\??nb#1]}% [#2] \def\dosetstructureblock[#1]% used to set the default - {\edef\currentstructureblock{\ctxlua{structure.sections.setblock("#1")}}} + {\edef\currentstructureblock{\ctxlua{structures.sections.setblock("#1")}}} \let\currentstructureblock\s!unknown \unexpanded\def\startstructureblock[#1]% - {%\ctxlua{structure.counters.check(0)}% we assume sane usage of \page, as this is the only workable place (in push) + {%\ctxlua{structures.counters.check(0)}% we assume sane usage of \page, as this is the only workable place (in push) \begingroup - \edef\currentstructureblock{\ctxlua{structure.sections.pushblock("#1")}}% + \edef\currentstructureblock{\ctxlua{structures.sections.pushblock("#1")}}% \csname #1true\endcsname % for old times sake \setsystemmode\currentstructureblock \the\everybeforestructureblock\relax @@ -91,7 +91,7 @@ \unexpanded\def\stopstructureblock {\showmessage\m!structures2\currentstructureblock \the\everyafterstructureblock\relax - \edef\currentstructureblock{\ctxlua{structure.sections.popblock()}}% + \edef\currentstructureblock{\ctxlua{structures.sections.popblock()}}% \endgroup} \long\def\setstructureblockenvironment#1#2% diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index fe2a0fddc..1dcd7f26b 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -41,14 +41,14 @@ % lua interface / names and interface might change -\def\setstructurelevel #1#2{\ctxlua{structure.sections.setlevel("#1","#2")}} % name, level|parent -\def\getstructurelevel #1{\ctxlua{structure.sections.getcurrentlevel("#1")}}% name -\def\setstructurenumber #1#2{\ctxlua{structure.sections.setnumber(#1,"#2")}} % level, number (+/-) -\def\getstructurenumber #1{\ctxlua{structure.sections.getnumber(#1)}} % level -\def\getsomestructurenumber #1#2{\ctxlua{structure.sections.getnumber(#1,"#2")}} % level, what -\def\getfullstructurenumber #1{\ctxlua{structure.sections.fullnumber(#1)}} % level -\def\getsomefullstructurenumber#1#2{\ctxlua{structure.sections.fullnumber(#1,"#2")}} -\def\getspecificstructuretitle #1{\ctxlua{structure.sections.structuredata(#1,"titledata.title",nil,"\structureheadparameter\s!catcodes")}}% +\def\setstructurelevel #1#2{\ctxlua{structures.sections.setlevel("#1","#2")}} % name, level|parent +\def\getstructurelevel #1{\ctxlua{structures.sections.getcurrentlevel("#1")}}% name +\def\setstructurenumber #1#2{\ctxlua{structures.sections.setnumber(#1,"#2")}} % level, number (+/-) +\def\getstructurenumber #1{\ctxlua{structures.sections.getnumber(#1)}} % level +\def\getsomestructurenumber #1#2{\ctxlua{structures.sections.getnumber(#1,"#2")}} % level, what +\def\getfullstructurenumber #1{\ctxlua{structures.sections.fullnumber(#1)}} % level +\def\getsomefullstructurenumber#1#2{\ctxlua{structures.sections.fullnumber(#1,"#2")}} +\def\getspecificstructuretitle #1{\ctxlua{structures.sections.structuredata(#1,"titledata.title",nil,"\structureheadparameter\s!catcodes")}}% % interface @@ -189,8 +189,8 @@ \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}% definestructurelist ? \the\everystructureheadsetup} -\def\sectionheadmarkingtitle #1#2{\ctxlua{structure.marks.title("#1","#2")}} -\def\sectionheadmarkingnumber#1#2{\ctxlua{structure.marks.number("#1","#2")}} +\def\sectionheadmarkingtitle #1#2{\ctxlua{structures.marks.title("#1","#2")}} +\def\sectionheadmarkingnumber#1#2{\ctxlua{structures.marks.number("#1","#2")}} \def\dodefineclonedstructurehead#1#2% class parent {\def\currentstructurehead{#1}% @@ -208,11 +208,11 @@ % \setstructurelevel\currentstructurehead{\structuresectionheadsection{\structuresectionheadcoupling\currentstructurehead}}% \setstructurelevel\currentstructurehead{\thenamedstructureheadlevel\currentstructurehead}% \doifelse{\structureheadparameter\c!ownnumber}\v!yes - {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadown[\currentstructurehead]}} - {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadnop[\currentstructurehead]}}% - \setevalue{\e!next \currentstructurehead}{\noexpand\donextstructurehead [\currentstructurehead]}% - \setevalue{\e!start\currentstructurehead}{\noexpand\dostartstructurehead[\currentstructurehead]}% - \setevalue{\e!stop \currentstructurehead}{\noexpand\dostopstructurehead [\currentstructurehead]}% + {\setevalue\currentstructurehead{\dohandlestructureheadown[\currentstructurehead]}} + {\setevalue\currentstructurehead{\dohandlestructureheadnop[\currentstructurehead]}}% + \setevalue{\e!next \currentstructurehead}{\donextstructurehead [\currentstructurehead]}% + \setevalue{\e!start\currentstructurehead}{\dostartstructurehead[\currentstructurehead]}% + \setevalue{\e!stop \currentstructurehead}{\dostopstructurehead [\currentstructurehead]}% \to \everystructureheadsetup % todo, check if section is defined @@ -229,37 +229,47 @@ % head construction -\def\dohandlestructureheadown{\dodoubleempty\dodohandlestructureheadown} % [ref] {nr} {title} -\def\dohandlestructureheadnop{\dodoubleempty\dodohandlestructureheadnop} % [ref] {title} -\def\dostartstructurehead {\dotripleempty\dodostartstructurehead} % [settings] [userdata] +\unexpanded\def\dohandlestructureheadown{\dodoubleempty\dodohandlestructureheadown} % [ref] {nr} {title} +\unexpanded\def\dohandlestructureheadnop{\dodoubleempty\dodohandlestructureheadnop} % [ref] {title} +\unexpanded\def\dostartstructurehead {\dotripleempty\dodostartstructurehead} % [settings] [userdata] \newconditional\currentstructureown -\def\dodohandlestructureheadown[#1][#2]#3#4% +\newtoks\everybeforestructurehead % hook, todo: before/after keys +\newtoks\everyafterstructurehead % hook, todo: before/after keys + +\unexpanded\def\dodohandlestructureheadown[#1][#2]#3#4% {\settrue\currentstructureown \dohandlestructurehead{#1}{\c!reference={#2},\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title -- -\def\dodohandlestructureheadnop[#1][#2]#3% +% \unexpanded\def\dodohandlestructureheadnop[#1][#2]#3% +% {\setfalse\currentstructureown +% \dohandlestructurehead{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title -- + +\unexpanded\def\dodohandlestructureheadnop[#1][#2]% for taco: [key=value] variant {\setfalse\currentstructureown - \dohandlestructurehead{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title -- + \doifassignmentelse{#2}\dodohandlestructureheadnopA\dodohandlestructureheadnopB{#1}{#2}} -\newtoks\everybeforestructurehead % hook, todo: before/after keys -\newtoks\everyafterstructurehead % hook, todo: before/after keys +\unexpanded\def\dodohandlestructureheadnopA#1#2% + {\dohandlestructurehead{#1}{#2}{}} + +\unexpanded\def\dodohandlestructureheadnopB#1#2#3% + {\dohandlestructurehead{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title -- -\def\dodostartstructurehead[#1][#2][#3]% for the moment no grouping, too annoying with page breaks +\unexpanded\def\dodostartstructurehead[#1][#2][#3]% for the moment no grouping, too annoying with page breaks {\setfalse\currentstructureown %\globalpushmacro\currentstructurehead \xdef\currentstructurehead{#1}% \the\everybeforestructurehead \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata -\def\dostopstructurehead[#1]% +\unexpanded\def\dostopstructurehead[#1]% {%\globalpopmacro\currentstructurehead \xdef\currentstructurehead{#1}% recover \dostoptagged\dostoptagged \the\everyafterstructurehead} -\def\donextstructurehead[#1][#2][#3]% +\unexpanded\def\donextstructurehead[#1][#2][#3]% {\setfalse\currentstructureown \xdef\currentstructurehead{#1}% \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata @@ -279,19 +289,19 @@ % When do we reset the referenceprefix? This needs to be checked. Does it work % at all? -\def\setstructureheadreference#1% reference - {\edef\structureheadreference{#1}% +\def\setstructureheadreference + {\edef\structureheadreference {\structureheadparameter\c!reference}% \edef\structureheadreferenceprefix{\structureheadparameter\c!prefix}% \ifx\structureheadreferenceprefix\empty \setupreferenceprefix[]% yes or no? \else\ifx\structureheadreferenceprefix\structureheadreferenceprefixplus \ifx\structureheadreference\empty - \setupreferenceprefix[\structureheadreferenceprefixplus] + \expanded{\setupreferenceprefix[\structureheadreferenceprefixplus]}% \else - \setupreferenceprefix[#1]% we assume just one reference + \expanded{\setupreferenceprefix[\structureheadreference]}% we assume just one reference \fi \else - \setupreferenceprefix[\structureheadreferenceprefix]% + \expanded{\setupreferenceprefix[\structureheadreferenceprefix]}% \fi\fi} \setvalue{\??nh:\c!incrementnumber:\v!yes }{\settrue \structureheaddoincrement\settrue \structureheadtolist} @@ -369,7 +379,7 @@ \unexpanded\def\fullstructureheadtitle {\dostarttagged\t!structuretitle\empty - \ctxlua{structure.sections.title()}% + \ctxlua{structures.sections.title()}% \dostoptagged} \let\currentstructurehead \empty @@ -382,7 +392,7 @@ \def\doregisterstructurehead#1#2#3% name data userdata {\structurecomponent - [\c!label={\structureheadparameter\c!label}, + [\c!label={\structureheadparameter\c!label}, % why { } \c!incrementnumber=\ifconditional\structureheaddoincrement\v!yes\else\v!no\fi, % not that needed \c!saveinlist=\ifconditional\structureheadtolist\v!yes\else\v!no\fi, \c!level=\currentstructureheadlevel, @@ -404,6 +414,7 @@ \c!sectionsegments=\structureheadparameter\c!sectionsegments, \c!reference=\structureheadreference, \c!referenceprefix=\structureheadreferenceprefix, + \c!backreference=, \c!command=, #2]% [#3]% @@ -444,14 +455,14 @@ \ifdefined \else \let\presetnumberheadalternative\relax \fi -\def\dohandlestructurehead#1#2#3% name data userdata +\def\dohandlestructurehead#1#2#3% name data userdata (we can move #1 to the caller) {\xdef\currentstructurehead {#1}% \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}% \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}% \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}% %writestatus\m!systems{setup: \currentstructurehead,\currentstructureheadcoupling,\currentstructureheadsection,\currentstructureheadlevel}% % - \setstructureheadreference{#3}% will change + \setstructureheadreference % does not do much currently \setstructureheadincrement \setstructureheadplacement \setstructureheaddisplay @@ -464,7 +475,7 @@ % % we might remove the lower level % - % not here, after optional \page: \doregisterstructurehead{#1}{#2}{#3}% + % not here, after optional \page: \doregisterstructurehead\currentstructurehead{#2}{#3}% % % \xdef\currentstructureheadcounter{\currentstructurecounter}% lua call % @@ -480,7 +491,7 @@ \ifconditional\structureheaddoincrement \ifconditional\structureheaddoplace \dostructureheadspacingbeforeyes - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \let\getstructureheadtitle\fullstructureheadtitle \ifconditional\structureheadshownumber @@ -491,12 +502,12 @@ \fi \dostructureheadspacingafteryes \else\ifconditional\structureheadhidden - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \placestructureheadhidden % only something when tracing \else \dostructureheadspacingbeforenop % toegevoegd ivm subpaginanr / tug sheets - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \placestructureheadempty % just flush 'm \dostructureheadspacingafternop @@ -504,19 +515,19 @@ \else \ifconditional\structureheaddoplace \dostructureheadspacingbeforeyes - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \let\getstructureheadtitle\fullstructureheadtitle \placestructureheadtext \dostructureheadspacingafteryes \else\ifconditional\structureheadhidden - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \placestructureheadhidden % only something when tracing \else % do nothing / should be vbox to 0pt \dostructureheadspacingbeforenop - \doregisterstructurehead{#1}{#2}{#3}% after optional \page + \doregisterstructurehead\currentstructurehead{#2}{#3}% after optional \page \let\getstructureheadsyncs\thestructureheadsynchonization \placestructureheadempty % just flush 'm \dostructureheadspacingafternop @@ -648,8 +659,8 @@ \dodocheckstructureheadlayout\v!text \c!text \dodocheckstructureheadlayout\v!footer\c!footer}} -\def\currentstructurecounter {\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead)}} -\def\previousstructurecounter{\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead-1)}} +\def\currentstructurecounter {\ctxlua{structures.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead)}} +\def\previousstructurecounter{\ctxlua{structures.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead-1)}} \def\dohandlestructureheadpagebreak {%[[\currentstructurehead @\thenamedstructureheadlevel\currentstructurehead/prev:\previousstructurecounter/curr:\currentstructurecounter]] diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua index d6f38c2c7..fed5bf58c 100644 --- a/tex/context/base/strc-syn.lua +++ b/tex/context/base/strc-syn.lua @@ -13,14 +13,18 @@ local ctxcatcodes = tex.ctxcatcodes -- interface to tex end -joblists = joblists or { } -joblists.collected = joblists.collected or { } -joblists.tobesaved = joblists.tobesaved or { } +local structures = structures -local collected, tobesaved = joblists.collected, joblists.tobesaved +structures.synonyms = structures.synonyms or { } +local synonyms = structures.synonyms + +synonyms.collected = synonyms.collected or { } +synonyms.tobesaved = synonyms.tobesaved or { } + +local collected, tobesaved = synonyms.collected, synonyms.tobesaved local function initializer() - collected, tobesaved = joblists.collected, joblists.tobesaved + collected, tobesaved = synonyms.collected, synonyms.tobesaved end local function finalizer() @@ -29,7 +33,7 @@ local function finalizer() end end -job.register('joblists.collected', joblists.tobesaved, initializer, finalizer) +job.register('structures.synonyms.collected', synonyms.tobesaved, initializer, finalizer) local function allocate(class) local d = tobesaved[class] @@ -50,12 +54,12 @@ local function allocate(class) return d end -function joblists.define(class,kind) +function synonyms.define(class,kind) local data = allocate(class) data.metadata.kind = kind end -function joblists.register(class,kind,spec) +function synonyms.register(class,kind,spec) local data = allocate(class) data.metadata.kind = kind -- runtime, not saved in format (yet) if not data.hash[spec.definition.tag or ""] then @@ -64,7 +68,7 @@ function joblists.register(class,kind,spec) end end -function joblists.registerused(class,tag) +function synonyms.registerused(class,tag) local data = allocate(class) local dht = data.hash[tag] if dht then @@ -72,7 +76,7 @@ function joblists.registerused(class,tag) end end -function joblists.synonym(class,tag) +function synonyms.synonym(class,tag) local data = allocate(class).hash local d = data[tag] if d then @@ -82,7 +86,7 @@ function joblists.synonym(class,tag) end end -function joblists.meaning(class,tag) +function synonyms.meaning(class,tag) local data = allocate(class).hash local d = data[tag] if d then @@ -92,9 +96,9 @@ function joblists.meaning(class,tag) end end -joblists.compare = sorters.comparers.basic -- (a,b) +synonyms.compare = sorters.comparers.basic -- (a,b) -function joblists.filter(data,options) +function synonyms.filter(data,options) local result = { } local entries = data.entries local all = options and options.criterium == interfaces.variables.all @@ -107,7 +111,7 @@ function joblists.filter(data,options) data.result = result end -function joblists.prepare(data) +function synonyms.prepare(data) local strip = sorters.strip local splitter = sorters.splitters.utf local result = data.result @@ -124,11 +128,11 @@ function joblists.prepare(data) end end -function joblists.sort(data,options) - sorters.sort(data.result,joblists.compare) +function synonyms.sort(data,options) + sorters.sort(data.result,synonyms.compare) end -function joblists.finalize(data,options) +function synonyms.finalize(data,options) local result = data.result data.metadata.nofsorted = #result local split = { } @@ -145,7 +149,7 @@ function joblists.finalize(data,options) data.result = split end -function joblists.flush(data,options) -- maybe pass the settings differently +function synonyms.flush(data,options) -- maybe pass the settings differently local kind = data.metadata.kind -- hack, will be done better --~ texsprint(ctxcatcodes,format("\\start%soutput",kind)) local result = data.result @@ -167,23 +171,23 @@ function joblists.flush(data,options) -- maybe pass the settings differently data.metadata.sorted = false end -function joblists.analysed(class,options) - local data = joblists.collected[class] +function synonyms.analysed(class,options) + local data = synonyms.collected[class] if data and data.entries then options = options or { } sorters.setlanguage(options.language) - joblists.filter(data,options) -- filters entries to result - joblists.prepare(data,options) -- adds split table parallel to list table - joblists.sort(data,options) -- sorts entries in result - joblists.finalize(data,options) -- do things with data.entries + synonyms.filter(data,options) -- filters entries to result + synonyms.prepare(data,options) -- adds split table parallel to list table + synonyms.sort(data,options) -- sorts entries in result + synonyms.finalize(data,options) -- do things with data.entries data.metadata.sorted = true end return data and data.metadata.sorted and data.result and next(data.result) end -function joblists.process(class,options) - if joblists.analysed(class,options) then - joblists.flush(joblists.collected[class],options) +function synonyms.process(class,options) + if synonyms.analysed(class,options) then + synonyms.flush(synonyms.collected[class],options) end end diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv index 0866ea209..1c59ad7a4 100644 --- a/tex/context/base/strc-syn.mkiv +++ b/tex/context/base/strc-syn.mkiv @@ -116,7 +116,7 @@ \fi \getparameters[\??sm#1][\s!parent=\??sm,\s!single={#1},\s!multi={#2}]% \presetheadtext[#2=\Word{#2}]% changes the \if...argument - %\ctxlua{joblists.define('#1')}% + %\ctxlua{structures.synonyms.define('#1')}% \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete \setvalue{\e!place \e!listof#2}{\placelistofsynonyms[#1]}% accepts extra argument \setvalue{\e!complete\e!listof#2}{\completelistofsynonyms[#1]}} @@ -137,7 +137,7 @@ \edef\currentsynonymexpansion{\synonymparameter\c!expansion}% \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}% \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}% - \ctxlua{joblists.register("\currentsynonym", "synonym", { + \ctxlua{structures.synonyms.register("\currentsynonym", "synonym", { metadata = { catcodes = \the\catcodetable, coding = "\currentsynonymcoding", @@ -158,20 +158,20 @@ {\dodoubleargument\doregistersynonym} \def\registersynonym[#1][#2]% - {\ctxlua{joblists.registerused("#1","#2")}} + {\ctxlua{structures.synonyms.registerused("#1","#2")}} \unexpanded\def\doinsertsynonymmeaning#1#2% name tag {\begingroup \def\currentsynonym{#1}% \dosetsynonymattributes\c!textstyle\c!textcolor - \synonymparameter\c!textcommand{\ctxlua{joblists.meaning("#1","#2")}}% + \synonymparameter\c!textcommand{\ctxlua{structures.synonyms.meaning("#1","#2")}}% \endgroup} \unexpanded\def\doinsertsynonym#1#2% name tag {\begingroup \def\currentsynonym{#1}% \dosetsynonymattributes\c!synonymstyle\c!synonymcolor - \synonymparameter\c!synonymcommand{\ctxlua{joblists.synonym("#1","#2")}}% + \synonymparameter\c!synonymcommand{\ctxlua{structures.synonyms.synonym("#1","#2")}}% \normalexpanded{\endgroup\synonymparameter\c!next}} \unexpanded\def\placelistofsynonyms @@ -200,7 +200,7 @@ \c!color=. #2]% \startpacked - \ctxlua{joblists.process('#1',{ criterium = "\synonymparameter\c!criterium" })}% + \ctxlua{structures.synonyms.process('#1',{ criterium = "\synonymparameter\c!criterium" })}% \stoppacked \endgroup} @@ -282,7 +282,7 @@ \fi \getparameters[\??so#1][\s!parent=\??so,\s!multi={#2}]% \presetheadtext[#2=\Word{#2}]% after \ifthirdargument -) - %\ctxlua{joblists.define('#1')}% + %\ctxlua{structures.synonyms.define('#1')}% \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??so#1]}% to be obsolete \setvalue{\e!place \e!listof#2}{\placelistofsorts[#1]}% \setvalue{\e!complete\e!listof#2}{\completelistofsorts[#1]}} @@ -302,7 +302,7 @@ \else \edef\currentsortingexpansion{\sortingparameter\c!expansion}% \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}% - \ctxlua{joblists.register("\currentsorting", "sorting", { + \ctxlua{structures.synonyms.register("\currentsorting", "sorting", { metadata = { catcodes = \the\catcodetable, coding = "\currentsortingcoding", @@ -323,14 +323,14 @@ % no kap currently, of .. we need to map cap onto WORD \edef\currentsorting{#1}% \dosetsynonymattributes\c!style\c!color - \ctxlua{joblists.synonym("#1","#2")}% + \ctxlua{structures.synonyms.synonym("#1","#2")}% \normalexpanded{\endgroup\sortingparameter\c!next}} \def\registersort {\dodoubleargument\doregistersort} \def\registersort[#1][#2]% - {\ctxlua{joblists.registerused("#1","#2")}} + {\ctxlua{structures.synonyms.registerused("#1","#2")}} % before after % @@ -344,7 +344,7 @@ \def\currentsorting{#1}% \getparameters[\??so#1][#2]% \startpacked - \ctxlua{joblists.process('#1',{ criterium = "\sortingparameter\c!criterium" })}% + \ctxlua{structures.synonyms.process('#1',{ criterium = "\sortingparameter\c!criterium" })}% \stoppacked \endgroup} @@ -373,7 +373,7 @@ % \def\mkloadsortedlist#1% class % {\bgroup % \getvalue{\s!set#1}% -% \ctxlua{joblists.process('#1')}% +% \ctxlua{structures.synonyms.process('#1')}% % \getvalue{\s!reset#1}% % \egroup} diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua index d69525bc9..981a336b9 100644 --- a/tex/context/base/strc-tag.lua +++ b/tex/context/base/strc-tag.lua @@ -12,29 +12,33 @@ local insert, remove, unpack, concat = table.insert, table.remove, table.unpack, local gsub, find, topattern, format = string.gsub, string.find, string.topattern, string.format local lpegmatch = lpeg.match local texattribute = tex.attribute -local unsetvalue = attributes.unsetvalue -structure.tags = structure.tags or { } +local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) local report_tags = logs.new("tags") -local trace_tags = false trackers.register("structure.tags", function(v) trace_tags = v end) +local attributes, structures = attributes, structures -local a_tagged = attributes.private('tagged') -local a_image = attributes.private('image') +local a_tagged = attributes.private('tagged') +local a_image = attributes.private('image') -local tags, labels, stack, chain, ids, enabled = { }, { }, { }, { }, { }, false -- no grouping assumed +local unsetvalue = attributes.unsetvalue +local codeinjections = backends.codeinjections -structure.tags.taglist = tags -- can best be hidden +local taglist, labels, stack, chain, ids, enabled = { }, { }, { }, { }, { }, false -- no grouping assumed -function structure.tags.start(tag,label,detail) +structures.tags = structures.tags or { } +local tags = structures.tags +tags.taglist = taglist -- can best be hidden + +function tags.start(tag,label,detail) --~ labels[label or tag] = tag labels[tag] = label ~= "" and label or tag if detail and detail ~= "" then tag = tag .. ":" .. detail end if not enabled then - backends.codeinjections.enabletags(tags,labels) + codeinjections.enabletags(tags,labels) enabled = true end local n = (ids[tag] or 0) + 1 @@ -42,12 +46,12 @@ function structure.tags.start(tag,label,detail) chain[#chain+1] = tag .. "-" .. n -- insert(chain,tag .. ":" .. n) local t = #tags + 1 stack[#stack+1] = t -- insert(stack,t) - tags[t] = { unpack(chain) } -- we can add key values for alt and actualtext if needed + taglist[t] = { unpack(chain) } -- we can add key values for alt and actualtext if needed texattribute[a_tagged] = t return t end -function structure.tags.stop() +function tags.stop() local t = stack[#stack] stack[#stack] = nil -- local t = remove(stack) if not t then if trace_tags then @@ -61,12 +65,12 @@ function structure.tags.stop() return t end -function structure.atlocation(str) - local location = gsub(concat(tags[texattribute[a_tagged]],"-"),"%-%d+","") +function structures.atlocation(str) + local location = gsub(concat(taglist[texattribute[a_tagged]],"-"),"%-%d+","") return find(location,topattern(str)) ~= nil end -function structure.tags.handler(head) -- we need a dummy +function tags.handler(head) -- we need a dummy return head, false end @@ -80,7 +84,7 @@ end) directives.register("backend.addtags", function(v) if not enabled then - backends.codeinjections.enabletags(tags,labels) + codeinjections.enabletags(tags,labels) enabled = true end end) diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv index 53323050a..05893c4c7 100644 --- a/tex/context/base/strc-tag.mkiv +++ b/tex/context/base/strc-tag.mkiv @@ -106,8 +106,8 @@ \unexpanded\def\dostartelement{\iftrialtypesetting\expandafter\noostartelement\else\expandafter\dodostartelement\fi} \unexpanded\def\dostopelement {\iftrialtypesetting \else\expandafter\dodostopelement \fi} -\unexpanded\def\dodostartelement[#1]{\ctxlua{structure.tags.start("#1","\dogetupsometaglabeltext{#1}")}} -\unexpanded\def\dodostopelement {\ctxlua{structure.tags.stop()}} +\unexpanded\def\dodostartelement[#1]{\ctxlua{structures.tags.start("#1","\dogetupsometaglabeltext{#1}")}} +\unexpanded\def\dodostopelement {\ctxlua{structures.tags.stop()}} \unexpanded\def\nostartelement[#1]{} \unexpanded\def\nostopelement {} @@ -117,8 +117,8 @@ \def\dodostarttagged{\iftrialtypesetting\expandafter\nodostarttagged\else\expandafter\dododostarttagged\fi} \def\dodostoptagged {\iftrialtypesetting \else\expandafter\dododostoptagged \fi} -\def\dododostarttagged#1#2{\ctxlua{structure.tags.start("#1","\dogetupsometaglabeltext{#1}","#2")}} -\def\dododostoptagged {\ctxlua{structure.tags.stop()}} +\def\dododostarttagged#1#2{\ctxlua{structures.tags.start("#1","\dogetupsometaglabeltext{#1}","#2")}} +\def\dododostoptagged {\ctxlua{structures.tags.stop()}} \def\nodostarttagged#1#2{} \def\nodostoptagged {} @@ -187,6 +187,6 @@ % \doifinelementelse{division:*-structure:chapter} {yes} {no} \def\doifinelementelse#1% - {\ctxlua{commands.testcase(structure.atlocation("#1"))}} + {\ctxlua{commands.testcase(structures.atlocation("#1"))}} \protect diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua index e289f530a..83cef81a1 100644 --- a/tex/context/base/supp-fil.lua +++ b/tex/context/base/supp-fil.lua @@ -21,18 +21,22 @@ local trace_modules = false trackers.register("modules.loading", function(v) tr local report_modules = logs.new("modules") -support = support or { } -environment = environment or { } +commands = commands or { } +local commands = commands +environment = environment or { } +local environment = environment -function support.checkfilename(str) -- "/whatever..." "c:..." "http://..." +function commands.checkfilename(str) -- "/whatever..." "c:..." "http://..." commands.chardef("kindoffile",boolean.tonumber(find(str,"^/") or find(str,"[%a]:"))) end -function support.thesanitizedfilename(str) +function commands.thesanitizedfilename(str) texwrite((gsub(str,"\\","/"))) end -function support.splitfilename(fullname) +local def, chardef, testcase = commands.def, commands.chardef, commands.testcase + +function commands.splitfilename(fullname) local path, name, base, suffix, kind = '', fullname, fullname, '', 0 local p, n = match(fullname,"^(.+)/(.-)$") if p and n then @@ -49,44 +53,44 @@ function support.splitfilename(fullname) else kind = 2 end - commands.def("splitofffull", fullname) - commands.def("splitoffpath", path) - commands.def("splitoffbase", base) - commands.def("splitoffname", name) - commands.def("splitofftype", suffix) - commands.chardef("splitoffkind", kind) + def("splitofffull", fullname) + def("splitoffpath", path) + def("splitoffbase", base) + def("splitoffname", name) + def("splitofftype", suffix) + chardef("splitoffkind", kind) end -function support.splitfiletype(fullname) +function commands.splitfiletype(fullname) local name, suffix = fullname, '' local n, s = match(fullname,"^(.+)%.(.-)$") if n and s then name, suffix = n, s end - commands.def("splitofffull", fullname) - commands.def("splitoffpath", "") - commands.def("splitoffname", name) - commands.def("splitofftype", suffix) + def("splitofffull", fullname) + def("splitoffpath", "") + def("splitoffname", name) + def("splitofftype", suffix) end -function support.doifparentfileelse(n) - commands.testcase(n==environment.jobname or n==environment.jobname..'.tex' or n==environment.outputfilename) +function commands.doifparentfileelse(n) + testcase(n==environment.jobname or n==environment.jobname..'.tex' or n==environment.outputfilename) end -- saves some .15 sec on 12 sec format generation local lastexistingfile = "" -function support.doiffileexistelse(name) +function commands.doiffileexistelse(name) if not name or name == "" then lastexistingfile = "" else lastexistingfile = resolvers.findtexfile(name) or "" end - return commands.testcase(lastexistingfile ~= "") + return testcase(lastexistingfile ~= "") end -function support.lastexistingfile() +function commands.lastexistingfile() texsprint(ctxcatcodes,lastexistingfile) end @@ -125,7 +129,7 @@ local function readfilename(specification,backtrack,treetoo) return fnd or "" end -support.readfilename = readfilename +commands.readfilename = readfilename function finders.job(filename) return readfilename(filename,nil,false) end -- current path, no backtracking function finders.loc(filename) return readfilename(filename,2, false) end -- current path, backtracking @@ -141,7 +145,7 @@ openers.fix = openers.generic loaders.fix = loaders.generic openers.set = openers.generic loaders.set = loaders.generic openers.any = openers.generic loaders.any = loaders.generic -function support.doreadfile(protocol,path,name) -- better do a split and then pass table +function commands.doreadfile(protocol,path,name) -- better do a split and then pass table local specification if url.hasscheme(name) then specification = name @@ -171,14 +175,14 @@ local function usemodule(name,hasscheme) if trace_modules then report_modules("checking suffix driven file '%s'",name) end - foundname = support.readfilename(name,false,true) or "" + foundname = commands.readfilename(name,false,true) or "" else for i=1,#suffixes do local fullname = file.addsuffix(name,suffixes[i]) if trace_modules then report_modules("checking suffix driven file '%s'",fullname) end - foundname = support.readfilename(fullname,false,true) or "" + foundname = commands.readfilename(fullname,false,true) or "" if foundname ~= "" then break end @@ -197,7 +201,7 @@ local function usemodule(name,hasscheme) end end -function support.usemodules(prefix,askedname,truename) +function commands.usemodules(prefix,askedname,truename) local hasprefix = prefix and prefix ~= "" local hashname = ((hasprefix and prefix) or "*") .. "-" .. truename local status = modstatus[hashname] diff --git a/tex/context/base/supp-fil.mkiv b/tex/context/base/supp-fil.mkiv index 872612eab..6f89735e3 100644 --- a/tex/context/base/supp-fil.mkiv +++ b/tex/context/base/supp-fil.mkiv @@ -12,7 +12,7 @@ %C details. %D \TEX\ operates on files, so one wouldn't wonder that there -%D is a separate module for file support. In \CONTEXT\ files +%D is a separate module for file commands. In \CONTEXT\ files %D are used for several purposes: %D %D \startitemize[packed] @@ -106,8 +106,8 @@ \def\writeln#1{\write#1{}} -\def\doiffileexistselse #1{\ctxlua{support.doiffileexistelse([[#1]])}} -\def\lastfoundexistingfile {\ctxlua{support.lastexistingfile()}} +\def\doiffileexistselse #1{\ctxlua{commands.doiffileexistelse([[#1]])}} +\def\lastfoundexistingfile {\ctxlua{commands.lastexistingfile()}} %D \macros %D {doprocessfile,fileline,fileprocessedtrue,dofinishfile} @@ -172,13 +172,13 @@ {\edef#3{#2}} {\edef#3{#1\f!pathseparator#2}}} -\def\sanitizefilename#1\to#2{\edef#2{\ctxlua{support.thesanitizedfilename([[#1]])}}} +\def\sanitizefilename#1\to#2{\edef#2{\ctxlua{commands.thesanitizedfilename([[#1]])}}} %D NEW: \chardef\kindoffile=0 % 0=normal 1=full path spec (or http) / set at the lua end -\def\checkfilename#1{\ctxlua{support.checkfilename([[#1]])}} +\def\checkfilename#1{\ctxlua{commands.checkfilename([[#1]])}} %D \macros %D {input, normalinput} @@ -254,7 +254,7 @@ % a format is generated on a source path. \def\doreadfile#1#2#3% protocol path filename true false - {\edef\readfilename{\ctxlua{support.doreadfile("#1","#2","#3")}}% + {\edef\readfilename{\ctxlua{commands.doreadfile("#1","#2","#3")}}% \ifx\readfilename\empty \expandafter\doreadfilenop \else @@ -403,7 +403,7 @@ \ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi -\def\doifparentfileelse#1{\ctxlua{support.doifparentfileelse([[#1]])}} +\def\doifparentfileelse#1{\ctxlua{commands.doifparentfileelse([[#1]])}} \newcount\readingfilelevel @@ -458,7 +458,7 @@ \let\splitoffname\empty \let\splitofftype\empty -\def\splitfilename#1{\ctxlua{support.splitfilename([[#1]])}} -\def\splitfiletype#1{\ctxlua{support.splitfiletype([[#1]])}} +\def\splitfilename#1{\ctxlua{commands.splitfilename([[#1]])}} +\def\splitfiletype#1{\ctxlua{commands.splitfiletype([[#1]])}} \protect \endinput diff --git a/tex/context/base/supp-ran.lua b/tex/context/base/supp-ran.lua index 76e57e933..5263208eb 100644 --- a/tex/context/base/supp-ran.lua +++ b/tex/context/base/supp-ran.lua @@ -12,7 +12,9 @@ if not modules then modules = { } end modules ['supp-ran'] = { local report_system = logs.new("system") commands = commands or { } +local commands = commands +local math = math local random, randomseed, round, seed, last = math.random, math.randomseed, math.round, false, 1 local texwrite = tex.write diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index fcc1ee88f..2d3355b72 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -5896,9 +5896,26 @@ %D helps a lot. The second boolena can be used to inhibit %D processing completely. -\newif\iftrialtypesetting \trialtypesettingfalse \newif\ifvisible \visibletrue +\newif \iftrialtypesetting +\newcount\trialtypesettingmode % we need to find a way to query conditionals so this one can become obsolete +\newtoks \everysettrialtypesetting +\newtoks \everyresettrialtypesetting + +\unexpanded\def\settrialtypesetting {\the\everysettrialtypesetting } % obeys grouping so +\unexpanded\def\resettrialtypesetting{\the\everyresettrialtypesetting} % this one is seldom needed + +\appendtoks + \trialtypesettingtrue + \trialtypesettingmode\plusone +\to \everysettrialtypesetting + +\appendtoks + \trialtypesettingfalse + \trialtypesettingmode\zerocount +\to \everyresettrialtypesetting + %D \macros %D {startlocal, startglobal} %D diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua index 6711bf737..94928dd01 100644 --- a/tex/context/base/syst-lua.lua +++ b/tex/context/base/syst-lua.lua @@ -12,7 +12,7 @@ local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes -commands = commands or { } cs = commands -- shorter +commands = commands or { } -- cs = commands -- shorter, maybe some day, not used now function commands.writereport(...) logs.report(...) end -- not that efficient function commands.writestatus(...) logs.status(...) end diff --git a/tex/context/base/tabl-ltb.mkiv b/tex/context/base/tabl-ltb.mkiv index 7d3fab0df..a1f92cedc 100644 --- a/tex/context/base/tabl-ltb.mkiv +++ b/tex/context/base/tabl-ltb.mkiv @@ -745,7 +745,7 @@ \unexpanded\def\startlinetableanalysis {\bgroup \linetableprerolltrue - \trialtypesettingtrue + \settrialtypesetting \startlinetablerun} \unexpanded\def\stoplinetableanalysis diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index e183e5552..3d5a90cd2 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -1052,8 +1052,8 @@ \chardef\tblpass\plusone \let\makeTBL\domakeTBLone \let\handleTBLcell\dohandleTBLcellA - \setbox0\vbox{\trialtypesettingtrue \flushtbltoks}% -% \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}% + \setbox0\vbox{\settrialtypesetting \flushtbltoks}% +% \setbox\scratchbox\vbox{\settrialtypesetting \flushtbltoks}% \lettbldis\maximumcol\zeropoint \ifautoTBLspread % experimental, stretch non fixed cells to \hsize @@ -1061,13 +1061,13 @@ \checktblwidthstwo % real run \stretchtblwidths \let\handleTBLcell\dohandleTBLcellB - \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}% + \setbox\scratchbox\vbox{\settrialtypesetting \flushtbltoks}% \else\ifdim\wd0>\hsize \ifautoTBLhsize \checktblwidthsone % trial run \checktblwidthstwo % real run \let\handleTBLcell\dohandleTBLcellB - \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}% + \setbox\scratchbox\vbox{\settrialtypesetting \flushtbltoks}% \fi \else\ifautoTBLrowspan\ifnum\maximumrowspan>1 % max ? % added jan 2002 because nx=* did no longer work @@ -1078,12 +1078,12 @@ \hsize\savedhsize % \let\handleTBLcell\dohandleTBLcellC - \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}% + \setbox\scratchbox\vbox{\settrialtypesetting \flushtbltoks}% \fi\fi\fi\fi \let\handleTBLcell\dohandleTBLcellD \chardef\tblpass\plustwo \let\makeTBL\domakeTBLtwo - \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}% + \setbox\scratchbox\vbox{\settrialtypesetting \flushtbltoks}% \checktblheightsone \checktblheightstwo \let\handleTBLcell\dohandleTBLcellE diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index 196a21850..9e0479283 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -1328,7 +1328,7 @@ \setbox0\vbox % outside \if because of line counting {\notesenabledfalse \let\tabulateindent\!!zeropoint - \trialtypesettingtrue % very important + \settrialtypesetting % very important \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}}% \ifnum\nofautotabulate>\zerocount % so, even if the natural size is larger, in the final diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index a04736487..1bbad4f9f 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -11,97 +11,102 @@ if not modules then modules = { } end modules ['task-ini'] = { -- -- we can disable more handlers and enable then when really used (*) -tasks.appendaction("processors", "normalizers", "fonts.collections.process") -- todo -tasks.appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled - -tasks.appendaction("processors", "characters", "mirroring.handler") -- disabled -tasks.appendaction("processors", "characters", "typesetting.cases.handler") -- disabled -tasks.appendaction("processors", "characters", "typesetting.breakpoints.handler") -- disabled -tasks.appendaction("processors", "characters", "scripts.preprocess") - -tasks.appendaction("processors", "words", "kernel.hyphenation") -- always on -tasks.appendaction("processors", "words", "languages.words.check") -- disabled - -tasks.appendaction("processors", "fonts", "parbuilders.solutions.splitters.split") -- experimental -tasks.appendaction("processors", "fonts", "nodes.process_characters") -- maybe todo -tasks.appendaction("processors", "fonts", "nodes.inject_kerns") -- maybe todo -tasks.appendaction("processors", "fonts", "nodes.protect_glyphs", nil, "nohead") -- maybe todo -tasks.appendaction("processors", "fonts", "kernel.ligaturing") -- always on -tasks.appendaction("processors", "fonts", "kernel.kerning") -- always on -tasks.appendaction("processors", "fonts", "nodes.stripping.process") -- disabled (might move) - -tasks.appendaction("processors", "lists", "typesetting.spacings.handler") -- disabled -tasks.appendaction("processors", "lists", "typesetting.kerns.handler") -- disabled -tasks.appendaction("processors", "lists", "typesetting.digits.handler") -- disabled (after otf handling) - -tasks.appendaction("shipouts", "normalizers", "nodes.cleanup_page") -- maybe todo -tasks.appendaction("shipouts", "normalizers", "nodes.add_references") -- disabled -tasks.appendaction("shipouts", "normalizers", "nodes.add_destinations") -- disabled -tasks.appendaction("shipouts", "normalizers", "nodes.rules.process") -- disabled -tasks.appendaction("shipouts", "normalizers", "nodes.shifts.process") -- disabled -tasks.appendaction("shipouts", "normalizers", "structure.tags.handler") -- disabled -tasks.appendaction("shipouts", "normalizers", "nodes.accessibility.handler") -- disabled - -tasks.appendaction("shipouts", "finishers", "shipouts.handle_color") -- disabled -tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency") -- disabled -tasks.appendaction("shipouts", "finishers", "shipouts.handle_colorintent") -- disabled -tasks.appendaction("shipouts", "finishers", "shipouts.handle_negative") -- disabled -tasks.appendaction("shipouts", "finishers", "shipouts.handle_effect") -- disabled -tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer") -- disabled - -tasks.appendaction("math", "normalizers", "noads.relocate_characters", nil, "nohead") -- always on -tasks.appendaction("math", "normalizers", "noads.resize_characters", nil, "nohead") -- always on -tasks.appendaction("math", "normalizers", "noads.respace_characters", nil, "nohead") -- always on -tasks.appendaction("math", "normalizers", "noads.check_alternates", nil, "nohead") -- always on -tasks.appendaction("math", "normalizers", "noads.add_tags", nil, "nohead") -- disabled - -tasks.appendaction("math", "builders", "noads.mlist_to_hlist") -- always on +local tasks = nodes.tasks + +tasks.appendaction("processors", "normalizers", "fonts.collections.process") -- todo +tasks.appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled + +tasks.appendaction("processors", "characters", "typesetters.directions.handler") -- disabled +tasks.appendaction("processors", "characters", "typesetters.cases.handler") -- disabled +tasks.appendaction("processors", "characters", "typesetters.breakpoints.handler") -- disabled +tasks.appendaction("processors", "characters", "scripts.preprocess") + +tasks.appendaction("processors", "words", "builders.kernel.hyphenation") -- always on +tasks.appendaction("processors", "words", "languages.words.check") -- disabled + +tasks.appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental +tasks.appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo +tasks.appendaction("processors", "fonts", "nodes.handlers.injectkerns") -- maybe todo +tasks.appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo +tasks.appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on +tasks.appendaction("processors", "fonts", "builders.kernel.kerning") -- always on +tasks.appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move) + +tasks.appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled +tasks.appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled +tasks.appendaction("processors", "lists", "typesetters.digits.handler") -- disabled (after otf handling) + +tasks.appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.references.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.destinations.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.rules.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.shifts.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "structures.tags.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled + +tasks.appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled +tasks.appendaction("shipouts", "finishers", "attributes.transparencies.handler") -- disabled +tasks.appendaction("shipouts", "finishers", "attributes.colorintents.handler") -- disabled +tasks.appendaction("shipouts", "finishers", "attributes.negatives.handler") -- disabled +tasks.appendaction("shipouts", "finishers", "attributes.effects.handler") -- disabled +tasks.appendaction("shipouts", "finishers", "attributes.viewerlayers.handler") -- disabled + +tasks.appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.handlers.check", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled + +tasks.appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on -- quite experimental -tasks.appendaction("finalizers", "lists", "nodes.repackage_graphicvadjust") -- todo -tasks.appendaction("finalizers", "fonts", "parbuilders.solutions.splitters.optimize") -- experimental +tasks.appendaction("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo +tasks.appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental -- rather new -tasks.appendaction("mvlbuilders", "normalizers", "nodes.migrate_outwards") -tasks.appendaction("mvlbuilders", "normalizers", "nodes.handle_page_spacing") -- last ! +tasks.appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate") -- +tasks.appendaction("mvlbuilders", "normalizers", "nodes.handlers.pagespacing") -- last ! -tasks.appendaction("vboxbuilders", "normalizers", "nodes.handle_vbox_spacing") +tasks.appendaction("vboxbuilders", "normalizers", "nodes.handlers.vboxspacing") -- -- speedup: only kick in when used tasks.disableaction("processors", "fonts.checkers.missing") tasks.disableaction("processors", "chars.handle_breakpoints") -tasks.disableaction("processors", "typesetting.cases.handler") -tasks.disableaction("processors", "typesetting.digits.handler") -tasks.disableaction("processors", "typesetting.breakpoints.handler") -tasks.disableaction("processors", "mirroring.handler") +tasks.disableaction("processors", "typesetters.cases.handler") +tasks.disableaction("processors", "typesetters.digits.handler") +tasks.disableaction("processors", "typesetters.breakpoints.handler") +tasks.disableaction("processors", "typesetters.directions.handler") tasks.disableaction("processors", "languages.words.check") -tasks.disableaction("processors", "typesetting.spacings.handler") -tasks.disableaction("processors", "typesetting.kerns.handler") -tasks.disableaction("processors", "nodes.stripping.process") - -tasks.disableaction("shipouts", "nodes.rules.process") -tasks.disableaction("shipouts", "nodes.shifts.process") -tasks.disableaction("shipouts", "shipouts.handle_color") -tasks.disableaction("shipouts", "shipouts.handle_transparency") -tasks.disableaction("shipouts", "shipouts.handle_colorintent") -tasks.disableaction("shipouts", "shipouts.handle_effect") -tasks.disableaction("shipouts", "shipouts.handle_negative") -tasks.disableaction("shipouts", "shipouts.handle_viewerlayer") -tasks.disableaction("shipouts", "structure.tags.handler") -tasks.disableaction("shipouts", "nodes.accessibility.handler") - -tasks.disableaction("shipouts", "nodes.add_references") -tasks.disableaction("shipouts", "nodes.add_destinations") - -tasks.disableaction("mvlbuilders", "nodes.migrate_outwards") - -tasks.disableaction("processors", "parbuilders.solutions.splitters.split") -tasks.disableaction("finalizers", "parbuilders.solutions.splitters.optimize") - -tasks.disableaction("math", "noads.add_tags") +tasks.disableaction("processors", "typesetters.spacings.handler") +tasks.disableaction("processors", "typesetters.kerns.handler") +tasks.disableaction("processors", "nodes.handlers.stripping") + +tasks.disableaction("shipouts", "nodes.rules.handler") +tasks.disableaction("shipouts", "nodes.shifts.handler") +tasks.disableaction("shipouts", "attributes.colors.handler") +tasks.disableaction("shipouts", "attributes.transparencies.handler") +tasks.disableaction("shipouts", "attributes.colorintents.handler") +tasks.disableaction("shipouts", "attributes.effects.handler") +tasks.disableaction("shipouts", "attributes.negatives.handler") +tasks.disableaction("shipouts", "attributes.viewerlayers.handler") +tasks.disableaction("shipouts", "structures.tags.handler") +tasks.disableaction("shipouts", "nodes.handlers.accessibility") +tasks.disableaction("shipouts", "nodes.handlers.backgrounds") +tasks.disableaction("shipouts", "nodes.handlers.cleanuppage") + +tasks.disableaction("shipouts", "nodes.references.handler") +tasks.disableaction("shipouts", "nodes.destinations.handler") + +tasks.disableaction("mvlbuilders", "nodes.handlers.migrate") + +tasks.disableaction("processors", "builders.paragraphs.solutions.splitters.split") +tasks.disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") + +tasks.disableaction("math", "noads.handlers.tags") callbacks.freeze("find_.*_file", "find file using resolver") callbacks.freeze("read_.*_file", "read file at once") diff --git a/tex/context/base/toks-ini.lua b/tex/context/base/toks-ini.lua index ec60402d8..67da7fea6 100644 --- a/tex/context/base/toks-ini.lua +++ b/tex/context/base/toks-ini.lua @@ -6,9 +6,8 @@ if not modules then modules = { } end modules ['toks-ini'] = { } local utf = unicode.utf8 -local format, gsub, texsprint = string.format, string.gsub, tex.sprint - -local ctxcatcodes = tex.ctxcatcodes +local utfbyte, utfchar = utf.byte, utf.char +local format, gsub = string.format, string.gsub --[[ldx-- <p>This code is experimental and needs a cleanup. The visualizers will move to @@ -32,85 +31,86 @@ a module.</p> -- actually, we can use token registers to store tokens -tokens = tokens or { } +local token, tex = token, tex + +local texsprint = tex.sprint +local ctxcatcodes = tex.ctxcatcodes + +local createtoken = token.create +local csname_id = token.csname_id +local command_id = token.command_id +local command_name = token.command_name +local get_next = token.get_next +local expand = token.expand +local is_activechar = token.is_activechar +local csname_name = token.csname_name -tokens.vbox = token.create("vbox") -tokens.hbox = token.create("hbox") -tokens.vtop = token.create("vtop") -tokens.bgroup = token.create(utf.byte("{"), 1) -tokens.egroup = token.create(utf.byte("}"), 2) +tokens = tokens or { } +local tokens = tokens -tokens.letter = function(chr) return token.create(utf.byte(chr), 11) end -tokens.other = function(chr) return token.create(utf.byte(chr), 12) end +tokens.vbox = createtoken("vbox") +tokens.hbox = createtoken("hbox") +tokens.vtop = createtoken("vtop") +tokens.bgroup = createtoken(utfbyte("{"), 1) +tokens.egroup = createtoken(utfbyte("}"), 2) + +tokens.letter = function(chr) return createtoken(utfbyte(chr), 11) end +tokens.other = function(chr) return createtoken(utfbyte(chr), 12) end tokens.letters = function(str) local t = { } for chr in string.utfvalues(str) do - t[#t+1] = token.create(chr, 11) + t[#t+1] = createtoken(chr, 11) end return t end -collectors = collectors or { } -collectors.data = collectors.data or { } +tokens.collectors = tokens.collectors or { } +local collectors = tokens.collectors + +collectors.data = collectors.data or { } +local collectordata = collectors.data -function tex.printlist(data) +collectors.registered = collectors.registered or { } +local registered = collectors.registered + +local function printlist(data) callbacks.push('token_filter', function () callbacks.pop('token_filter') -- tricky but the nil assignment helps return data end) end +tex.printlist = printlist + function collectors.flush(tag) - tex.printlist(collectors.data[tag]) + printlist(collectordata[tag]) end function collectors.test(tag) - tex.printlist(collectors.data[tag]) + printlist(collectordata[tag]) end -collectors.registered = { } - function collectors.register(name) - collectors.registered[token.csname_id(name)] = name + registered[csname_id(name)] = name end ---~ function collectors.install(tag,end_cs) ---~ collectors.data[tag] = { } ---~ local data = collectors.data[tag] ---~ local call = token.command_id("call") ---~ local relax = token.command_id("relax") ---~ local endcs = token.csname_id(end_cs) ---~ local expand = collectors.registered ---~ local get = token.get_next -- so no callback! ---~ while true do ---~ local t = get() ---~ local a, b = t[1], t[3] ---~ if a == relax and b == endcs then ---~ return ---~ elseif a == call and expand[b] then ---~ token.expand() ---~ else ---~ data[#data+1] = t ---~ end ---~ end ---~ end +local call = command_id("call") +local letter = command_id("letter") +local other = command_id("other_char") function collectors.install(tag,end_cs) - collectors.data[tag] = { } - local data = collectors.data[tag] - local call = token.command_id("call") - local endcs = token.csname_id(end_cs) - local expand = collectors.registered - local get = token.get_next + local data = { } + collectordata[tag] = data + local endcs = csname_id(end_cs) while true do - local t = get() + local t = get_next() local a, b = t[1], t[3] if b == endcs then - tex.print('\\' ..end_cs) + texsprint('\\' ..end_cs) return - elseif a == call and expand[b] then - token.expand() + elseif a == call and registered[b] then + expand() else data[#data+1] = t end @@ -118,30 +118,26 @@ function collectors.install(tag,end_cs) end function collectors.handle(tag,handle,flush) - collectors.data[tag] = handle(collectors.data[tag]) + collectordata[tag] = handle(collectordata[tag]) if flush then collectors.flush(tag) end end -collectors.show_methods = { } +local show_methods = { } +collectors.show_methods = show_methods function collectors.show(tag, method) if type(tag) == "table" then - collectors.show_methods[method or 'a'](tag) + show_methods[method or 'a'](tag) else - collectors.show_methods[method or 'a'](collectors.data[tag]) + show_methods[method or 'a'](collectordata[tag]) end end -commands = commands or { } - -commands.letter = token.command_id("letter") -commands.other = token.command_id("other_char") - function collectors.default_words(t,str) t[#t+1] = tokens.bgroup - t[#t+1] = token.create("red") + t[#t+1] = createtoken("red") for i=1,#str do t[#t+1] = tokens.other('*') end @@ -151,10 +147,10 @@ end function collectors.with_words(tag,handle) local t, w = { }, { } handle = handle or collectors.default_words - local tagdata = collectors.data[tag] + local tagdata = collectordata[tag] for k=1,#tagdata do local v = tagdata[k] - if v[1] == commands.letter then + if v[1] == letter then w[#w+1] = v[2] else if #w > 0 then @@ -167,16 +163,16 @@ function collectors.with_words(tag,handle) if #w > 0 then handle(t,w) end - collectors.data[tag] = t + collectordata[tag] = t end function collectors.show_token(t) if t then - local cmd, chr, id, cs, name = t[1], t[2], t[3], nil, token.command_name(t) or "" - if cmd == commands.letter or cmd == commands.other then - return format("%s-> %s -> %s", name, chr, utf.char(chr)) + local cmd, chr, id, cs, name = t[1], t[2], t[3], nil, command_name(t) or "" + if cmd == letter or cmd == other then + return format("%s-> %s -> %s", name, chr, utfchar(chr)) elseif id > 0 then - cs = token.csname_name(t) or nil + cs = csname_name(t) or nil if cs then return format("%s-> %s", name, cs) elseif tonumber(chr) < 0 then @@ -193,98 +189,110 @@ function collectors.show_token(t) end function collectors.trace() - local t = token.get_next() + local t = get_next() texio.write_nl(collectors.show_token(t)) return t end -collectors.show_methods.a = function(data) -- no need to store the table, just pass directly - local template = "\\NC %s\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR " - texsprint(ctxcatcodes, "\\starttabulate[|T|Tr|cT|Tr|T|]") - texsprint(ctxcatcodes, format(template,"cmd","chr","","id","name")) - texsprint(ctxcatcodes, "\\HL") +-- these might move to a runtime module + +show_methods.a = function(data) -- no need to store the table, just pass directly + local function row(one,two,three,four,five) + context.NC() context(one) + context.NC() context(two) + context.NC() context(three) + context.NC() context(four) + context.NC() context(five) + context.NC() context.NR() + end + context.starttabulate { "|T|Tr|cT|Tr|T|" } + row("cmd","chr","","id","name") + context.HL() for _,v in next, data do local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", "" - local name = gsub(token.command_name(v) or "","_","\\_") + local name = gsub(command_name(v) or "","_","\\_") if id > 0 then - cs = token.csname_name(v) or "" + cs = csname_name(v) or "" if cs ~= "" then cs = "\\string " .. cs end else id = "" end - if cmd == commands.letter or cmd == commands.other then + if cmd == letter or cmd == other then sym = "\\char " .. chr end if tonumber(chr) < 0 then - texsprint(ctxcatcodes, format(template, name, "", sym, id, cs)) + row(name,"",sym,id,cs) else - texsprint(ctxcatcodes, format(template, name, chr, sym, id, cs)) + row(name,chr,sym,id,cs) end end - texsprint(ctxcatcodes, "\\stoptabulate") + context.stoptabulate() end -collectors.show_methods.b_c = function(data,swap) -- no need to store the table, just pass directly - local template = "\\NC %s\\NC %s\\NC %s\\NC\\NR" +local function show_b_c(data,swap) -- no need to store the table, just pass directly + local function row(one,two,three) + context.NC() context(one) + context.NC() context(two) + context.NC() context(three) + context.NC() context.NR() + end if swap then - texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tl|Tr|]") + context.starttabulate { "|Tl|Tl|Tr|" } else - texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tr|Tl|]") + context.starttabulate { "|Tl|Tr|Tl|" } end - texsprint(ctxcatcodes, format(template,"cmd","chr","name")) - texsprint(ctxcatcodes, "\\HL") + row("cmd","chr","name") + context.HL() for _,v in next, data do local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", "" - local name = gsub(token.command_name(v) or "","_","\\_") + local name = gsub(command_name(v) or "","_","\\_") if id > 0 then - cs = token.csname_name(v) or "" + cs = csname_name(v) or "" end - if cmd == commands.letter or cmd == commands.other then + if cmd == letter or cmd == other then sym = "\\char " .. chr - elseif cs ~= "" then - if token.is_activechar(v) then - sym = "\\string " .. cs - else - sym = "\\string\\" .. cs - end + elseif cs == "" then + -- okay + elseif is_activechar(v) then + sym = "\\string " .. cs + else + sym = "\\string\\" .. cs end if swap then - texsprint(ctxcatcodes, format(template, name, sym, chr)) + row(name,sym,chr) elseif tonumber(chr) < 0 then - texsprint(ctxcatcodes, format(template, name, "", sym)) + row(name,"",sym) else - texsprint(ctxcatcodes, format(template, name, chr, sym)) + row(name,chr,sym) end end - texsprint(ctxcatcodes, "\\stoptabulate") + context.stoptabulate() end -- Even more experimental ... -collectors.show_methods.b = function(tag) collectors.show_methods.b_c(tag,false) end -collectors.show_methods.c = function(tag) collectors.show_methods.b_c(tag,true ) end +show_methods.b = function(data) show_b_c(data,false) end +show_methods.c = function(data) show_b_c(data,true ) end -collectors.remapper = { - -- namespace -} +local remapper = { } -- namespace +collectors.remapper = remapper -collectors.remapper.data = { - -- user mappings -} +local remapperdata = { } -- user mappings +remapper.data = remapperdata -function collectors.remapper.store(tag,class,key) - local s = collectors.remapper.data[class] +function remapper.store(tag,class,key) + local s = remapperdata[class] if not s then s = { } - collectors.remapper.data[class] = s + remapperdata[class] = s end - s[key] = collectors.data[tag] - collectors.data[tag] = nil + s[key] = collectordata[tag] + collectordata[tag] = nil end -function collectors.remapper.convert(tag,toks) - local data = collectors.remapper.data[tag] - local leftbracket, rightbracket = utf.byte('['), utf.byte(']') +function remapper.convert(tag,toks) + local data = remapperdata[tag] + local leftbracket, rightbracket = utfbyte('['), utfbyte(']') local skipping = 0 -- todo: math if data then diff --git a/tex/context/base/toks-ini.mkiv b/tex/context/base/toks-ini.mkiv index 22deca745..2aa2ed4a6 100644 --- a/tex/context/base/toks-ini.mkiv +++ b/tex/context/base/toks-ini.mkiv @@ -19,12 +19,12 @@ %D Handy for manuals \unknown -\unexpanded\def\starttokens [#1]{\ctxlua{collectors.install("#1", "stoptokens")}} +\unexpanded\def\starttokens [#1]{\ctxlua{tokens.collectors.install("#1","stoptokens")}} \let\stoptokens \relax -\def\flushtokens [#1]{\ctxlua{collectors.flush("#1")}} -\def\showtokens [#1]{\ctxlua{collectors.show("#1")}} -\def\testtokens [#1]{\ctxlua{collectors.with_words("#1")}} -\def\registertoken #1{\ctxlua{collectors.register("#1")}} +\def\flushtokens [#1]{\ctxlua{tokens.collectors.flush("#1")}} +\def\showtokens [#1]{\ctxlua{tokens.collectors.show("#1")}} +\def\testtokens [#1]{\ctxlua{tokens.collectors.with_words("#1")}} +\def\registertoken #1{\ctxlua{tokens.collectors.register("#1")}} %D Inspired by a prototype by Taco for Thomas cum suis. @@ -54,13 +54,13 @@ % {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}} \def\dostartremapper#1% - {\ctxlua{collectors.install("#1", "\e!stop#1")}} + {\ctxlua{tokens.collectors.install("#1", "\e!stop#1")}} \def\dostopremapper#1% - {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end, true)}} + {\ctxlua{tokens.collectors.handle("#1",function(str) return tokens.collectors.remapper.convert("#1",str) end, true)}} \def\remaptokens#1% - {\ctxlua{collectors.handle("#1",function(str) return collectors.remapper.convert("#1",str) end)}} + {\ctxlua{tokens.collectors.handle("#1",function(str) return tokens.collectors.remapper.convert("#1",str) end)}} \unexpanded\def\defineremapper[#1]% {\setvalue{\e!start#1}{\dostartremapper{#1}}% @@ -72,7 +72,7 @@ {\dodoubleempty\doremapcharacter} \def\doremapcharacter[#1][#2]#3% - {\ctxlua{collectors.install("store", "ctxlua")}#3% - \ctxlua{collectors.remapper.store("store","#1",\number#2)}} + {\ctxlua{tokens.collectors.install("store", "ctxlua")}#3% + \ctxlua{tokens.collectors.remapper.store("store","#1",\number#2)}} \protect \endinput diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 51b98c7f3..b631450f8 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -6,32 +6,39 @@ if not modules then modules = { } end modules ['trac-deb'] = { license = "see context related readme files" } +local lpeg = lpeg local lpegmatch = lpeg.match local format, concat = string.format, table.concat local tonumber, tostring = tonumber, tostring local texdimen, textoks, texcount = tex.dimen, tex.toks, tex.count -local tracers = namespaces.private("tracers") +-- maybe tracers -> tracers.tex (and tracers.lua for current debugger) local report_system = logs.new("system") +tracers = tracers or { } +local tracers = tracers + tracers.lists = { } +local lists = tracers.lists + tracers.strings = { } +local strings = tracers.strings -tracers.strings.undefined = "undefined" +strings.undefined = "undefined" -tracers.lists.scratch = { +lists.scratch = { 0, 2, 4, 6, 8 } -tracers.lists.internals = { +lists.internals = { 'p:hsize', 'p:parindent', 'p:leftskip','p:rightskip', 'p:vsize', 'p:parskip', 'p:baselineskip', 'p:lineskip', 'p:topskip' } -tracers.lists.context = { +lists.context = { 'd:lineheight', - 'c:realpageno', 'c:pageno', 'c:subpageno' + 'c:realpageno', 'c:userpageno', 'c:pageno', 'c:subpageno' } local types = { @@ -64,24 +71,24 @@ end function tracers.dimen(name) local d = texdimen[name] - return d and number.topoints(d) or tracers.strings.undefined + return d and number.topoints(d) or strings.undefined end function tracers.count(name) - return texcount[name] or tracers.strings.undefined + return texcount[name] or strings.undefined end function tracers.toks(name,limit) local t = textoks[name] - return t and string.limit(t,tonumber(limit) or 40) or tracers.strings.undefined + return t and string.limit(t,tonumber(limit) or 40) or strings.undefined end function tracers.primitive(name) - return tex[name] or tracers.strings.undefined + return tex[name] or strings.undefined end function tracers.knownlist(name) - local l = tracers.lists[name] + local l = lists[name] return l and #l > 0 end @@ -122,23 +129,6 @@ function tracers.printerror(offset) end end -if tex.error then - - function tracers.texerrormessage(...) -- for the moment we put this function here - tex.error(format(...), { }) - end - -else - - function tracers.texerrormessage(...) -- for the moment we put this function here - local v = format(...) - tex.sprint(tex.ctxcatcodes,"\\errmessage{") - tex.sprint(tex.vrbcatcodes,v) - tex.print(tex.ctxcatcodes,"}") - end - -end - directives.register("system.errorcontext", function(v) if v then callback.register('show_error_hook', function() tracers.printerror(v) end) @@ -149,7 +139,7 @@ end) -- this might move -local lmx = namespaces.private("lmx") +lmx = lmx or { } if not lmx.variables then lmx.variables = { } end @@ -199,3 +189,16 @@ function lmx.overloaderror() end directives.register("system.showerror", lmx.overloaderror) + +local debugger = utilities.debugger + +local function trace_calls(n) + debugger.enable() + luatex.register_stop_actions(function() + debugger.disable() + debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) + end) + trace_calls = function() end +end + +directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua index 4e9280d50..ad50af4c8 100644 --- a/tex/context/base/trac-inf.lua +++ b/tex/context/base/trac-inf.lua @@ -14,14 +14,13 @@ if not modules then modules = { } end modules ['trac-inf'] = { local format = string.format local clock = os.gettimeofday or os.clock -- should go in environment -local statusinfo, n, registered = { }, 0, { } - -statistics = statistics or { } +statistics = statistics or { } +local statistics = statistics statistics.enable = true statistics.threshold = 0.05 -local timers = { } +local statusinfo, n, registered, timers = { }, 0, { }, { } local function hastiming(instance) return instance and timers[instance] diff --git a/tex/context/base/trac-lmx.lua b/tex/context/base/trac-lmx.lua index 74e711ea4..47bca3b1e 100644 --- a/tex/context/base/trac-lmx.lua +++ b/tex/context/base/trac-lmx.lua @@ -10,9 +10,11 @@ if not modules then modules = { } end modules ['trac-lmx'] = { local gsub, format, concat, byte = string.gsub, string.format, table.concat, string.byte -local lmx = namespaces.private("lmx") +lmx = lmx or { } +local lmx = lmx -lmx.variables = lmx.variables or { } -- global, shared +lmx.variables = lmx.variables or { } -- global, shared +local lmxvariables = lmx.variables local escapes = { ['&'] = '&', @@ -23,8 +25,6 @@ local escapes = { -- variables -local lmxvariables = lmx.variables - lmxvariables['title-default'] = 'ConTeXt LMX File' lmxvariables['title'] = lmx.variables['title-default'] lmxvariables['color-background-green'] = '#4F6F6F' diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index ae1130e65..3b75b390a 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -24,7 +24,8 @@ provide an <l n='xml'/> structured file. Actually, any logging that is hooked into callbacks will be \XML\ by default.</p> --ldx]]-- -logs = logs or { } +logs = logs or { } +local logs = logs --[[ldx-- <p>This looks pretty ugly but we need to speed things up a bit.</p> @@ -268,8 +269,8 @@ function noplog.simple(fmt,...) -- todo: fmt,s end end -if utils then - utils.report = function(...) logs.simple(...) end +if utilities then + utilities.report = function(...) logs.simple(...) end end function logs.setprogram(newname,newbanner) @@ -365,3 +366,47 @@ end --~ function logs.tex.stop_page_number() --~ write("]") --~ end + +function logs.obsolete(old,new) + local o = loadstring("return " .. new)() + if type(o) == "function" then + return function(...) + logs.report("system","function %s is obsolete, use %s",old,new) + loadstring(old .. "=" .. new .. " return ".. old)()(...) + end + elseif type(o) == "table" then + local t, m = { }, { } + m.__index = function(t,k) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + return o[k] + end + m.__newindex = function(t,k,v) + logs.report("system","table %s is obsolete, use %s",old,new) + m.__index, m.__newindex = o, o + o[k] = v + end + if libraries then + libraries.obsolete[old] = t -- true + end + setmetatable(t,m) + return t + end +end + +if tex.error then + + function logs.texerrormessage(...) -- for the moment we put this function here + tex.error(format(...), { }) + end + +else + + function logs.texerrormessage(...) -- for the moment we put this function here + local v = format(...) + tex.sprint(tex.ctxcatcodes,"\\errmessage{") + tex.sprint(tex.vrbcatcodes,v) + tex.print(tex.ctxcatcodes,"}") + end + +end diff --git a/tex/context/base/trac-pro.lua b/tex/context/base/trac-pro.lua index bfcd71138..b06d63cfe 100644 --- a/tex/context/base/trac-pro.lua +++ b/tex/context/base/trac-pro.lua @@ -19,7 +19,8 @@ local trace_namespaces = false trackers.register("system.namespaces", function( local report_system = logs.new("system") -namespaces = { } +namespaces = namespaces or { } +local namespaces = namespaces local registered = { } diff --git a/tex/context/base/trac-set.lua b/tex/context/base/trac-set.lua index e7498ea85..54ef22ee5 100644 --- a/tex/context/base/trac-set.lua +++ b/tex/context/base/trac-set.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['trac-set'] = { +if not modules then modules = { } end modules ['trac-set'] = { -- might become util-set.lua version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -10,8 +10,12 @@ local type, next, tostring = type, next, tostring local concat = table.concat local format, find, lower, gsub, simpleesc = string.format, string.find, string.lower, string.gsub, string.simpleesc local is_boolean = string.is_boolean +local settings_to_hash = utilities.parsers.settings_to_hash -setters = { } +utilities = utilities or { } +local utilities = utilities +utilities.setters = utilities.setters or { } +local setters = utilities.setters local data = { } -- maybe just local @@ -67,7 +71,7 @@ end local function set(t,what,newvalue) local data, done = t.data, t.done if type(what) == "string" then - what = aux.settings_to_hash(what) -- inefficient but ok + what = settings_to_hash(what) -- inefficient but ok end for w, value in next, what do if value == "" then @@ -194,18 +198,20 @@ end -- we could have used a bit of oo and the trackers:enable syntax but -- there is already a lot of code around using the singular tracker --- we could make this into a module +-- we could make this into a module but we also want the rest avaliable + +local enable, disable, register, list, show = setters.enable, setters.disable, setters.register, setters.list, setters.show function setters.new(name) - local t + local t -- we need to access it in t t = { data = { }, -- indexed, but also default and value fields name = name, - enable = function(...) setters.enable (t,...) end, - disable = function(...) setters.disable (t,...) end, - register = function(...) setters.register(t,...) end, - list = function(...) setters.list (t,...) end, - show = function(...) setters.show (t,...) end, + enable = function(...) enable (t,...) end, + disable = function(...) disable (t,...) end, + register = function(...) register(t,...) end, + list = function(...) list (t,...) end, + show = function(...) show (t,...) end, } data[name] = t return t @@ -215,13 +221,18 @@ trackers = setters.new("trackers") directives = setters.new("directives") experiments = setters.new("experiments") +local t_enable, t_disable = trackers .enable, trackers .disable +local d_enable, d_disable = directives .enable, directives .disable +local e_enable, e_disable = experiments.enable, experiments.disable + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end + if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) + d_enable(environment.engineflags.directives) end -- nice trick: we overload two of the directives related functions with variants that @@ -235,30 +246,24 @@ end local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) -local enable = directives.enable -local disable = directives.disable - function directives.enable(...) report("directives","enabling: %s",concat({...}," ")) - enable(...) + d_enable(...) end function directives.disable(...) report("directives","disabling: %s",concat({...}," ")) - disable(...) + d_disable(...) end -local enable = experiments.enable -local disable = experiments.disable - function experiments.enable(...) report("experiments","enabling: %s",concat({...}," ")) - enable(...) + e_enable(...) end function experiments.disable(...) report("experiments","disabling: %s",concat({...}," ")) - disable(...) + e_disable(...) end -- a useful example @@ -267,11 +272,15 @@ directives.register("system.nostatistics", function(v) statistics.enable = not v end) +directives.register("system.nolibraries", function(v) + libraries = nil -- we discard this tracing for security +end) + -- experiment if trackers and environment and environment.engineflags.trackers then - trackers.enable(environment.engineflags.trackers) + t_enable(environment.engineflags.trackers) end if directives and environment and environment.engineflags.directives then - directives.enable(environment.engineflags.directives) + d_enable(environment.engineflags.directives) end diff --git a/tex/context/base/trac-tex.lua b/tex/context/base/trac-tex.lua index 914769c7f..8435efafd 100644 --- a/tex/context/base/trac-tex.lua +++ b/tex/context/base/trac-tex.lua @@ -8,14 +8,18 @@ if not modules then modules = { } end modules ['trac-hsh'] = { -- moved from trac-deb.lua +local texhashtokens = tex.hashtokens + +local trackers = trackers + local saved = { } function trackers.save_hash() - saved = tex.hashtokens() + saved = texhashtokens() end function trackers.dump_hash(filename,delta) - local list, hash, command_name = { }, tex.hashtokens(), token.command_name + local list, hash, command_name = { }, texhashtokens(), token.command_name for name, token in next, hash do if not delta or not saved[name] then -- token: cmd, chr, csid -- combination cmd,chr determines name @@ -37,8 +41,8 @@ local delta = nil local function dump_hash(wanteddelta) if delta == nil then - saved = saved or tex.hashtokens() - luatex.register_stop_actions(1,function() trackers.dump_hash(nil,wanteddelta) end) -- at front + saved = saved or texhashtokens() -- no need for trackers.dump_hash + luatex.register_stop_actions(1,function() dump_hash(nil,wanteddelta) end) -- at front end delta = wanteddelta end diff --git a/tex/context/base/trac-tim.lua b/tex/context/base/trac-tim.lua index 18d023982..2917a5686 100644 --- a/tex/context/base/trac-tim.lua +++ b/tex/context/base/trac-tim.lua @@ -11,10 +11,7 @@ local concat, sort = table.concat, table.sort local next, tonumber = next, tonumber moduledata.progress = moduledata.progress or { } - -local progress = moduledata.progress - -progress = progress or { } +local progress = moduledata.progress progress.defaultfilename = ((tex and tex.jobname) or "whatever") .. "-luatex-progress" @@ -47,7 +44,7 @@ function progress.store() local c = os.clock() local t = { elapsed_time = c - last, - node_memory = nodes.usage(), + node_memory = nodes.pool.usage(), } for k, v in next, params do if status[v] then t[v] = status[v] end diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv index 24b9f4f6e..8e914f721 100644 --- a/tex/context/base/type-otf.mkiv +++ b/tex/context/base/type-otf.mkiv @@ -1892,20 +1892,20 @@ \stoptypescriptcollection -% \starttypescriptcollection[hvmath] +\starttypescriptcollection[hvmath] -% \starttypescript [math] [hvmath] -% \definefontsynonym[MathRoman][hvmath@hvmath-math] -% \loadfontgoodies[hvmath-math] -% \stoptypescript + \starttypescript [math] [hvmath] + \definefontsynonym[MathRoman][hvmath@hvmath-math] + \loadfontgoodies[hvmath-math] + \stoptypescript -% \starttypescript [hvmath] -% \definetypeface [hvmath] [ss] [sans] [heros] [default] [rscale=0.9] -% \definetypeface [hvmath] [rm] [serif] [termes] [default] -% \definetypeface [hvmath] [tt] [mono] [cursor] [default] [rscale=1.05] -% \definetypeface [hvmath] [mm] [math] [hvmath] [default] -% \stoptypescript + \starttypescript [hvmath] + \definetypeface [hvmath] [ss] [sans] [heros] [default] [rscale=0.9] + \definetypeface [hvmath] [rm] [serif] [termes] [default] + \definetypeface [hvmath] [tt] [mono] [cursor] [default] [rscale=1.05] + \definetypeface [hvmath] [mm] [math] [hvmath] [default] + \stoptypescript -% \stoptypescriptcollection +\stoptypescriptcollection \protect \endinput diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua index a845599f5..7a193a6af 100644 --- a/tex/context/base/typo-brk.lua +++ b/tex/context/base/typo-brk.lua @@ -13,11 +13,13 @@ local next, type, tonumber = next, type, tonumber local utfbyte, utfchar = utf.byte, utf.char local format = string.format -local trace_breakpoints = false trackers.register("typesetting.breakpoints", function(v) trace_breakpoints = v end) +local trace_breakpoints = false trackers.register("typesetters.breakpoints", function(v) trace_breakpoints = v end) local report_breakpoints = logs.new("breakpoints") -local settings_to_array = aux.settings_to_array +local nodes, node = nodes, node + +local settings_to_array = utilities.parsers.settings_to_array local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute local set_attribute = node.set_attribute @@ -26,32 +28,41 @@ local copy_nodelist = node.copy_list local free_node = node.free local insert_node_before = node.insert_before local insert_node_after = node.insert_after -local make_penalty_node = nodes.penalty -local make_glue_node = nodes.glue -local make_disc_node = nodes.disc -local make_glyph_node = nodes.glyph local remove_node = nodes.remove -- ! nodes local tonodes = blobs.tonodes -local nodecodes = nodes.nodecodes +local texattribute = tex.attribute + +local nodepool = nodes.pool +local tasks = nodes.tasks + +local new_penalty = nodepool.penalty +local new_glue = nodepool.glue +local new_disc = nodepool.disc -local glyph = nodecodes.glyph -local kern = nodecodes.kern +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes -typesetting = typesetting or {} -typesetting.breakpoints = typesetting.breakpoints or {} +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern -local breakpoints = typesetting.breakpoints +local kerning_code = kerncodes.kerning -breakpoints.mapping = breakpoints.mapping or { } -breakpoints.methods = breakpoints.methods or { } -breakpoints.attribute = attributes.private("breakpoint") +local typesetters = typesetters -local a_breakpoints = breakpoints.attribute +typesetters.breakpoints = typesetters.breakpoints or {} +local breakpoints = typesetters.breakpoints -storage.register("typesetting/breakpoints/mapping", breakpoints.mapping, "typesetting.breakpoints.mapping") +breakpoints.mapping = breakpoints.mapping or { } +local mapping = breakpoints.mapping -local mapping = breakpoints.mapping +breakpoints.methods = breakpoints.methods or { } +local methods = breakpoints.methods + +local a_breakpoints = attributes.private("breakpoint") +breakpoints.attribute = a_breakpoints + +storage.register("typesetters/breakpoints/mapping", breakpoints.mapping, "typesetters.breakpoints.mapping") function breakpoints.setreplacement(id,char,language,settings) char = utfbyte(char) @@ -77,24 +88,24 @@ function breakpoints.setreplacement(id,char,language,settings) end local function insert_break(head,start,before,after) - insert_node_before(head,start,make_penalty_node(before)) - insert_node_before(head,start,make_glue_node(0)) - insert_node_after(head,start,make_glue_node(0)) - insert_node_after(head,start,make_penalty_node(after)) + insert_node_before(head,start,new_penalty(before)) + insert_node_before(head,start,new_glue(0)) + insert_node_after(head,start,new_glue(0)) + insert_node_after(head,start,new_penalty(after)) end -breakpoints.methods[1] = function(head,start) +methods[1] = function(head,start) if start.prev and start.next then insert_break(head,start,10000,0) end return head, start end -breakpoints.methods[2] = function(head,start) -- ( => (- +methods[2] = function(head,start) -- ( => (- if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.replace = tmp local tmp, hyphen = copy_node(tmp), copy_node(tmp) @@ -106,11 +117,11 @@ breakpoints.methods[2] = function(head,start) -- ( => (- return head, start end -breakpoints.methods[3] = function(head,start) -- ) => -) +methods[3] = function(head,start) -- ) => -) if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.replace = tmp local tmp, hyphen = copy_node(tmp), copy_node(tmp) @@ -122,11 +133,11 @@ breakpoints.methods[3] = function(head,start) -- ) => -) return head, start end -breakpoints.methods[4] = function(head,start) -- - => - - - +methods[4] = function(head,start) -- - => - - - if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) start.attr = copy_nodelist(tmp.attr) -- todo: critical only start.pre, start.post, start.replace = copy_node(tmp), copy_node(tmp), tmp insert_break(head,start,10000,10000) @@ -134,11 +145,11 @@ breakpoints.methods[4] = function(head,start) -- - => - - - return head, start end -breakpoints.methods[5] = function(head,start,settings) -- x => p q r +methods[5] = function(head,start,settings) -- x => p q r if start.prev and start.next then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,make_disc_node()) + head, start = insert_node_before(head,start,new_disc()) local attr = tmp.attr start.attr = copy_nodelist(attr) -- todo: critical only start.pre, start.post, start.replace = tonodes(settings.right,tmp,attr), tonodes(settings.left,tmp,attr), tonodes(settings.middle,tmp,attr) @@ -148,14 +159,12 @@ breakpoints.methods[5] = function(head,start,settings) -- x => p q r return head, start end -local methods = breakpoints.methods - local function process(namespace,attribute,head) local done, numbers = false, languages.numbers local start, n = head, 0 while start do local id = start.id - if id == glyph then + if id == glyph_code then local attr = has_attribute(start,attribute) if attr and attr > 0 then unset_attribute(start,attribute) -- maybe test for subtype > 256 (faster) @@ -173,7 +182,7 @@ local function process(namespace,attribute,head) local next = start.next while next do -- gamble on same attribute (not that important actually) local id = next.id - if id == glyph then -- gamble on same attribute (not that important actually) + if id == glyph_code then -- gamble on same attribute (not that important actually) if map[next.char] then break elseif m == 1 then @@ -187,7 +196,7 @@ local function process(namespace,attribute,head) m = m - 1 next = next.next end - elseif id == kern and next.subtype == 0 then + elseif id == kern_code and next.subtype == kerning_code then next = next.next -- ignore intercharacter kerning, will go way else @@ -209,7 +218,7 @@ local function process(namespace,attribute,head) else -- n = n + 1 -- if we want single char handling (|-|) then we will use grouping and then we need this end - elseif id == kern and start.subtype == 0 then + elseif id == kern_code and start.subtype == kerning_code then -- ignore intercharacter kerning, will go way else n = 0 @@ -223,9 +232,9 @@ function breakpoints.set(n) if trace_breakpoints then report_breakpoints("enabling breakpoints handler") end - tasks.enableaction("processors","typesetting.breakpoints.handler") + tasks.enableaction("processors","typesetters.breakpoints.handler") function breakpoints.set(n) - tex.attribute[a_breakpoints] = n + texattribute[a_breakpoints] = n end breakpoints.set(n) end @@ -237,5 +246,5 @@ breakpoints.handler = nodes.install_attribute_handler { } function breakpoints.enable() - tasks.enableaction("processors","typesetting.breakpoints.handler") + tasks.enableaction("processors","typesetters.breakpoints.handler") end diff --git a/tex/context/base/typo-brk.mkiv b/tex/context/base/typo-brk.mkiv index 931345153..bfb79a126 100644 --- a/tex/context/base/typo-brk.mkiv +++ b/tex/context/base/typo-brk.mkiv @@ -49,7 +49,7 @@ {\ifcsname\??bp:#1\endcsname \begingroup \getparameters[\??bp][\c!type=1,\c!nleft=3,\c!nright=3,\s!language=,\c!left=,\c!right=,\c!middle=,#3]% - \ctxlua{typesetting.breakpoints.setreplacement(\csname\??bp:#1\endcsname, "#2", "\reallanguagetag\@@bplanguage", { + \ctxlua{typesetters.breakpoints.setreplacement(\csname\??bp:#1\endcsname, "#2", "\reallanguagetag\@@bplanguage", { kind = \@@bptype, nleft = "\@@bpnleft", nright = "\@@bpnright", @@ -61,7 +61,7 @@ \fi} \unexpanded\def\setbreakpoints[#1]% - {\ctxlua{typesetting.breakpoints.set(\number\csname\??bp:#1\endcsname)}} + {\ctxlua{typesetters.breakpoints.set(\number\csname\??bp:#1\endcsname)}} \letvalue{\??bp:\s!reset}\attributeunsetvalue diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua index 3de2c5ab1..bcb4fbd6e 100644 --- a/tex/context/base/typo-cap.lua +++ b/tex/context/base/typo-cap.lua @@ -10,38 +10,47 @@ local next, type = next, type local format, insert = string.format, table.insert local div = math.div -local trace_casing = false trackers.register("typesetting.casing", function(v) trace_casing = v end) +local trace_casing = false trackers.register("typesetters.casing", function(v) trace_casing = v end) local report_casing = logs.new("casing") +local nodes, node = nodes, node + local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute local set_attribute = node.set_attribute local traverse_id = node.traverse_id -local texattribute = tex.attribute +local texattribute = tex.attribute + +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes +local kerncodes = nodes.kerncodes -local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern -local glyph = nodecodes.glyph -local kern = nodecodes.kern +local kerning_code = kerncodes.kerning +local userskip_code = skipcodes.userskip -local fontdata = fonts.ids -local fontchar = fonts.chr -local chardata = characters.data +local tasks = nodes.tasks -typesetting = typesetting or { } -typesetting.cases = typesetting.cases or { } +local fontdata = fonts.ids +local fontchar = fonts.chr +local chardata = characters.data -local cases = typesetting.cases +typesetters = typesetters or { } +local typesetters = typesetters -cases.actions = { } -cases.attribute = attributes.private("case") -- no longer needed +typesetters.cases = typesetters.cases or { } +local cases = typesetters.cases -local a_cases = cases.attribute +cases.actions = { } +local actions = cases.actions +cases.attribute = c_cases -- no longer needed +local a_cases = attributes.private("case") -local actions = cases.actions -local lastfont = nil +local lastfont = nil -- we use char(0) as placeholder for the larger font, so we need to remove it -- before it can do further harm @@ -68,7 +77,7 @@ local function helper(start, code, codes, special, attribute, once) next.prev = prev end return prev, true - elseif lastfont and start.prev.id ~= glyph then + elseif lastfont and start.prev.id ~= glyph_code then fnt = lastfont start.font = lastfont end @@ -130,12 +139,12 @@ end actions[3] = function(start,attribute,attr) lastfont = nil local prev = start.prev - if prev and prev.id == kern and prev.subtype == 0 then + if prev and prev.id == kern_code and prev.subtype == kerning_code then prev = prev.prev end - if not prev or prev.id ~= glyph then + if not prev or prev.id ~= glyph_code then --- only the first character is treated - for n in traverse_id(glyph,start.next) do + for n in traverse_id(glyph_code,start.next) do if has_attribute(n,attribute) == attr then unset_attribute(n,attribute) else @@ -153,10 +162,10 @@ end actions[4] = function(start,attribute) lastfont = nil local prev = start.prev - if prev and prev.id == kern and prev.subtype == 0 then + if prev and prev.id == kern_code and prev.subtype == kerning_code then prev = prev.prev end - if not prev or prev.id ~= glyph then + if not prev or prev.id ~= glyph_code then return helper(start,'uccode','uccodes') else return start, false @@ -212,7 +221,7 @@ local function process(namespace,attribute,head) -- not real fast but also not u local start = head while start do -- while because start can jump ahead local id = start.id - if id == glyph then + if id == glyph_code then local attr = has_attribute(start,attribute) if attr and attr > 0 then if attr ~= lastattr then @@ -244,7 +253,7 @@ local m, enabled = 0, false -- a trick to make neighbouring ranges work function cases.set(n) if not enabled then - tasks.enableaction("processors","typesetting.cases.handler") + tasks.enableaction("processors","typesetters.cases.handler") if trace_casing then report_casing("enabling case handler") end diff --git a/tex/context/base/typo-cap.mkiv b/tex/context/base/typo-cap.mkiv index aa6683ca1..a7f59f10f 100644 --- a/tex/context/base/typo-cap.mkiv +++ b/tex/context/base/typo-cap.mkiv @@ -52,7 +52,7 @@ % test \Word{test TEST \TeX} test \unexpanded\def\setcharactercasing[#1]% - {\ctxlua{typesetting.cases.set(\number#1)}} + {\ctxlua{typesetters.cases.set(\number#1)}} % todo: names casings diff --git a/tex/context/base/typo-dig.lua b/tex/context/base/typo-dig.lua index 687090074..4e94f7185 100644 --- a/tex/context/base/typo-dig.lua +++ b/tex/context/base/typo-dig.lua @@ -13,43 +13,46 @@ local next, type = next, type local format, insert = string.format, table.insert local round, div = math.round, math.div -local trace_digits = false trackers.register("typesetting.digits", function(v) trace_digits = v end) +local trace_digits = false trackers.register("typesetters.digits", function(v) trace_digits = v end) local report_digits = logs.new("digits") -local has_attribute = node.has_attribute -local unset_attribute = node.unset_attribute -local set_attribute = node.set_attribute -local hpack_node = node.hpack -local traverse_id = node.traverse_id -local insert_before = node.insert_before -local insert_after = node.insert_after +local nodes, node = nodes, node -local texattribute = tex.attribute +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local set_attribute = node.set_attribute +local hpack_node = node.hpack +local traverse_id = node.traverse_id +local insert_before = node.insert_before +local insert_after = node.insert_after -local nodecodes = nodes.nodecodes +local texattribute = tex.attribute -local glyph = nodecodes.glyph -local kern = nodecodes.kern +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph -local new_glue = nodes.glue +local nodepool = nodes.pool +local tasks = nodes.tasks -local fontdata = fonts.identifiers -local chardata = fonts.characters -local quaddata = fonts.quads -local charbase = characters.data +local new_glue = nodepool.glue -typesetting = typesetting or { } -typesetting.digits = typesetting.digits or { } +local fontdata = fonts.identifiers +local chardata = fonts.characters +local quaddata = fonts.quads +local charbase = characters.data -local digits = typesetting.digits +typesetters = typesetters or { } +local typesetters = typesetters -digits.actions = { } -digits.attribute = attributes.private("digits") +typesetters.digits = typesetters.digits or { } +local digits = typesetters.digits -local a_digits = digits.attribute +digits.actions = { } +local actions = digits.actions -local actions = digits.actions +local a_digits = attributes.private("digits") +digits.attribute = a_digits -- at some point we can manipulate the glyph node so then i need -- to rewrite this then @@ -99,7 +102,7 @@ end local function process(namespace,attribute,head) local done, current, ok = false, head, false while current do - if current.id == glyph then + if current.id == glyph_code then local attr = has_attribute(current,attribute) if attr and attr > 0 then unset_attribute(current,attribute) @@ -121,7 +124,7 @@ local m, enabled = 0, false -- a trick to make neighbouring ranges work function digits.set(n) if not enabled then - tasks.enableaction("processors","typesetting.digits.handler") + tasks.enableaction("processors","typesetters.digits.handler") if trace_digits then report_digits("enabling digit handler") end diff --git a/tex/context/base/typo-dig.mkiv b/tex/context/base/typo-dig.mkiv index 2739ec5d4..365afebce 100644 --- a/tex/context/base/typo-dig.mkiv +++ b/tex/context/base/typo-dig.mkiv @@ -39,7 +39,7 @@ %D \stoplines \unexpanded\def\setdigitsmanipulation[#1]% - {\ctxlua{typesetting.digits.set(\number#1)}} + {\ctxlua{typesetters.digits.set(\number#1)}} \unexpanded\def\resetdigitsmanipulation {\attribute\digitsattribute\attributeunsetvalue} diff --git a/tex/context/base/typo-mir.lua b/tex/context/base/typo-dir.lua index f0ed7fdff..7fae75975 100644 --- a/tex/context/base/typo-mir.lua +++ b/tex/context/base/typo-dir.lua @@ -1,6 +1,6 @@ -if not modules then modules = { } end modules ['typo-mir'] = { +if not modules then modules = { } end modules ['typo-dir'] = { version = 1.001, - comment = "companion to typo-mir.mkiv", + comment = "companion to typo-dir.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -14,9 +14,11 @@ local utfchar = utf.char -- vertical space handler -local trace_mirroring = false trackers.register("nodes.mirroring", function(v) trace_mirroring = v end) +local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end) -local report_bidi = logs.new("bidi") +local report_directions = logs.new("directions") + +local nodes, node = nodes, node local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute @@ -26,15 +28,33 @@ local insert_node_before = node.insert_before local insert_node_after = node.insert_after local remove_node = nodes.remove -local nodecodes = nodes.nodecodes +local texattribute = tex.attribute +local unsetvalue = attributes.unsetvalue + +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local mathcodes = nodes.mathcodes + +local tasks = nodes.tasks + +local glyph_code = nodecodes.glyph +local whatsit_code = nodecodes.whatsit +local math_code = nodecodes.math + +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir + +local nodepool = nodes.pool + +local new_textdir = nodepool.textdir -local glyph = nodecodes.glyph -local whatsit = nodecodes.whatsit -local mthnode = nodecodes.math +local beginmath_code = mathcodes.beginmath +local endmath_code = mathcodes.endmath -local fontdata = fonts.ids -local fontchar = fonts.chr -local chardata = characters.data +local fontdata = fonts.ids +local fontchar = fonts.chr +local chardata = characters.data +local chardirs = characters.directions -- maybe make a special mirror table --~ Analysis by Idris: --~ @@ -61,31 +81,29 @@ local chardata = characters.data -- elseif d == "ws" then -- Whitespace -- elseif d == "on" then -- Other Neutrals -mirroring = mirroring or { } -mirroring.strip = false -mirroring.attribute = attributes.private("mirroring") +typesetters.directions = typesetters.directions or { } +local directions = typesetters.directions -local a_state = attributes.private('state') -local a_mirroring = attributes.private('mirroring') +local a_state = attributes.private('state') +local a_directions = attributes.private('directions') -local directions = characters.directions -- maybe make a special mirror table +local skipmath = true +local strip = false -- todo: delayed inserts here -- todo: get rid of local functions here -- beware, math adds whatsits afterwards so that will mess things up -local skipmath = true - local finish, autodir, embedded, override, done = nil, 0, 0, 0, false local list, glyphs = nil, false local finished, finidir, finipos = nil, nil, 1 local head, current, inserted = nil, nil, nil local function finish_auto_before() - head, inserted = insert_node_before(head,current,nodes.textdir("-"..finish)) + head, inserted = insert_node_before(head,current,new_textdir("-"..finish)) finished, finidir = inserted, finish - if trace_mirroring then + if trace_directions then insert(list,#list,format("auto finish inserted before: %s",finish)) finipos = #list-1 end @@ -93,9 +111,9 @@ local function finish_auto_before() end local function finish_auto_after() - head, current = insert_node_after(head,current,nodes.textdir("-"..finish)) + head, current = insert_node_after(head,current,new_textdir("-"..finish)) finished, finidir = current, finish - if trace_mirroring then + if trace_directions then list[#list+1] = format("auto finish inserted after: %s",finish) finipos = #list end @@ -113,13 +131,13 @@ local function force_auto_left_before() end if finidir == finish then head = remove_node(head,finished,true) - if trace_mirroring then + if trace_directions then list[finipos] = list[finipos] .. " (deleted afterwards)" insert(list,#list,format("start text dir %s (embedded: %s)",finish,embedded)) end else - head, inserted = insert_node_before(head,current,nodes.textdir("+"..finish)) - if trace_mirroring then + head, inserted = insert_node_before(head,current,new_textdir("+"..finish)) + if trace_directions then insert(list,#list,format("start text dir %s (embedded: %s)",finish,embedded)) end end @@ -136,13 +154,13 @@ local function force_auto_right_before() end if finidir == finish then head = remove_node(head,finished,true) - if trace_mirroring then + if trace_directions then list[finipos] = list[finipos] .. " (deleted afterwards)" insert(list,#list,format("start text dir %s (embedded: %s)",finish,embedded)) end else - head, inserted = insert_node_before(head,current,nodes.textdir("+"..finish)) - if trace_mirroring then + head, inserted = insert_node_before(head,current,new_textdir("+"..finish)) + if trace_directions then insert(list,#list,format("start text dir %s (embedded: %s)",finish,embedded)) end end @@ -150,25 +168,24 @@ end -- todo: use new dir functions -function mirroring.process(namespace,attribute,start) -- todo: make faster +function directions.process(namespace,attribute,start) -- todo: make faster if not start.next then return start, false end head, current, inserted = start, start, nil finish, autodir, embedded, override, done = nil, 0, 0, 0, false - list, glyphs = trace_mirroring and { }, false + list, glyphs = trace_directions and { }, false finished, finidir, finipos = nil, nil, 1 local stack, top, obsolete = { }, 0, { } local lro, rlo, prevattr, inmath = false, false, 0, false while current do local id = current.id --~ print(id,attribute,has_attribute(current,attribute)) - if skipmath and id == mthnode then + if skipmath and id == math_code then local subtype = current.subtype - if subtype == 0 then - -- begin math + if subtype == beginmath_code then inmath = true - elseif subtype == 1 then + elseif subtype == endmath_code then inmath = false else -- todo @@ -185,17 +202,17 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster elseif attr ~= prevattr then -- no pop, grouped driven (2=normal,3=lro,4=rlo) if attr == 3 then - if trace_mirroring then + if trace_directions then list[#list+1] = format("override right -> left (lro) (bidi=%s)",attr) end lro, rlo = true, false elseif attr == 4 then - if trace_mirroring then + if trace_directions then list[#list+1] = format("override left -> right (rlo) (bidi=%s)",attr) end lro, rlo = false, true else - if trace_mirroring and + if trace_directions and current ~= head then list[#list+1] = format("override reset (bidi=%s)",attr) end lro, rlo = false, false @@ -203,18 +220,18 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster prevattr = attr end end - if id == glyph then + if id == glyph_code then glyphs = true if attr and attr > 0 then local char = current.char - local d = directions[char] + local d = chardirs[char] if rlo or override > 0 then if d == "l" then - if trace_mirroring then + if trace_directions then list[#list+1] = format("char %s (%s / U+%04X) of class %s overidden to r (bidi=%s)",utfchar(char),char,char,d,attr) end d = "r" - elseif trace_mirroring then + elseif trace_directions then if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal list[#list+1] = format("override char of class %s (bidi=%s)",d,attr) else -- todo: rle lre @@ -224,18 +241,18 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster elseif lro or override < 0 then if d == "r" or d == "al" then set_attribute(current,a_state,4) -- maybe better have a special bidi attr value -> override (9) -> todo - if trace_mirroring then + if trace_directions then list[#list+1] = format("char %s (%s / U+%04X) of class %s overidden to l (bidi=%s) (state=isol)",utfchar(char),char,char,d,attr) end d = "l" - elseif trace_mirroring then + elseif trace_directions then if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal list[#list+1] = format("override char of class %s (bidi=%s)",d,attr) else -- todo: rle lre list[#list+1] = format("char %s (%s / U+%04X) of class %s (bidi=%s)",utfchar(char),char,char,d,attr) end end - elseif trace_mirroring then + elseif trace_directions then if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal list[#list+1] = format("override char of class %s (bidi=%s)",d,attr) else -- todo: rle lre @@ -271,7 +288,7 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster force_auto_left_before() end elseif d == "lro" then -- Left-to-Right Override -> right becomes left - if trace_mirroring then + if trace_directions then list[#list+1] = "override right -> left" end top = top + 1 @@ -279,7 +296,7 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster override = -1 obsolete[#obsolete+1] = current elseif d == "rlo" then -- Right-to-Left Override -> left becomes right - if trace_mirroring then + if trace_directions then list[#list+1] = "override left -> right" end top = top + 1 @@ -287,7 +304,7 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster override = 1 obsolete[#obsolete+1] = current elseif d == "lre" then -- Left-to-Right Embedding -> TLT - if trace_mirroring then + if trace_directions then list[#list+1] = "embedding left -> right" end top = top + 1 @@ -295,7 +312,7 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster embedded = 1 obsolete[#obsolete+1] = current elseif d == "rle" then -- Right-to-Left Embedding -> TRT - if trace_mirroring then + if trace_directions then list[#list+1] = "embedding right -> left" end top = top + 1 @@ -308,27 +325,27 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster local s = stack[top] override, embedded = s[1], s[2] top = top - 1 - if trace_mirroring then + if trace_directions then list[#list+1] = format("state: override: %s, embedded: %s, autodir: %s",override,embedded,autodir) end else - if trace_mirroring then + if trace_directions then list[#list+1] = "pop (error, too many pops)" end end obsolete[#obsolete+1] = current end - elseif trace_mirroring then + elseif trace_directions then local char = current.char - local d = directions[char] + local d = chardirs[char] list[#list+1] = format("char %s (%s / U+%04X) of class %s (no bidi)",utfchar(char),char,char,d or "?") end - elseif id == whatsit then + elseif id == whatsit_code then if finish then finish_auto_before() end local subtype = current.subtype - if subtype == 6 then + if subtype == localpar_code then local dir = current.dir local d = sub(dir,2,2) if d == 'R' then -- find(dir,".R.") / dir == "TRT" @@ -337,10 +354,10 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster autodir = 1 end -- embedded = autodir - if trace_mirroring then + if trace_directions then list[#list+1] = format("pardir %s",dir) end - elseif subtype == 7 then + elseif subtype == dir_code then local dir = current.dir -- local sign = sub(dir,1,1) -- local dire = sub(dir,3,3) @@ -358,12 +375,12 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster finish, autodir = nil, 0 end end - if trace_mirroring then + if trace_directions then list[#list+1] = format("textdir %s",dir) end end else - if trace_mirroring then + if trace_directions then list[#list+1] = format("node %s (subtype %s)",node.type(id),current.subtype) end if finish then @@ -379,20 +396,20 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster current = cn end end - if trace_mirroring and glyphs then - report_bidi("start log") + if trace_directions and glyphs then + report_directions("start log") for i=1,#list do - report_bidi("%02i: %s",i,list[i]) + report_directions("%02i: %s",i,list[i]) end - report_bidi("stop log") + report_directions("stop log") end - if done and mirroring.strip then + if done and strip then local n = #obsolete if n > 0 then for i=1,n do remove_node(head,obsolete[i],true) end - report_bidi("%s character nodes removed",n) + report_directions("%s character nodes removed",n) end end return head, done @@ -401,10 +418,10 @@ end --~ local function is_right(n) -- keep ! --~ if n then --~ local id = n.id ---~ if id == glyph then +--~ if id == glyph_code then --~ local attr = has_attribute(n,attribute) --~ if attr and attr > 0 then ---~ local d = directions[n.char] +--~ local d = chardirs[n.char] --~ if d == "r" or d == "al" then -- override --~ return true --~ end @@ -414,12 +431,23 @@ end --~ return false --~ end -mirroring.handler = nodes.install_attribute_handler { - name = "mirroring", - namespace = mirroring, - processor = mirroring.process, -} +--~ function directions.enable() +--~ tasks.enableaction("processors","directions.handler") +--~ end -function mirroring.enable() - tasks.enableaction("processors","mirroring.handler") +function directions.set(n) + if trace_directions then + report_breakpoints("enabling directions handler") + end + tasks.enableaction("processors","typesetters.directions.handler") + function directions.set(n) + texattribute[a_directions] = n == 0 and unsetvalue or n + end + directions.set(n) end + +directions.handler = nodes.install_attribute_handler { + name = "directions", + namespace = directions, + processor = directions.process, +} diff --git a/tex/context/base/typo-mir.mkiv b/tex/context/base/typo-dir.mkiv index 4c85262aa..ec071d0a1 100644 --- a/tex/context/base/typo-mir.mkiv +++ b/tex/context/base/typo-dir.mkiv @@ -1,8 +1,8 @@ %D \module -%D [ file=typo-mir, +%D [ file=typo-dir, %D version=2009.03.27, % code moved from core-spa.mkiv %D title=\CONTEXT\ Typesetting Macros, -%D subtitle=Mirroring, +%D subtitle=Directions, %D author=Hans Hagen, %D date=\currentdate, %D copyright=\PRAGMA] @@ -11,23 +11,22 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\writestatus{loading}{ConTeXt Typesetting Macros / Mirroring} +\writestatus{loading}{ConTeXt Typesetting Macros / Directions} \unprotect -\registerctxluafile{typo-mir}{1.001} +\registerctxluafile{typo-dir}{1.001} -\definesystemattribute[mirroring] \chardef\mirroringattribute \dogetattributeid{mirroring} +\definesystemattribute[directions] \chardef\directionsattribute \dogetattributeid{directions} -% experimental mirroring +% experimental directions -\def\setcharactermirroring - {\ctxlua{mirroring.enable()}% - \gdef\setcharactermirroring[##1]{\attribute\mirroringattribute##1\relax}% - \setcharactermirroring} +\unexpanded\def\setdirection[#1]% todo: symbolic names + {\ctxlua{typesetters.directions.set(#1)}} -\def\resetcharactermirroring - {\attribute\mirroringattribute\attributeunsetvalue} +\unexpanded\def\resetdirection + %{\ctxlua{typesetters.directions.set(0)}} + {\attribute\directionsattribute\attributeunsetvalue} \newtoks\everysetupdirections @@ -45,13 +44,13 @@ \appendtoks \chardef\directionsbidimode\executeifdefined{\??di:bidi:\@@dibidi}\zerocount\relax \ifcase\directionsbidimode - \resetcharactermirroring + \resetdirection \or - \setcharactermirroring[1]% global, chars + \setdirection[1]% global, chars \or - \setcharactermirroring[2]% local, attributes + \setdirection[2]% local, attributes \or - \setcharactermirroring[1]% default + \setdirection[1]% default \fi \to \everysetupdirections @@ -68,10 +67,10 @@ \unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi} \unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi} -\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setcharactermirroring[3]\fi} -\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setcharactermirroring[4]\fi} +\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setdirection[3]\fi} +\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setdirection[4]\fi} -% for the moment: \setcharactermirroring[\plusone] +% for the moment: \setdirection[\plusone] \protect \endinput @@ -86,7 +85,7 @@ \font\Arabic=arabtype*arab at 20pt -\def\LATIN{LATIN} {\setcharactermirroring[1]} % enable this +\def\LATIN{LATIN} {\setdirection[1]} % enable this \def\ARAB {محمد} \startluacode @@ -100,9 +99,9 @@ \def\biditest#1#2#3% font text raw {\dontleavehmode\hbox {\framed[offset=overlay]{\tttf#2}\quad - \enabletrackers[nodes.mirroring]% + \enabletrackers[typesetters.directions]% \framed[offset=overlay]{#1#3}\quad - \disabletrackers[nodes.mirroring]% + \disabletrackers[typesetters.directions]% \tttf\ctxlua{document.split_tokens([[\detokenize{#3}]])}}} \startbuffer[bidi-sample] diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua index 27bd09e4d..effbd01f6 100644 --- a/tex/context/base/typo-krn.lua +++ b/tex/context/base/typo-krn.lua @@ -11,6 +11,8 @@ local utf = unicode.utf8 local next, type = next, type local utfchar = utf.char +local nodes, node, fonts = nodes, node, fonts + local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute local find_node_tail = node.tail or node.slide @@ -20,37 +22,47 @@ local copy_node = node.copy local copy_nodelist = node.copy_list local insert_node_before = node.insert_before local insert_node_after = node.insert_after -local make_glue_spec = nodes.glue_spec -local make_kern_node = nodes.kern local texattribute = tex.attribute -local nodecodes = nodes.nodecodes +local nodepool = nodes.pool +local tasks = nodes.tasks + +local new_gluespec = nodepool.glue_spec +local new_kern = nodepool.kern + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes +local skipcodes = nodes.skipcodes -local glyph = nodecodes.glyph -local kern = nodecodes.kern -local disc = nodecodes.disc -local glue = nodecodes.glue -local hlist = nodecodes.hlist -local vlist = nodecodes.vlist +local glyph_code = nodecodes.glyph +local kern_code = nodecodes.kern +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist -local fontdata = fonts.identifiers -local chardata = fonts.characters -local quaddata = fonts.quads +local kerning_code = kerncodes.kerning +local userkern_code = kerncodes.userkern +local userskip_code = skipcodes.userskip -typesetting = typesetting or { } -typesetting.kerns = typesetting.kerns or { } +local fontdata = fonts.identifiers +local chardata = fonts.characters +local quaddata = fonts.quads -local kerns = typesetting.kerns +typesetters = typesetters or { } +local typesetters = typesetters -kerns.mapping = kerns.mapping or { } -kerns.factors = kerns.factors or { } -kerns.attribute = attributes.private("kern") +typesetters.kerns = typesetters.kerns or { } +local kerns = typesetters.kerns -local a_kerns = kerns.attribute +kerns.mapping = kerns.mapping or { } +kerns.factors = kerns.factors or { } +local a_kerns = attributes.private("kern") +kerns.attribute = kerns.attribute -storage.register("typesetting/kerns/mapping", kerns.mapping, "typesetting.kerns.mapping") -storage.register("typesetting/kerns/factors", kerns.factors, "typesetting.kerns.factors") +storage.register("typesetters/kerns/mapping", kerns.mapping, "typesetters.kerns.mapping") +storage.register("typesetters/kerns/factors", kerns.factors, "typesetters.kerns.factors") local mapping = kerns.mapping local factors = kerns.factors @@ -73,7 +85,7 @@ local function do_process(namespace,attribute,head,force) local krn = mapping[attr] if krn and krn ~= 0 then local id = start.id - if id == glyph then + if id == glyph_code then lastfont = start.font local c = start.components if c then @@ -102,11 +114,11 @@ local function do_process(namespace,attribute,head,force) local pid = prev.id if not pid then -- nothing - elseif pid == kern and prev.subtype == 0 then - prev.subtype = 1 + elseif pid == kern_code and prev.subtype == kerning_code then + prev.subtype = userkern_code prev.kern = prev.kern + quaddata[lastfont]*krn done = true - elseif pid == glyph then + elseif pid == glyph_code then if prev.font == lastfont then local prevchar, lastchar = prev.char, start.char local kerns = chardata[lastfont][prevchar].kerns @@ -115,9 +127,9 @@ local function do_process(namespace,attribute,head,force) else krn = quaddata[lastfont]*krn end - insert_node_before(head,start,make_kern_node(krn)) + insert_node_before(head,start,new_kern(krn)) done = true - elseif pid == disc then + elseif pid == disc_code then -- a bit too complicated, we can best not copy and just calculate -- but we could have multiple glyphs involved so ... local disc = prev -- disc @@ -164,7 +176,7 @@ local function do_process(namespace,attribute,head,force) free_node(after) free_node(before) else - if prv and prv.id == glyph and prv.font == lastfont then + if prv and prv.id == glyph_code and prv.font == lastfont then local prevchar, lastchar = prv.char, start.char local kerns = chardata[lastfont][prevchar].kerns local kern = kerns and kerns[lastchar] or 0 @@ -172,33 +184,33 @@ local function do_process(namespace,attribute,head,force) else krn = quaddata[lastfont]*krn end - disc.replace = make_kern_node(krn) + disc.replace = new_kern(krn) end end end - elseif id == glue and start.subtype == 0 then + elseif id == glue_code and start.subtype == userskip_code then local s = start.spec local w = s.width if w > 0 then local width, stretch, shrink = w+gluefactor*w*krn, s.stretch, s.shrink - start.spec = make_glue_spec(width,stretch*width/w,shrink*width/w) + start.spec = new_gluespec(width,stretch*width/w,shrink*width/w) done = true end - elseif false and id == kern and start.subtype == 0 then -- handle with glyphs + elseif false and id == kern_code and start.subtype == kerning_code then -- handle with glyphs local sk = start.kern if sk > 0 then start.kern = sk*krn done = true end - elseif lastfont and (id == hlist or id == vlist) then -- todo: lookahead + elseif lastfont and (id == hlist_code or id == vlist_code) then -- todo: lookahead local p = start.prev - if p and p.id ~= glue then - insert_node_before(head,start,make_kern_node(quaddata[lastfont]*krn)) + if p and p.id ~= glue_code then + insert_node_before(head,start,new_kern(quaddata[lastfont]*krn)) done = true end local n = start.next - if n and n.id ~= glue then - insert_node_after(head,start,make_kern_node(quaddata[lastfont]*krn)) + if n and n.id ~= glue_code then + insert_node_after(head,start,new_kern(quaddata[lastfont]*krn)) done = true end end @@ -215,7 +227,7 @@ local enabled = false function kerns.set(factor) if not enabled then - tasks.enableaction("processors","typesetting.kerns.handler") + tasks.enableaction("processors","typesetters.kerns.handler") enabled = true end if factor > 0 then diff --git a/tex/context/base/typo-krn.mkiv b/tex/context/base/typo-krn.mkiv index d2b9d3b65..7bb3a10a7 100644 --- a/tex/context/base/typo-krn.mkiv +++ b/tex/context/base/typo-krn.mkiv @@ -41,7 +41,7 @@ \fi} \unexpanded\def\dosetcharacterkerning#1% - {\ctxlua{typesetting.kerns.set(\csname\??ck#1\c!factor\endcsname)}} + {\ctxlua{typesetters.kerns.set(\csname\??ck#1\c!factor\endcsname)}} \unexpanded\def\setcharacterkerning[#1]% {\csname\??ck:#1\endcsname} diff --git a/tex/context/base/typo-rep.lua b/tex/context/base/typo-rep.lua index ac93cde6f..bdeb813ba 100644 --- a/tex/context/base/typo-rep.lua +++ b/tex/context/base/typo-rep.lua @@ -15,21 +15,23 @@ local trace_stripping = false trackers.register("nodes.stripping", function(v) local report_fonts = logs.new("fonts") +local nodes, node = nodes, node + local delete_node = nodes.delete local replace_node = nodes.replace local copy_node = node.copy local has_attribute = node.has_attribute -local chardata = characters.data -local collected = false -local attribute = attributes.private("stripping") -local fontdata = fonts.ids - -local nodecodes = nodes.nodecodes +local chardata = characters.data +local collected = false +local attribute = attributes.private("stripping") +local fontdata = fonts.ids +local tasks = nodes.tasks -local glyph = nodecodes.glyph +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph --- other namespace +-- todo: other namespace -> typesetters nodes.stripping = nodes.stripping or { } local stripping = nodes.stripping stripping.glyphs = stripping.glyphs or { } local glyphs = stripping.glyphs @@ -67,10 +69,10 @@ local function process(what,head,current,char) return head, current end -function nodes.stripping.process(head) +function nodes.handlers.stripping(head) local current, done = head, false while current do - if current.id == glyph then + if current.id == glyph_code then -- it's more efficient to keep track of what needs to be kept local todo = has_attribute(current,attribute) if todo == 1 then @@ -92,12 +94,12 @@ function nodes.stripping.process(head) return head, done end -tasks.appendaction("processors","fonts","nodes.stripping.process",nil,"nodes.process_characters") -tasks.disableaction("processors","nodes.stripping.process") +tasks.appendaction("processors","fonts","nodes.handlers.stripping",nil,"nodes.handlers.characters") +tasks.disableaction("processors","nodes.handlers.stripping") function nodes.stripping.enable() if initialize then initialize() end - tasks.enableaction("processors","nodes.stripping.process") + tasks.enableaction("processors","nodes.handlers.stripping") function nodes.stripping.enable() end end @@ -110,7 +112,7 @@ local function processformatters(head,font) if how == nil or how == "strip" then -- nil when forced local current, done = head, false while current do - if current.id == glyph and current.subtype<256 and current.font == font then + if current.id == glyph_code and current.subtype<256 and current.font == font then local char = current.char local what = glyphs[char] if what then diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua index b11d4e386..75cc64728 100644 --- a/tex/context/base/typo-spa.lua +++ b/tex/context/base/typo-spa.lua @@ -13,37 +13,43 @@ local utf = unicode.utf8 local next, type = next, type local utfchar = utf.char -local trace_spacing = false trackers.register("typesetting.spacing", function(v) trace_spacing = v end) +local trace_spacing = false trackers.register("typesetters.spacing", function(v) trace_spacing = v end) local report_spacing = logs.new("spacing") +local nodes, fonts, node = nodes, fonts, node + local has_attribute = node.has_attribute local unset_attribute = node.unset_attribute local insert_node_before = node.insert_before local insert_node_after = node.insert_after local remove_node = nodes.remove -local make_penalty_node = nodes.penalty -local make_glue_node = nodes.glue local fontdata = fonts.identifiers local quaddata = fonts.quads -local nodecodes = nodes.nodecodes local texattribute = tex.attribute -local glyph = nodecodes.glyph +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph + +local nodepool = nodes.pool +local tasks = nodes.tasks -typesetting = typesetting or { } -typesetting.spacings = typesetting.spacings or { } +local new_penalty = nodepool.penalty +local new_glue = nodepool.glue -local spacings = typesetting.spacings +typesetters = typesetters or { } +local typesetters = typesetters -spacings.mapping = spacings.mapping or { } -spacings.attribute = attributes.private("spacing") +typesetters.spacings = typesetters.spacings or { } +local spacings = typesetters.spacings -local a_spacings = spacings.attribute +spacings.mapping = spacings.mapping or { } +local a_spacings = attributes.private("spacing") +spacings.attribute = a_spacings -storage.register("typesetting/spacings/mapping", spacings.mapping, "typesetting.spacings.mapping") +storage.register("typesetters/spacings/mapping", spacings.mapping, "typesetters.spacings.mapping") local function process(namespace,attribute,head) local done, mapping = false, spacings.mapping @@ -51,7 +57,7 @@ local function process(namespace,attribute,head) -- head is always begin of par (whatsit), so we have at least two prev nodes -- penalty followed by glue while start do - if start.id == glyph then + if start.id == glyph_code then local attr = has_attribute(start,attribute) if attr and attr > 0 then local map = mapping[attr] @@ -90,8 +96,8 @@ local function process(namespace,attribute,head) if trace_spacing then report_spacing("inserting penalty and space before %s (left)", utfchar(start.char)) end - insert_node_before(head,start,make_penalty_node(10000)) - insert_node_before(head,start,make_glue_node(tex.scale(quad,left))) + insert_node_before(head,start,new_penalty(10000)) + insert_node_before(head,start,new_glue(tex.scale(quad,left))) done = true end end @@ -127,8 +133,8 @@ local function process(namespace,attribute,head) if trace_spacing then report_spacing("inserting penalty and space after %s (right)", utfchar(start.char)) end - insert_node_after(head,start,make_glue_node(tex.scale(quad,right))) - insert_node_after(head,start,make_penalty_node(10000)) + insert_node_after(head,start,new_glue(tex.scale(quad,right))) + insert_node_after(head,start,new_penalty(10000)) done = true end end @@ -159,7 +165,7 @@ end function spacings.set(id) if not enabled then - tasks.enableaction("processors","typesetting.spacings.handler") + tasks.enableaction("processors","typesetters.spacings.handler") enabled = true end texattribute[a_spacings] = id diff --git a/tex/context/base/typo-spa.mkiv b/tex/context/base/typo-spa.mkiv index c877fdf67..2f6aaf43b 100644 --- a/tex/context/base/typo-spa.mkiv +++ b/tex/context/base/typo-spa.mkiv @@ -38,12 +38,12 @@ {\ifcsname\??ch:#1\endcsname \begingroup % for the moment we use modes, in ordere to avoid interface translation \getparameters[\??ch][\c!left=0,\c!right=0,\c!alternative=0,#3]% - \ctxlua{typesetting.spacings.setup(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}% + \ctxlua{typesetters.spacings.setup(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}% \endgroup \fi} \unexpanded\def\setcharacterspacing[#1]% - {\ctxlua{typesetting.spacings.set(\number\csname\??ch:#1\endcsname)}} + {\ctxlua{typesetters.spacings.set(\number\csname\??ch:#1\endcsname)}} \unexpanded\def\resetcharacterspacing % fast one {\attribute\spacingattribute\attributeunsetvalue} diff --git a/tex/context/base/trac-tra.lua b/tex/context/base/util-deb.lua index 916b68045..8a0efde45 100644 --- a/tex/context/base/trac-tra.lua +++ b/tex/context/base/util-deb.lua @@ -1,6 +1,6 @@ -if not modules then modules = { } end modules ['trac-tra'] = { +if not modules then modules = { } end modules ['util.deb'] = { version = 1.001, - comment = "companion to trac-tra.mkiv", + comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -17,10 +17,12 @@ local type, next = type, next local format, find = string.format, string.find local is_boolean = string.is_boolean -debugger = debugger or { } +utilities = utilities or { } +utilities.debugger = utilities.debugger or { } +local debugger = utilities.debugger local counters = { } -local names = { } +local names = { } -- one @@ -126,19 +128,6 @@ function debugger.disable() --~ counters[debug.getinfo(2,"f").func] = nil end -local function trace_calls(n) - debugger.enable() - luatex.register_stop_actions(function() - debugger.disable() - debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) - end) - trace_calls = function() end -end - -if directives then - directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling -end - --~ debugger.enable() --~ print(math.sin(1*.5)) diff --git a/tex/context/base/util-fmt.lua b/tex/context/base/util-fmt.lua new file mode 100644 index 000000000..e94782c32 --- /dev/null +++ b/tex/context/base/util-fmt.lua @@ -0,0 +1,96 @@ +if not modules then modules = { } end modules ['util-fmt'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or { } +utilities.formatters = utilities.formatters or { } +local formatters = utilities.formatters + +local concat, format = table.concat, string.format +local tostring, type = tostring, type +local strip = string.strip + +local P, R, Cs = lpeg.P, lpeg.R, lpeg.Cs +local lpegmatch = lpeg.match + +-- temporary here + +local digit = R("09") +local period = P(".") +local zero = P("0") +local trailingzeros = zero^0 * -digit -- suggested by Roberto R +local case_1 = period * trailingzeros / "" +local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number = digit^1 * (case_1 + case_2) +local stripper = Cs((number + 1)^0) + +--~ local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100" +--~ collectgarbage("collect") +--~ str = string.rep(sample,10000) +--~ local ts = os.clock() +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) + +lpeg.patterns.strip_zeros = stripper + +function formatters.strip_zeros(str) + return lpegmatch(stripper,str) +end + +function formatters.formatcolumns(result,between) + if result and #result > 0 then + between = between or " " + local widths, numbers = { }, { } + local first = result[1] + local n = #first + for i=1,n do + widths[i] = 0 + end + for i=1,#result do + local r = result[i] + for j=1,n do + local rj = r[j] + local tj = type(rj) + if tj == "number" then + numbers[j] = true + end + if tj ~= "string" then + rj = tostring(rj) + r[j] = rj + end + local w = #rj + if w > widths[j] then + widths[j] = w + end + end + end + for i=1,n do + local w = widths[i] + if numbers[i] then + if w > 80 then + widths[i] = "%s" .. between + else + widths[i] = "%0" .. w .. "i" .. between + end + else + if w > 80 then + widths[i] = "%s" .. between + elseif w > 0 then + widths[i] = "%-" .. w .. "s" .. between + else + widths[i] = "%s" + end + end + end + local template = strip(concat(widths)) + for i=1,#result do + local str = format(template,unpack(result[i])) + result[i] = strip(str) + end + end + return result +end diff --git a/tex/context/base/util-lua.lua b/tex/context/base/util-lua.lua new file mode 100644 index 000000000..0174f667f --- /dev/null +++ b/tex/context/base/util-lua.lua @@ -0,0 +1,27 @@ +if not modules then modules = { } end modules ['util-lua'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.lua = utilities.merger or { } +utilities.report = utilities.report or print + +function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true + utilities.report("lua: compiling %s into %s",luafile,lucfile) + os.remove(lucfile) + local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile) + if strip ~= false then + command = "-s " .. command + end + local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 + if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + utilities.report("lua: removing %s",luafile) + os.remove(luafile) + end + return done +end + diff --git a/tex/context/base/util-mrg.lua b/tex/context/base/util-mrg.lua new file mode 100644 index 000000000..79e83541f --- /dev/null +++ b/tex/context/base/util-mrg.lua @@ -0,0 +1,138 @@ +if not modules then modules = { } end modules ['util-mrg'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- hm, quite unreadable + +local gsub, format = string.gsub, string.format +local concat = table.concat +local type, next = type, next + +utilities = utilities or {} +utilities.merger = utilities.merger or { } +utilities.report = utilities.report or print + +local merger = utilities.merger + +merger.strip_comment = true + +local m_begin_merge = "begin library merge" +local m_end_merge = "end library merge" +local m_begin_closure = "do -- create closure to overcome 200 locals limit" +local m_end_closure = "end -- of closure" + +local m_pattern = + "%c+" .. + "%-%-%s+" .. m_begin_merge .. + "%c+(.-)%c+" .. + "%-%-%s+" .. m_end_merge .. + "%c+" + +local m_format = + "\n\n-- " .. m_begin_merge .. + "\n%s\n" .. + "-- " .. m_end_merge .. "\n\n" + +local m_faked = + "-- " .. "created merged file" .. "\n\n" .. + "-- " .. m_begin_merge .. "\n\n" .. + "-- " .. m_end_merge .. "\n\n" + +local function self_fake() + return m_faked +end + +local function self_nothing() + return "" +end + +local function self_load(name) + local data = io.loaddata(name) or "" + if data == "" then + utilities.report("merge: unknown file %s",name) + else + utilities.report("merge: inserting %s",name) + end + return data or "" +end + +local function self_save(name, data) + if data ~= "" then + if merger.strip_comment then + -- saves some 20K + local n = #data + data = gsub(data,"%-%-~[^\n\r]*[\r\n]","") + utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data) + end + io.savedata(name,data) + utilities.report("merge: saving %s",name) + end +end + +local function self_swap(data,code) + return data ~= "" and (gsub(data,m_pattern, function() return format(m_format,code) end, 1)) or "" +end + +local function self_libs(libs,list) + local result, f, frozen, foundpath = { }, nil, false, nil + result[#result+1] = "\n" + if type(libs) == 'string' then libs = { libs } end + if type(list) == 'string' then list = { list } end + for i=1,#libs do + local lib = libs[i] + for j=1,#list do + local pth = gsub(list[j],"\\","/") -- file.clean_path + utilities.report("merge: checking library path %s",pth) + local name = pth .. "/" .. lib + if lfs.isfile(name) then + foundpath = pth + end + end + if foundpath then break end + end + if foundpath then + utilities.report("merge: using library path %s",foundpath) + local right, wrong = { }, { } + for i=1,#libs do + local lib = libs[i] + local fullname = foundpath .. "/" .. lib + if lfs.isfile(fullname) then + utilities.report("merge: using library %s",fullname) + right[#right+1] = lib + result[#result+1] = m_begin_closure + result[#result+1] = io.loaddata(fullname,true) + result[#result+1] = m_end_closure + else + utilities.report("merge: skipping library %s",fullname) + wrong[#wrong+1] = lib + end + end + if #right > 0 then + utilities.report("merge: used libraries: %s",concat(right," ")) + end + if #wrong > 0 then + utilities.report("merge: skipped libraries: %s",concat(wrong," ")) + end + else + utilities.report("merge: no valid library path found") + end + return concat(result, "\n\n") +end + +function merger.selfcreate(libs,list,target) + if target then + self_save(target,self_swap(self_fake(),self_libs(libs,list))) + end +end + +function merger.selfmerge(name,libs,list,target) + self_save(target or name,self_swap(self_load(name),self_libs(libs,list))) +end + +function merger.selfclean(name) + self_save(name,self_swap(self_load(name),self_nothing())) +end diff --git a/tex/context/base/util-pck.lua b/tex/context/base/util-pck.lua new file mode 100644 index 000000000..835c70800 --- /dev/null +++ b/tex/context/base/util-pck.lua @@ -0,0 +1,110 @@ +if not modules then modules = { } end modules ['util-pck'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- moved from core-uti + +local next, tostring, type = next, tostring, type +local sort, concat = table.sort, table.concat + +utilities = utilities or { } +utilities.packers = utilities.packers or { } +local packers = utilities.packers +packers.version = 1.00 + +local function hashed(t) + local s = { } + for k, v in next, t do + if type(v) == "table" then + s[#s+1] = k.."={"..hashed(v).."}" + else + s[#s+1] = k.."="..tostring(v) + end + end + sort(s) + return concat(s,",") +end + +local function pack(t,keys,hash,index) + for k,v in next, t do + if type(v) == "table" then + pack(v,keys,hash,index) + end + if keys[k] and type(v) == "table" then + local h = hashed(v) + local i = hash[h] + if not i then + i = #index+1 + index[i] = v + hash[h] = i + end + t[k] = i + end + end +end + +local function unpack(t,keys,index) + for k,v in next, t do + if keys[k] and type(v) == "number" then + local iv = index[v] + if iv then + v = iv + t[k] = v + end + end + if type(v) == "table" then + unpack(v,keys,index) + end + end +end + +function packers.new(keys,version) + return { + version = version or packers.version, + keys = table.tohash(keys), + hash = { }, + index = { }, + } +end + +function packers.pack(t,p,shared) + if shared then + pack(t,p.keys,p.hash,p.index) + elseif not t.packer then + pack(t,p.keys,p.hash,p.index) + if #p.index > 0 then + t.packer = { + version = p.version or packers.version, + keys = p.keys, + index = p.index, + } + end + p.hash, p.index = { }, { } + end +end + +function packers.unpack(t,p,shared) + if shared then + if p then + unpack(t,p.keys,p.index) + end + else + local tp = t.packer + if tp then + if tp.version == (p and p.version or packers.version) then + unpack(t,tp.keys,tp.index) + else + -- fatal error, wrong version + end + t.packer = nil + end + end +end + +function packers.strip(p) + p.hash = nil +end diff --git a/tex/context/base/util-prs.lua b/tex/context/base/util-prs.lua new file mode 100644 index 000000000..4580a02b8 --- /dev/null +++ b/tex/context/base/util-prs.lua @@ -0,0 +1,201 @@ +if not modules then modules = { } end modules ['util-prs'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.parsers = utilities.parsers or { } +local parsers = utilities.parsers +parsers.patterns = parsers.patterns or { } + +local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg +local lpegmatch = lpeg.match +local concat, format, gmatch = table.concat, string.format, string.gmatch +local tostring, type = tostring, type +local sortedhash = table.sortedhash + +local escape, left, right = P("\\"), P('{'), P('}') + +lpeg.patterns.balanced = P { + [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0, + [2] = left * V(1) * right +} + +local space = P(' ') +local equal = P("=") +local comma = P(",") +local lbrace = P("{") +local rbrace = P("}") +local nobrace = 1 - (lbrace+rbrace) +local nested = P { lbrace * (nobrace + V(1))^0 * rbrace } +local spaces = space^0 + +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) + +local key = C((1-equal-comma)^1) +local pattern_a = (space+comma)^0 * (key * equal * value + key * C("")) +local pattern_c = (space+comma)^0 * (key * equal * value) + +local key = C((1-space-equal-comma)^1) +local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C(""))) + +-- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored + +local hash = { } + +local function set(key,value) -- using Carg is slower here + hash[key] = value +end + +local pattern_a_s = (pattern_a/set)^1 +local pattern_b_s = (pattern_b/set)^1 +local pattern_c_s = (pattern_c/set)^1 + +parsers.patterns.settings_to_hash_a = pattern_a_s +parsers.patterns.settings_to_hash_b = pattern_b_s +parsers.patterns.settings_to_hash_c = pattern_c_s + +function parsers.make_settings_to_hash_pattern(set,how) + if how == "strict" then + return (pattern_c/set)^1 + elseif how == "tolerant" then + return (pattern_b/set)^1 + else + return (pattern_a/set)^1 + end +end + +function parsers.settings_to_hash(str,existing) + if str and str ~= "" then + hash = existing or { } + lpegmatch(pattern_a_s,str) + return hash + else + return { } + end +end + +function parsers.settings_to_hash_tolerant(str,existing) + if str and str ~= "" then + hash = existing or { } + lpegmatch(pattern_b_s,str) + return hash + else + return { } + end +end + +function parsers.settings_to_hash_strict(str,existing) + if str and str ~= "" then + hash = existing or { } + lpegmatch(pattern_c_s,str) + return next(hash) and hash + else + return nil + end +end + +local separator = comma * space^0 +local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) +local pattern = Ct(value*(separator*value)^0) + +-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored + +parsers.patterns.settings_to_array = pattern + +-- we could use a weak table as cache + +function parsers.settings_to_array(str) + if not str or str == "" then + return { } + else + return lpegmatch(pattern,str) + end +end + +local function set(t,v) + t[#t+1] = v +end + +local value = P(Carg(1)*value) / set +local pattern = value*(separator*value)^0 * Carg(1) + +function parsers.add_settings_to_array(t,str) + return lpegmatch(pattern,str,nil,t) +end + +function parsers.hash_to_string(h,separator,yes,no,strict,omit) + if h then + local t, s = { }, table.sortedkeys(h) + omit = omit and table.tohash(omit) + for i=1,#s do + local key = s[i] + if not omit or not omit[key] then + local value = h[key] + if type(value) == "boolean" then + if yes and no then + if value then + t[#t+1] = key .. '=' .. yes + elseif not strict then + t[#t+1] = key .. '=' .. no + end + elseif value or not strict then + t[#t+1] = key .. '=' .. tostring(value) + end + else + t[#t+1] = key .. '=' .. value + end + end + end + return concat(t,separator or ",") + else + return "" + end +end + +function parsers.array_to_string(a,separator) + if a then + return concat(a,separator or ",") + else + return "" + end +end + +function parsers.settings_to_set(str,t) -- tohash? -- todo: lpeg -- duplicate anyway + t = t or { } + for s in gmatch(str,"%s*([^, ]+)") do -- space added + t[s] = true + end + return t +end + +function parsers.simple_hash_to_string(h, separator) + local t = { } + for k, v in sortedhash(h) do + if v then + t[#t+1] = k + end + end + return concat(t,separator or ",") +end + +local value = lbrace * C((nobrace + nested)^0) * rbrace +local pattern = Ct((space + value)^0) + +function parsers.arguments_to_table(str) + return lpegmatch(pattern,str) +end + +-- temporary here (unoptimized) + +function parsers.getparameters(self,class,parentclass,settings) + local sc = self[class] + if not sc then + sc = table.clone(self[parent]) + self[class] = sc + end + parsers.settings_to_hash(settings,sc) +end diff --git a/tex/context/base/node-seq.lua b/tex/context/base/util-seq.lua index 3a2cf5b6e..3f27221fe 100644 --- a/tex/context/base/node-seq.lua +++ b/tex/context/base/util-seq.lua @@ -1,6 +1,6 @@ -if not modules then modules = { } end modules ['node-seq'] = { +if not modules then modules = { } end modules ['util-seq'] = { version = 1.001, - comment = "companion to node-ini.mkiv", + comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -18,7 +18,9 @@ use locals to refer to them when compiling the chain.</p> local format, gsub, concat, gmatch = string.format, string.gsub, table.concat, string.gmatch local type, loadstring = type, loadstring -sequencer = sequencer or { } +utilities = utilities or { } +utilities.sequencers = utilities.sequencers or { } +local sequencers = utilities.sequencers local function validaction(action) local g = _G @@ -31,7 +33,7 @@ local function validaction(action) return true end -function sequencer.reset() +function sequencers.reset() return { list = { }, order = { }, @@ -41,21 +43,21 @@ function sequencer.reset() } end -function sequencer.prependgroup(t,group,where) +function sequencers.prependgroup(t,group,where) local list, order = t.list, t.order table.remove_value(order,group) table.insert_before_value(order,where,group) list[group] = { } end -function sequencer.appendgroup(t,group,where) +function sequencers.appendgroup(t,group,where) local list, order = t.list, t.order table.remove_value(order,group) table.insert_after_value(order,where,group) list[group] = { } end -function sequencer.prependaction(t,group,action,where,kind,force) +function sequencers.prependaction(t,group,action,where,kind,force) local g = t.list[group] if g and (force or validaction(action)) then table.remove_value(g,action) @@ -64,7 +66,7 @@ function sequencer.prependaction(t,group,action,where,kind,force) end end -function sequencer.appendaction(t,group,action,where,kind,force) +function sequencers.appendaction(t,group,action,where,kind,force) local g = t.list[group] if g and (force or validaction(action)) then table.remove_value(g,action) @@ -73,29 +75,29 @@ function sequencer.appendaction(t,group,action,where,kind,force) end end -function sequencer.enableaction (t,action) t.askip[action] = false end -function sequencer.disableaction(t,action) t.askip[action] = true end -function sequencer.enablegroup (t,group) t.gskip[group] = false end -function sequencer.disablegroup (t,group) t.gskip[group] = true end +function sequencers.enableaction (t,action) t.askip[action] = false end +function sequencers.disableaction(t,action) t.askip[action] = true end +function sequencers.enablegroup (t,group) t.gskip[group] = false end +function sequencers.disablegroup (t,group) t.gskip[group] = true end -function sequencer.setkind(t,action,kind) +function sequencers.setkind(t,action,kind) t.kind[action] = kind end -function sequencer.removeaction(t,group,action,force) +function sequencers.removeaction(t,group,action,force) local g = t.list[group] if g and (force or validaction(action)) then table.remove_value(g,action) end end -function sequencer.compile(t,compiler,n) +function sequencers.compile(t,compiler,n) if type(t) == "string" then -- already compiled elseif compiler then t = compiler(t,n) else - t = sequencer.tostring(t) + t = sequencers.tostring(t) end return loadstring(t)() end @@ -110,7 +112,7 @@ return function(...) %s end]] -function sequencer.tostring(t) +function sequencers.tostring(t) local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip local vars, calls, args = { }, { }, nil for i=1,#order do @@ -144,7 +146,7 @@ return function(head%s) return head, done end]] -function sequencer.nodeprocessor(t,n) +function sequencers.nodeprocessor(t,n) local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip local vars, calls, args = { }, { }, nil if n == 0 then diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua new file mode 100644 index 000000000..c9a0923a5 --- /dev/null +++ b/tex/context/base/util-tab.lua @@ -0,0 +1,34 @@ +if not modules then modules = { } end modules ['util-tab'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.tables = utilities.tables or { } +local tables = utilities.tables + +local concat, format, gmatch = table.concat, string.format, string.gmatch + +function tables.definetable(target) -- defines undefined tables + local composed, t = nil, { } + for name in gmatch(target,"([^%.]+)") do + if composed then + composed = composed .. "." .. name + else + composed = name + end + t[#t+1] = format("%s = %s or { }",composed,composed) + end + return concat(t,"\n") +end + +function tables.accesstable(target) + local t = _G + for name in gmatch(target,"([^%.]+)") do + t = t[name] + end + return t +end diff --git a/tex/context/interface/keys-cs.xml b/tex/context/interface/keys-cs.xml index f45cd0892..4001b5808 100644 --- a/tex/context/interface/keys-cs.xml +++ b/tex/context/interface/keys-cs.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='offsetpozadi'/> <cd:constant name='backgroundradius' value='polomerpozadi'/> <cd:constant name='backgroundscreen' value='rastrpozadi'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='zpetnamezera'/> <cd:constant name='balance' value='rovnovaha'/> <cd:constant name='before' value='pred'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interakce'/> <cd:constant name='interlinespace' value='meziradkovamezera'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='polozky'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml index 0f0cd6da5..a5a6052c1 100644 --- a/tex/context/interface/keys-de.xml +++ b/tex/context/interface/keys-de.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='hintergrundoffset'/> <cd:constant name='backgroundradius' value='hintergrundradius'/> <cd:constant name='backgroundscreen' value='hintergrundraster'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='rumpfspatium'/> <cd:constant name='balance' value='ausgleichen'/> <cd:constant name='before' value='vor'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interaktion'/> <cd:constant name='interlinespace' value='zeilenabstande'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='posten'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml index 2d2dfe04a..6e38271af 100644 --- a/tex/context/interface/keys-en.xml +++ b/tex/context/interface/keys-en.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='backgroundoffset'/> <cd:constant name='backgroundradius' value='backgroundradius'/> <cd:constant name='backgroundscreen' value='backgroundscreen'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='backspace'/> <cd:constant name='balance' value='balance'/> <cd:constant name='before' value='before'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interaction'/> <cd:constant name='interlinespace' value='interlinespace'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='items'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml index 0ff5eabe2..4496a84e5 100644 --- a/tex/context/interface/keys-fr.xml +++ b/tex/context/interface/keys-fr.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='decalagearriereplan'/> <cd:constant name='backgroundradius' value='rayonarriereplan'/> <cd:constant name='backgroundscreen' value='ecranarriereplan'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='retour'/> <cd:constant name='balance' value='equilibre'/> <cd:constant name='before' value='avant'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interaction'/> <cd:constant name='interlinespace' value='espaceinterligne'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='elements'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml index 543c67949..24079698f 100644 --- a/tex/context/interface/keys-it.xml +++ b/tex/context/interface/keys-it.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='offsetsfondo'/> <cd:constant name='backgroundradius' value='raggiosfondo'/> <cd:constant name='backgroundscreen' value='schermosfondo'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='backspace'/> <cd:constant name='balance' value='bilanciamento'/> <cd:constant name='before' value='prima'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interazione'/> <cd:constant name='interlinespace' value='interlinea'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='elementi'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml index 0ac9763ec..17e3586d3 100644 --- a/tex/context/interface/keys-nl.xml +++ b/tex/context/interface/keys-nl.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='achtergrondoffset'/> <cd:constant name='backgroundradius' value='achtergrondstraal'/> <cd:constant name='backgroundscreen' value='achtergrondraster'/> + <cd:constant name='backreference' value='terugreferentie'/> <cd:constant name='backspace' value='rugwit'/> <cd:constant name='balance' value='balanceren'/> <cd:constant name='before' value='voor'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interactie'/> <cd:constant name='interlinespace' value='interlinie'/> + <cd:constant name='internalgrid' value='interngrid'/> <cd:constant name='itemalign' value='itemuitlijnen'/> <cd:constant name='items' value='items'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-pe.xml b/tex/context/interface/keys-pe.xml index 0cb1f8a70..22148fd09 100644 --- a/tex/context/interface/keys-pe.xml +++ b/tex/context/interface/keys-pe.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='آفستپسزمینه'/> <cd:constant name='backgroundradius' value='شعاعپسزمینه'/> <cd:constant name='backgroundscreen' value='پردهپسزمینه'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='فضایپس'/> <cd:constant name='balance' value='تعادل'/> <cd:constant name='before' value='قبلاز'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='پانل'/> <cd:constant name='interlinespace' value='فضایبینخط'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='تنظیمآیتم'/> <cd:constant name='items' value='آیتمها'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml index 8665521df..c529e10de 100644 --- a/tex/context/interface/keys-ro.xml +++ b/tex/context/interface/keys-ro.xml @@ -560,6 +560,7 @@ <cd:constant name='backgroundoffset' value='offsetfundal'/> <cd:constant name='backgroundradius' value='razafundal'/> <cd:constant name='backgroundscreen' value='ecranfundal'/> + <cd:constant name='backreference' value='backreference'/> <cd:constant name='backspace' value='spatiuspate'/> <cd:constant name='balance' value='balanta'/> <cd:constant name='before' value='inainte'/> @@ -709,6 +710,7 @@ <cd:constant name='intent' value='intent'/> <cd:constant name='interaction' value='interactiune'/> <cd:constant name='interlinespace' value='spatiereinterliniara'/> + <cd:constant name='internalgrid' value='internalgrid'/> <cd:constant name='itemalign' value='itemalign'/> <cd:constant name='items' value='elemente'/> <cd:constant name='juniorsep' value='juniorsep'/> diff --git a/tex/context/test/pdf-x-common.mkiv b/tex/context/test/pdf-x-common.mkiv index dcea03a66..ac514c50d 100644 --- a/tex/context/test/pdf-x-common.mkiv +++ b/tex/context/test/pdf-x-common.mkiv @@ -1,4 +1,4 @@ -\showlayoutcomponents \nopdfcompression +\showlayoutcomponents % \nopdfcompression \setupinteraction [title=TITLE, diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 7b3efea0d..f2a22d983 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 08/10/10 17:14:16 +-- merge date : 08/19/10 01:08:29 do -- begin closure to overcome local limits and interference @@ -12,6 +12,7 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } +local string = string local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower local lpegmatch = lpeg.match @@ -171,18 +172,6 @@ end string.padd = string.rpadd -function is_number(str) -- tonumber - return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1 -end - ---~ print(is_number("1")) ---~ print(is_number("1.1")) ---~ print(is_number(".1")) ---~ print(is_number("-0.1")) ---~ print(is_number("+0.1")) ---~ print(is_number("-.1")) ---~ print(is_number("+.1")) - function string:split_settings() -- no {} handling, see l-aux for lpeg variant if find(self,"=") then local t = { } @@ -568,10 +557,11 @@ if not modules then modules = { } end modules ['l-boolean'] = { license = "see context related readme files" } -boolean = boolean or { } - local type, tonumber = type, tonumber +boolean = boolean or { } +local boolean = boolean + function boolean.tonumber(b) if b then return 1 else return 0 end end @@ -674,12 +664,10 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -table.join = table.concat - +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match local getmetatable, setmetatable = getmetatable, setmetatable -local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs -- Starting with version 5.2 Lua no longer provide ipairs, which makes -- sense. As we already used the for loop and # in most places the @@ -1626,12 +1614,15 @@ if not modules then modules = { } end modules ['l-file'] = { -- needs a cleanup file = file or { } +local file = file local insert, concat = table.insert, table.concat local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char local lpegmatch = lpeg.match local getcurrentdir = lfs.currentdir +local P, R, S, C, Cs, Cp, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc + local function dirname(name,default) return match(name,"^(.+)[/\\].-$") or (default or "") end @@ -1902,31 +1893,31 @@ end -- lpeg variants, slightly faster, not always ---~ local period = lpeg.P(".") ---~ local slashes = lpeg.S("\\/") +--~ local period = P(".") +--~ local slashes = S("\\/") --~ local noperiod = 1-period --~ local noslashes = 1-slashes --~ local name = noperiod^1 ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * C(noperiod^1) * -1 --~ function file.extname(name) --~ return lpegmatch(pattern,name) or "" --~ end ---~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) +--~ local pattern = Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) --~ return lpegmatch(pattern,name) --~ end ---~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 +--~ local pattern = (noslashes^0 * slashes)^1 * C(noslashes^1) * -1 --~ function file.basename(name) --~ return lpegmatch(pattern,name) or name --~ end ---~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^1 * Cp() * noslashes^1 * -1 --~ function file.dirname(name) --~ local p = lpegmatch(pattern,name) @@ -1937,7 +1928,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) --~ local p = lpegmatch(pattern,name) @@ -1948,7 +1939,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) --~ local p = lpegmatch(pattern,name) @@ -1959,7 +1950,7 @@ end --~ end --~ end ---~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 +--~ local pattern = (noslashes^0 * slashes)^0 * Cp() * ((noperiod^1 * period)^1 * Cp() + P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) --~ local a, b = lpegmatch(pattern,name) @@ -1991,11 +1982,11 @@ end -- also rewrite previous -local letter = lpeg.R("az","AZ") + lpeg.S("_-+") -local separator = lpeg.P("://") +local letter = R("az","AZ") + S("_-+") +local separator = P("://") -local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/") -local rootbased = lpeg.P("/") + letter*lpeg.P(":") +local qualified = P(".")^0 * P("/") + letter*P(":") + letter^1*separator + letter^1 * P("/") +local rootbased = P("/") + letter*P(":") -- ./name ../name /name c: :// name/name @@ -2007,14 +1998,16 @@ function file.is_rootbased_path(filename) return lpegmatch(rootbased,filename) ~= nil end -local slash = lpeg.S("\\/") -local period = lpeg.P(".") -local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":") -local path = lpeg.C(((1-slash)^0 * slash)^0) -local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1)) -local base = lpeg.C((1-suffix)^0) +-- actually these are schemes -local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) +local slash = S("\\/") +local period = P(".") +local drive = C(R("az","AZ")) * P(":") +local path = C(((1-slash)^0 * slash)^0) +local suffix = period * C(P(1-period)^0 * P(-1)) +local base = C((1-suffix)^0) + +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) function file.splitname(str) -- returns drive, path, base, suffix return lpegmatch(pattern,str) @@ -2048,7 +2041,9 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte, find, gsub = string.byte, string.find, string.gsub +local io = io +local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format +local concat = table.concat if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -2059,9 +2054,7 @@ end function io.loaddata(filename,textmode) local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- collectgarbage("step") -- sometimes makes a big difference in mem consumption local data = f:read('*all') - -- garbagecollector.check(data) f:close() return data else @@ -2073,7 +2066,7 @@ function io.savedata(filename,data,joiner) local f = io.open(filename,"wb") if f then if type(data) == "table" then - f:write(table.join(data,joiner or "")) + f:write(concat(data,joiner or "")) elseif type(data) == "function" then data(f) else @@ -2199,12 +2192,12 @@ function io.ask(question,default,options) while true do io.write(question) if options then - io.write(string.format(" [%s]",table.concat(options,"|"))) + io.write(format(" [%s]",concat(options,"|"))) end if default then - io.write(string.format(" [%s]",default)) + io.write(format(" [%s]",default)) end - io.write(string.format(" ")) + io.write(format(" ")) local answer = io.read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then @@ -2304,12 +2297,6 @@ logs = { report = dummyfunction, simple = dummyfunction, } -tasks = { -- no longer needed - new = dummyfunction, - actions = dummyfunction, - appendaction = dummyfunction, - prependaction = dummyfunction, -} callbacks = { register = function(n,f) return callback.register(n,f) end, } @@ -2485,8 +2472,8 @@ table structures without bothering about the disk cache.</p> <p>Examples of usage can be found in the font related code.</p> --ldx]]-- -containers = containers or { } - +containers = containers or { } +local containers = containers containers.usecache = true local report_cache = logs.new("cache") @@ -2609,12 +2596,24 @@ nodes = nodes or { } fonts = fonts or { } attributes = attributes or { } +nodes.pool = nodes.pool or { } +nodes.handlers = nodes.handlers or { } + +local nodecodes = { } for k,v in next, node.types () do nodecodes[string.gsub(v,"_","")] = k end +local whatcodes = { } for k,v in next, node.whatsits() do whatcodes[string.gsub(v,"_","")] = k end +local glyphcodes = { [0] = "character", "glyph", "ligature", "ghost", "left", "right" } + +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes +nodes.whatsitcodes = whatcodes +nodes.glyphcodes = glyphcodes + local traverse_id = node.traverse_id local free_node = node.free local remove_node = node.remove local new_node = node.new -local glyph = node.id('glyph') +local glyph_code = nodecodes.glyph -- fonts @@ -2622,9 +2621,9 @@ local fontdata = fonts.ids or { } function nodes.simple_font_handler(head) -- lang.hyphenate(head) - head = nodes.process_characters(head) - nodes.inject_kerns(head) - nodes.protect_glyphs(head) + head = nodes.handlers.characters(head) + nodes.handlers.injectkerns(head) + nodes.handlers.protectglyphs(head) head = node.ligaturing(head) head = node.kerning(head) return head @@ -2642,45 +2641,47 @@ if tex.attribute[0] ~= 0 then end -nodes.protect_glyphs = node.protect_glyphs -nodes.unprotect_glyphs = node.unprotect_glyphs - -function nodes.process_characters(head) - local usedfonts, done, prevfont = { }, false, nil - for n in traverse_id(glyph,head) do - local font = n.font - if font ~= prevfont then - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - done = true +nodes.handlers.protectglyphs = node.protect_glyphs +nodes.handlers.unprotectglyphs = node.unprotect_glyphs + +nodes.characters = { + handler = function (head) + local usedfonts, done, prevfont = { }, false, nil + for n in traverse_id(glyph_code,head) do + local font = n.font + if font ~= prevfont then + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + done = true + end end end end end end - end - if done then - for font, processors in next, usedfonts do - for i=1,#processors do - local h, d = processors[i](head,font,0) - head, done = h or head, done or d + if done then + for font, processors in next, usedfonts do + for i=1,#processors do + local h, d = processors[i](head,font,0) + head, done = h or head, done or d + end end end + return head, true end - return head, true -end +} -- helper -function nodes.kern(k) +function nodes.pool.kern(k) local n = new_node("kern",1) n.kern = k return n @@ -2750,14 +2751,17 @@ local trace_injections = false trackers.register("nodes.injections", function(v local report_injections = logs.new("injections") +local attributes, nodes, node = attributes, nodes, node + fonts = fonts or { } fonts.tfm = fonts.tfm or { } fonts.ids = fonts.ids or { } -local fontdata = fonts.ids - -local glyph = node.id('glyph') -local kern = node.id('kern') +local fontdata = fonts.ids +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local nodepool = nodes.pool +local newkern = nodepool.kern local traverse_id = node.traverse_id local unset_attribute = node.unset_attribute @@ -2766,8 +2770,6 @@ local set_attribute = node.set_attribute local insert_node_before = node.insert_before local insert_node_after = node.insert_after -local newkern = nodes.kern - local markbase = attributes.private('markbase') local markmark = attributes.private('markmark') local markdone = attributes.private('markdone') @@ -2852,12 +2854,13 @@ function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, m return dx, dy, bound end +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end + function nodes.trace_injection(head) - local function dir(n) - return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or ("unset") - end report_injections("begin run") - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then local kp = has_attribute(n,kernpair) local mb = has_attribute(n,markbase) @@ -2906,7 +2909,7 @@ end -- todo: reuse tables (i.e. no collection), but will be extra fields anyway -- todo: check for attribute -function nodes.inject_kerns(head,where,keep) +function nodes.handlers.injectkerns(head,where,keep) local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns) if has_marks or has_cursives then --~ if has_marks or has_cursives or has_kerns then @@ -2917,7 +2920,7 @@ function nodes.inject_kerns(head,where,keep) local done, ky, rl, valid, cx, wx, mk = false, { }, { }, { }, { }, { }, { } if has_kerns then -- move outside loop local nf, tm = nil, nil - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then valid[#valid+1] = n if n.font ~= nf then @@ -2945,7 +2948,7 @@ function nodes.inject_kerns(head,where,keep) end else local nf, tm = nil, nil - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then valid[#valid+1] = n if n.font ~= nf then @@ -3038,7 +3041,7 @@ function nodes.inject_kerns(head,where,keep) local p_markbase = has_attribute(p,markbase) if p_markbase then local mrks = marks[p_markbase] - for n in traverse_id(glyph,p.next) do + for n in traverse_id(glyph_code,p.next) do local n_markmark = has_attribute(n,markmark) if p_markbase == n_markmark then local index = has_attribute(n,markdone) or 1 @@ -3117,7 +3120,7 @@ function nodes.inject_kerns(head,where,keep) if trace_injections then nodes.trace_injection(head) end - for n in traverse_id(glyph,head) do + for n in traverse_id(glyph_code,head) do if n.subtype < 256 then local k = has_attribute(n,kernpair) if k then @@ -3189,8 +3192,6 @@ local lower = string.lower local report_define = logs.new("define fonts") -if not fontloader then fontloader = fontforge end - fontloader.totable = fontloader.to_table -- vtf comes first @@ -3205,6 +3206,10 @@ fonts.chr = fonts.chr or { } fonts.characters = fonts.chr -- aka chardata fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata fonts.tfm = fonts.tfm or { } +fonts.vf = fonts.vf or { } +fonts.afm = fonts.afm or { } +fonts.pfb = fonts.pfb or { } +fonts.otf = fonts.otf or { } fonts.private = 0xF0000 -- 0x10FFFF fonts.verbose = false -- more verbose cache tables @@ -3301,23 +3306,23 @@ local report_define = logs.new("define fonts") <p>Here we only implement a few helper functions.</p> --ldx]]-- -fonts = fonts or { } -fonts.tfm = fonts.tfm or { } -fonts.ids = fonts.ids or { } - -local tfm = fonts.tfm +local fonts = fonts +local tfm = fonts.tfm -fonts.loaded = fonts.loaded or { } +fonts.loaded = fonts.loaded or { } fonts.dontembed = fonts.dontembed or { } -fonts.triggers = fonts.triggers or { } -- brrr -fonts.initializers = fonts.initializers or { } +fonts.triggers = fonts.triggers or { } -- brrr +fonts.initializers = fonts.initializers or { } fonts.initializers.common = fonts.initializers.common or { } -local fontdata = fonts.ids -local disc = node.id('disc') -local glyph = node.id('glyph') local set_attribute = node.set_attribute +local fontdata = fonts.ids +local nodecodes = nodes.nodecodes + +local disc_code = nodecodes.disc +local glyph_code = nodecodes.glyph + --[[ldx-- <p>The next function encapsulates the standard <l n='tfm'/> loader as supplied by <l n='luatex'/>.</p> @@ -3940,7 +3945,7 @@ function fonts.analyzers.aux.setstate(head,font) local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean while current do local id = current.id - if id == glyph and current.font == font then + if id == glyph_code and current.font == font then local d = descriptions[current.char] if d then if d.class == "mark" then @@ -3961,7 +3966,7 @@ function fonts.analyzers.aux.setstate(head,font) end first, last, n = nil, nil, 0 end - elseif id == disc then + elseif id == disc_code then -- always in the middle set_attribute(current,state,2) -- midi last = current @@ -4043,11 +4048,12 @@ local trace_loading = false trackers.register("otf.loading", function(v) t local report_otf = logs.new("load otf") -fonts = fonts or { } -fonts.cid = fonts.cid or { } -fonts.cid.map = fonts.cid.map or { } -fonts.cid.max = fonts.cid.max or 10 +local fonts = fonts +fonts.cid = fonts.cid or { } +local cid = fonts.cid +cid.map = cid.map or { } +cid.max = cid.max or 10 -- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap -- @@ -4056,12 +4062,14 @@ fonts.cid.max = fonts.cid.max or 10 -- 1..95 0020 -- 99 3000 -local number = lpeg.C(lpeg.R("09","af","AF")^1) -local space = lpeg.S(" \n\r\t") +local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C + +local number = C(R("09","af","AF")^1) +local space = S(" \n\r\t") local spaces = space^0 -local period = lpeg.P(".") +local period = P(".") local periods = period * period -local name = lpeg.P("/") * lpeg.C((1-space)^1) +local name = P("/") * C((1-space)^1) local unicodes, names = { }, { } @@ -4089,7 +4097,7 @@ local grammar = lpeg.P { "start", named = (number * spaces * name) / do_name } -function fonts.cid.load(filename) +function cid.load(filename) local data = io.loaddata(filename) if data then unicodes, names = { }, { } @@ -4110,23 +4118,22 @@ end local template = "%s-%s-%s.cidmap" - local function locate(registry,ordering,supplement) local filename = format(template,registry,ordering,supplement) local hashname = lower(filename) - local cidmap = fonts.cid.map[hashname] + local cidmap = cid.map[hashname] if not cidmap then if trace_loading then report_otf("checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename) end local fullname = resolvers.find_file(filename,'cid') or "" if fullname ~= "" then - cidmap = fonts.cid.load(fullname) + cidmap = cid.load(fullname) if cidmap then if trace_loading then report_otf("using cidmap file %s",filename) end - fonts.cid.map[hashname] = cidmap + cid.map[hashname] = cidmap cidmap.usedname = file.basename(filename) return cidmap end @@ -4135,7 +4142,7 @@ local function locate(registry,ordering,supplement) return cidmap end -function fonts.cid.getmap(registry,ordering,supplement) +function cid.getmap(registry,ordering,supplement) -- cf Arthur R. we can safely scan upwards since cids are downward compatible local supplement = tonumber(supplement) if trace_loading then @@ -4145,8 +4152,8 @@ function fonts.cid.getmap(registry,ordering,supplement) if not cidmap then local cidnum = nil -- next highest (alternatively we could start high) - if supplement < fonts.cid.max then - for supplement=supplement+1,fonts.cid.max do + if supplement < cid.max then + for supplement=supplement+1,cid.max do local c = locate(registry,ordering,supplement) if c then cidmap, cidnum = c, supplement @@ -4168,8 +4175,8 @@ function fonts.cid.getmap(registry,ordering,supplement) if cidmap and cidnum > 0 then for s=0,cidnum-1 do filename = format(template,registry,ordering,s) - if not fonts.cid.map[filename] then - fonts.cid.map[filename] = cidmap -- copy of ref + if not cid.map[filename] then + cid.map[filename] = cidmap -- copy of ref end end end @@ -4190,17 +4197,20 @@ if not modules then modules = { } end modules ['font-otf'] = { } local type, next, tonumber, tostring = type, next, tonumber, tostring -local gsub, lower = string.gsub, string.lower +local gsub, lower, format = string.gsub, string.lower, string.format +local is_boolean = string.is_boolean -fonts = fonts or { } -fonts.otf = fonts.otf or { } +local fonts = fonts +fonts.otf = fonts.otf or { } +local otf = fonts.otf -local otf = fonts.otf +otf.tables = otf.tables or { } +local tables = otf.tables -otf.tables = otf.tables or { } -otf.meanings = otf.meanings or { } +otf.meanings = otf.meanings or { } +local meanings = otf.meanings -otf.tables.scripts = { +local scripts = { ['dflt'] = 'Default', ['arab'] = 'Arabic', @@ -4273,7 +4283,7 @@ otf.tables.scripts = { ['yi' ] = 'Yi', } -otf.tables.languages = { +local languages = { ['dflt'] = 'Default', ['aba'] = 'Abaza', @@ -4667,7 +4677,7 @@ otf.tables.languages = { ['zul'] = 'Zulu' } -otf.tables.features = { +local features = { ['aalt'] = 'Access All Alternates', ['abvf'] = 'Above-Base Forms', ['abvm'] = 'Above-Base Mark Positioning', @@ -4805,7 +4815,7 @@ otf.tables.features = { ['tlig'] = 'Traditional TeX Ligatures', } -otf.tables.baselines = { +local baselines = { ['hang'] = 'Hanging baseline', ['icfb'] = 'Ideographic character face bottom edge baseline', ['icft'] = 'Ideographic character face tope edige baseline', @@ -4815,10 +4825,33 @@ otf.tables.baselines = { ['romn'] = 'Roman baseline' } +local to_scripts = table.reverse_hash(scripts ) +local to_languages = table.reverse_hash(languages) +local to_features = table.reverse_hash(features ) + +tables.scripts = scripts +tables.languages = languages +tables.features = features +tables.baselines = baselines + +tables.to_scripts = to_scripts +tables.to_languages = to_languages +tables.to_features = to_features + +for k, v in next, to_features do + local stripped = gsub(k,"%-"," ") + to_features[stripped] = v + local stripped = gsub(k,"[^a-zA-Z0-9]","") + to_features[stripped] = v +end +for k, v in next, to_features do + to_features[lower(k)] = v +end + -- can be sped up by local tables -function otf.tables.to_tag(id) - return stringformat("%4s",lower(id)) +function tables.to_tag(id) + return format("%4s",lower(id)) end local function resolve(tab,id) @@ -4830,50 +4863,20 @@ local function resolve(tab,id) end end -function otf.meanings.script(id) - return resolve(otf.tables.scripts,id) -end -function otf.meanings.language(id) - return resolve(otf.tables.languages,id) -end -function otf.meanings.feature(id) - return resolve(otf.tables.features,id) -end -function otf.meanings.baseline(id) - return resolve(otf.tables.baselines,id) -end - -otf.tables.to_scripts = table.reverse_hash(otf.tables.scripts ) -otf.tables.to_languages = table.reverse_hash(otf.tables.languages) -otf.tables.to_features = table.reverse_hash(otf.tables.features ) - -local scripts = otf.tables.scripts -local languages = otf.tables.languages -local features = otf.tables.features - -local to_scripts = otf.tables.to_scripts -local to_languages = otf.tables.to_languages -local to_features = otf.tables.to_features +function meanings.script (id) return resolve(scripts, id) end +function meanings.language(id) return resolve(languages,id) end +function meanings.feature (id) return resolve(features, id) end +function meanings.baseline(id) return resolve(baselines,id) end -for k, v in next, to_features do - local stripped = gsub(k,"%-"," ") - to_features[stripped] = v - local stripped = gsub(k,"[^a-zA-Z0-9]","") - to_features[stripped] = v -end -for k, v in next, to_features do - to_features[lower(k)] = v -end - -otf.meanings.checkers = { +local checkers = { rand = function(v) return v and "random" end } -local checkers = otf.meanings.checkers +meanings.checkers = checkers -function otf.meanings.normalize(features) +function meanings.normalize(features) if features then local h = { } for k,v in next, features do @@ -4894,7 +4897,7 @@ function otf.meanings.normalize(features) end else if type(v) == "string" then - local b = v:is_boolean() + local b = is_boolean(v) if type(b) == "nil" then v = tonumber(v) or lower(v) else @@ -4912,7 +4915,7 @@ end -- When I feel the need ... ---~ otf.tables.aat = { +--~ tables.aat = { --~ [ 0] = { --~ name = "allTypographicFeaturesType", --~ [ 0] = "allTypeFeaturesOnSelector", @@ -5169,8 +5172,8 @@ of obsolete. Some code may move to runtime or auxiliary modules.</p> <p>The name to unciode related code will stay of course.</p> --ldx]]-- -fonts = fonts or { } -fonts.map = fonts.map or { } +local fonts = fonts +fonts.map = fonts.map or { } local function load_lum_table(filename) -- will move to font goodies local lumname = file.replacesuffix(file.basename(filename),"lum") @@ -5184,15 +5187,16 @@ local function load_lum_table(filename) -- will move to font goodies end end -local hex = lpeg.R("AF","09") +local P, R, S, C, Ct, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc + +local hex = R("AF","09") local hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end local hexsix = (hex^1) / function(s) return tonumber(s,16) end -local dec = (lpeg.R("09")^1) / tonumber -local period = lpeg.P(".") - -local unicode = lpeg.P("uni") * (hexfour * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexfour^1) * lpeg.Cc(true)) -local ucode = lpeg.P("u") * (hexsix * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexsix ^1) * lpeg.Cc(true)) -local index = lpeg.P("index") * dec * lpeg.Cc(false) +local dec = (R("09")^1) / tonumber +local period = P(".") +local unicode = P("uni") * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) +local ucode = P("u") * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) +local index = P("index") * dec * Cc(false) local parser = unicode + ucode + index @@ -5204,7 +5208,7 @@ local function make_name_parser(str) else local p = parsers[str] if not p then - p = lpeg.P(str) * period * dec * lpeg.Cc(false) + p = P(str) * period * dec * Cc(false) parsers[str] = p end return p @@ -5271,9 +5275,9 @@ fonts.map.make_name_parser = make_name_parser fonts.map.tounicode16 = tounicode16 fonts.map.tounicode16sequence = tounicode16sequence -local separator = lpeg.S("_.") -local other = lpeg.C((1 - separator)^1) -local ligsplitter = lpeg.Ct(other * (separator * other)^0) +local separator = S("_.") +local other = C((1 - separator)^1) +local ligsplitter = Ct(other * (separator * other)^0) --~ print(table.serialize(lpegmatch(ligsplitter,"this"))) --~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) @@ -5584,26 +5588,26 @@ involved is not that large. This only makes sense when we have many fonts in a l and don't change to frequently.</p> --ldx]]-- -fonts = fonts or { } -fonts.otf = fonts.otf or { } -fonts.tfm = fonts.tfm or { } +local fonts = fonts +fonts.otf = fonts.otf or { } local otf = fonts.otf local tfm = fonts.tfm local fontdata = fonts.ids -otf.tables = otf.tables or { } -- defined in font-ott.lua -otf.meanings = otf.meanings or { } -- defined in font-ott.lua -otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua -otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua -otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua +--~ otf.tables = otf.tables or { } -- defined in font-ott.lua +--~ otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua +--~ otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua +--~ otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua otf.features = otf.features or { } otf.features.list = otf.features.list or { } otf.features.default = otf.features.default or { } -otf.enhancers = otf.enhancers or { } +otf.enhancers = otf.enhancers or { } +local enhancers = otf.enhancers + otf.glists = { "gsub", "gpos" } otf.version = 2.653 -- beware: also sync font-mis.lua @@ -5620,6 +5624,8 @@ local default = "dflt" <p>We start with a lot of tables and related functions.</p> --ldx]]-- +-- we can have more local functions + otf.tables.global_fields = table.tohash { "lookups", "glyphs", @@ -5714,8 +5720,8 @@ local function load_featurefile(ff,featurefile) end end -function otf.enhance(name,data,filename,verbose) - local enhancer = otf.enhancers[name] +local function enhance(name,data,filename,verbose) + local enhancer = enhancers[name] if enhancer then if (verbose ~= nil and verbose) or trace_loading then report_otf("enhance: %s (%s)",name,filename) @@ -5724,7 +5730,7 @@ function otf.enhance(name,data,filename,verbose) end end -local enhancers = { +local ordered_enhancers = { -- implemented later -- pack and unpack are handled separately; they might even be moved -- away from the enhancers namespace "patch bugs", @@ -5744,6 +5750,8 @@ local enhancers = { "check math parameters", } +local add_dimensions, show_feature_order -- implemented later + function otf.load(filename,format,sub,featurefile) local name = file.basename(file.removesuffix(filename)) local attr = lfs.attributes(filename) @@ -5784,12 +5792,12 @@ function otf.load(filename,format,sub,featurefile) if data then report_otf("file size: %s", size) report_otf("enhancing ...") - for e=1,#enhancers do - otf.enhance(enhancers[e],data,filename) + for e=1,#ordered_enhancers do + enhance(ordered_enhancers[e],data,filename) io.flush() -- we want instant messages end if otf.pack and not fonts.verbose then - otf.enhance("pack",data,filename) + enhance("pack",data,filename) end data.size = size data.time = time @@ -5810,16 +5818,16 @@ function otf.load(filename,format,sub,featurefile) if trace_defining then report_otf("loading from cache: %s",hash) end - otf.enhance("unpack",data,filename,false) -- no message here - otf.add_dimensions(data) + enhance("unpack",data,filename,false) -- no message here + add_dimensions(data) if trace_sequences then - otf.show_feature_order(data,filename) + show_feature_order(data,filename) end end return data end -function otf.add_dimensions(data) +add_dimensions = function(data) -- todo: forget about the width if it's the defaultwidth (saves mem) -- we could also build the marks hash here (instead of storing it) if data then @@ -5855,7 +5863,7 @@ function otf.add_dimensions(data) end end -function otf.show_feature_order(otfdata,filename) +local function show_feature_order(otfdata,filename) local sequences = otfdata.luatex.sequences if sequences and #sequences > 0 then if trace_loading then @@ -5897,7 +5905,7 @@ end -- todo: normalize, design_size => designsize -otf.enhancers["reorganize mark classes"] = function(data,filename) +enhancers["reorganize mark classes"] = function(data,filename) if data.mark_classes then local unicodes = data.luatex.unicodes local reverse = { } @@ -5920,7 +5928,7 @@ otf.enhancers["reorganize mark classes"] = function(data,filename) end end -otf.enhancers["prepare luatex tables"] = function(data,filename) +enhancers["prepare luatex tables"] = function(data,filename) data.luatex = data.luatex or { } local luatex = data.luatex luatex.filename = filename @@ -5928,7 +5936,7 @@ otf.enhancers["prepare luatex tables"] = function(data,filename) luatex.creator = "context mkiv" end -otf.enhancers["cleanup aat"] = function(data,filename) +enhancers["cleanup aat"] = function(data,filename) if otf.cleanup_aat then end end @@ -5956,13 +5964,13 @@ local function analyze_features(g, features) return nil end -otf.enhancers["analyse features"] = function(data,filename) +enhancers["analyse features"] = function(data,filename) -- local luatex = data.luatex -- luatex.gposfeatures = analyze_features(data.gpos) -- luatex.gsubfeatures = analyze_features(data.gsub) end -otf.enhancers["rehash features"] = function(data,filename) +enhancers["rehash features"] = function(data,filename) local features = { } data.luatex.features = features for k, what in next, otf.glists do @@ -5993,7 +6001,7 @@ otf.enhancers["rehash features"] = function(data,filename) end end -otf.enhancers["analyse anchors"] = function(data,filename) +enhancers["analyse anchors"] = function(data,filename) local classes = data.anchor_classes local luatex = data.luatex local anchor_to_lookup, lookup_to_anchor = { }, { } @@ -6019,7 +6027,7 @@ otf.enhancers["analyse anchors"] = function(data,filename) end end -otf.enhancers["analyse marks"] = function(data,filename) +enhancers["analyse marks"] = function(data,filename) local glyphs = data.glyphs local marks = { } data.luatex.marks = marks @@ -6031,9 +6039,9 @@ otf.enhancers["analyse marks"] = function(data,filename) end end -otf.enhancers["analyse unicodes"] = fonts.map.add_to_unicode +enhancers["analyse unicodes"] = fonts.map.add_to_unicode -otf.enhancers["analyse subtables"] = function(data,filename) +enhancers["analyse subtables"] = function(data,filename) data.luatex = data.luatex or { } local luatex = data.luatex local sequences = { } @@ -6101,7 +6109,7 @@ otf.enhancers["analyse subtables"] = function(data,filename) end end -otf.enhancers["merge cid fonts"] = function(data,filename) +enhancers["merge cid fonts"] = function(data,filename) -- we can also move the names to data.luatex.names which might -- save us some more memory (at the cost of harder tracing) if data.subfonts then @@ -6155,7 +6163,7 @@ otf.enhancers["merge cid fonts"] = function(data,filename) end end -otf.enhancers["prepare unicode"] = function(data,filename) +enhancers["prepare unicode"] = function(data,filename) local luatex = data.luatex if not luatex then luatex = { } data.luatex = luatex end local indices, unicodes, multiples, internals = { }, { }, { }, { } @@ -6238,7 +6246,7 @@ otf.enhancers["prepare unicode"] = function(data,filename) luatex.private = private end -otf.enhancers["cleanup ttf tables"] = function(data,filename) +enhancers["cleanup ttf tables"] = function(data,filename) local ttf_tables = data.ttf_tables if ttf_tables then for k=1,#ttf_tables do @@ -6248,7 +6256,7 @@ otf.enhancers["cleanup ttf tables"] = function(data,filename) data.ttf_tab_saved = nil end -otf.enhancers["compact glyphs"] = function(data,filename) +enhancers["compact glyphs"] = function(data,filename) table.compact(data.glyphs) -- needed? if data.subfonts then for _, subfont in next, data.subfonts do @@ -6257,7 +6265,7 @@ otf.enhancers["compact glyphs"] = function(data,filename) end end -otf.enhancers["reverse coverage"] = function(data,filename) +enhancers["reverse coverage"] = function(data,filename) -- we prefer the before lookups in a normal order if data.lookups then for _, v in next, data.lookups do @@ -6273,7 +6281,7 @@ otf.enhancers["reverse coverage"] = function(data,filename) end end -otf.enhancers["check italic correction"] = function(data,filename) +enhancers["check italic correction"] = function(data,filename) local glyphs = data.glyphs local ok = false for index, glyph in next, glyphs do @@ -6291,7 +6299,7 @@ otf.enhancers["check italic correction"] = function(data,filename) data.has_italic = true end -otf.enhancers["check math"] = function(data,filename) +enhancers["check math"] = function(data,filename) if data.math then -- we move the math stuff into a math subtable because we then can -- test faster in the tfm copy @@ -6358,7 +6366,7 @@ otf.enhancers["check math"] = function(data,filename) end end -otf.enhancers["share widths"] = function(data,filename) +enhancers["share widths"] = function(data,filename) local glyphs = data.glyphs local widths = { } for index, glyph in next, glyphs do @@ -6392,7 +6400,7 @@ end -- unpredictable alternatively we could force an [1] if not set (maybe I will do that -- anyway). ---~ otf.enhancers["reorganize kerns"] = function(data,filename) +--~ enhancers["reorganize kerns"] = function(data,filename) --~ local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes --~ local mkdone = false --~ for index, glyph in next, glyphs do @@ -6532,7 +6540,7 @@ end --~ end --~ end -otf.enhancers["reorganize kerns"] = function(data,filename) +enhancers["reorganize kerns"] = function(data,filename) local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes local mkdone = false local function do_it(lookup,first_unicode,kerns) @@ -6676,15 +6684,7 @@ otf.enhancers["reorganize kerns"] = function(data,filename) end end - - - - - - - - -otf.enhancers["strip not needed data"] = function(data,filename) +enhancers["strip not needed data"] = function(data,filename) local verbose = fonts.verbose local int_to_uni = data.luatex.unicodes for k, v in next, data.glyphs do @@ -6726,7 +6726,7 @@ otf.enhancers["strip not needed data"] = function(data,filename) end end -otf.enhancers["migrate metadata"] = function(data,filename) +enhancers["migrate metadata"] = function(data,filename) local global_fields = otf.tables.global_fields local metadata = { } for k,v in next, data do @@ -6747,7 +6747,7 @@ local private_math_parameters = { "FractionDelimiterDisplayStyleSize", } -otf.enhancers["check math parameters"] = function(data,filename) +enhancers["check math parameters"] = function(data,filename) local mathdata = data.metadata.math if mathdata then for m=1,#private_math_parameters do @@ -6762,7 +6762,7 @@ otf.enhancers["check math parameters"] = function(data,filename) end end -otf.enhancers["flatten glyph lookups"] = function(data,filename) +enhancers["flatten glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do local lookups = v.lookups if lookups then @@ -6816,7 +6816,7 @@ otf.enhancers["flatten glyph lookups"] = function(data,filename) end end -otf.enhancers["simplify glyph lookups"] = function(data,filename) +enhancers["simplify glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do local lookups = v.lookups if lookups then @@ -6841,7 +6841,7 @@ otf.enhancers["simplify glyph lookups"] = function(data,filename) end end -otf.enhancers["flatten anchor tables"] = function(data,filename) +enhancers["flatten anchor tables"] = function(data,filename) for k, v in next, data.glyphs do if v.anchors then for kk, vv in next, v.anchors do @@ -6860,7 +6860,7 @@ otf.enhancers["flatten anchor tables"] = function(data,filename) end end -otf.enhancers["flatten feature tables"] = function(data,filename) +enhancers["flatten feature tables"] = function(data,filename) -- is this needed? do we still use them at all? for _, tag in next, otf.glists do if data[tag] then @@ -6886,11 +6886,11 @@ otf.enhancers["flatten feature tables"] = function(data,filename) end end -otf.enhancers.patches = otf.enhancers.patches or { } +enhancers.patches = enhancers.patches or { } -otf.enhancers["patch bugs"] = function(data,filename) +enhancers["patch bugs"] = function(data,filename) local basename = file.basename(lower(filename)) - for pattern, action in next, otf.enhancers.patches do + for pattern, action in next, enhancers.patches do if find(basename,pattern) then action(data,filename) end @@ -6899,7 +6899,7 @@ end -- tex features -fonts.otf.enhancers["enrich with features"] = function(data,filename) +enhancers["enrich with features"] = function(data,filename) -- later, ctx only end @@ -7322,13 +7322,11 @@ if not modules then modules = { } end modules ['font-otd'] = { license = "see context related readme files" } -local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end) +local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end) local report_otf = logs.new("load otf") -fonts = fonts or { } -fonts.otf = fonts.otf or { } - +local fonts = fonts local otf = fonts.otf local fontdata = fonts.ids @@ -7409,11 +7407,12 @@ if not modules then modules = { } end modules ['font-oti'] = { license = "see context related readme files" } --- i need to check features=yes|no also in relation to hashing - local lower = string.lower -local otf = fonts.otf +local fonts = fonts + +local otf = fonts.otf +local initializers = fonts.initializers otf.default_language = 'latn' otf.default_script = 'dflt' @@ -7421,7 +7420,7 @@ otf.default_script = 'dflt' local languages = otf.tables.languages local scripts = otf.tables.scripts -function otf.features.language(tfmdata,value) +local function set_language(tfmdata,value) if value then value = lower(value) if languages[value] then @@ -7430,7 +7429,7 @@ function otf.features.language(tfmdata,value) end end -function otf.features.script(tfmdata,value) +local function set_script(tfmdata,value) if value then value = lower(value) if scripts[value] then @@ -7439,21 +7438,24 @@ function otf.features.script(tfmdata,value) end end -function otf.features.mode(tfmdata,value) +local function set_mode(tfmdata,value) if value then tfmdata.mode = lower(value) end end -fonts.initializers.base.otf.language = otf.features.language -fonts.initializers.base.otf.script = otf.features.script -fonts.initializers.base.otf.mode = otf.features.mode -fonts.initializers.base.otf.method = otf.features.mode +local base_initializers = initializers.base.otf +local node_initializers = initializers.node.otf + +base_initializers.language = set_language +base_initializers.script = set_script +base_initializers.mode = set_mode +base_initializers.method = set_mode -fonts.initializers.node.otf.language = otf.features.language -fonts.initializers.node.otf.script = otf.features.script -fonts.initializers.node.otf.mode = otf.features.mode -fonts.initializers.node.otf.method = otf.features.mode +node_initializers.language = set_language +node_initializers.script = set_script +node_initializers.mode = set_mode +node_initializers.method = set_mode otf.features.register("features",true) -- we always do features table.insert(fonts.processors,"features") -- we need a proper function for doing this @@ -7476,8 +7478,9 @@ local format, gmatch, gsub, find, match, lower, strip = string.format, string.gm local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match -local otf = fonts.otf -local tfm = fonts.tfm +local fonts = fonts +local otf = fonts.otf +local tfm = fonts.tfm local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end) local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end) @@ -7514,7 +7517,7 @@ local function gref(descriptions,n) for j=1,#ni do local nj = ni[j] nnum[j] = format("U+%04X",nj) - nnam[j] = descriptions[nj].name or "?" + nnam[j] = descriptions[nj].name or "?" end num[i] = concat(nnum,"|") nam[i] = concat(nnam,"|") @@ -7982,6 +7985,8 @@ local format, gmatch, gsub, find, match, lower, strip = string.format, string.gm local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match +local logs, trackers, fonts, nodes, attributes = logs, trackers, fonts, nodes, attributes + local otf = fonts.otf local tfm = fonts.tfm @@ -8032,11 +8037,19 @@ local default = "dflt" local split_at_space = lpeg.splitters[" "] or lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway -local glyph = node.id('glyph') -local glue = node.id('glue') -local kern = node.id('kern') -local disc = node.id('disc') -local whatsit = node.id('whatsit') +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local glyphcodes = nodes.glyphcodes + +local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue +local disc_code = nodecodes.disc +local whatsit_code = nodecodes.whatsit + +local dir_code = whatcodes.dir +local localpar_code = whatcodes.localpar + +local ligature_code = glyphcodes.ligature local state = attributes.private('state') local markbase = attributes.private('markbase') @@ -8166,7 +8179,7 @@ local function markstoligature(kind,lookupname,start,stop,char) snext.prev = current end start.prev, stop.next = nil, nil - current.char, current.subtype, current.components = char, 2, start + current.char, current.subtype, current.components = char, ligature_code, start return keep end @@ -8176,16 +8189,16 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- --~ local lignode = copy_node(start) --~ lignode.font = start.font --~ lignode.char = char ---~ lignode.subtype = 2 +--~ lignode.subtype = ligature_code --~ start = node.do_ligature_n(start, stop, lignode) ---~ if start.id == disc then +--~ if start.id == disc_code then --~ local prev = start.prev --~ start = start.next --~ end if discfound then -- print("start->stop",nodes.tosequence(start,stop)) local lignode = copy_node(start) - lignode.font, lignode.char, lignode.subtype = start.font, char, 2 + lignode.font, lignode.char, lignode.subtype = start.font, char, ligature_code local next, prev = stop.next, start.prev stop.next = nil lignode = node.do_ligature_n(start, stop, lignode) @@ -8207,7 +8220,7 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- snext.prev = current end start.prev, stop.next = nil, nil - current.char, current.subtype, current.components = char, 2, start + current.char, current.subtype, current.components = char, ligature_code, start local head = current if deletemarks then if trace_marks then @@ -8233,7 +8246,7 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- start = start.next end start = current.next - while start and start.id == glyph do + while start and start.id == glyph_code do if marks[start.char] then set_attribute(start,markdone,i) if trace_marks then @@ -8328,7 +8341,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma if marks[startchar] then while s do local id = s.id - if id == glyph and s.subtype<256 then + if id == glyph_code and s.subtype<256 then if s.font == currentfont then local char = s.char local lg = ligature[1][char] @@ -8360,7 +8373,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma local skipmark = sequence.flags[1] while s do local id = s.id - if id == glyph and s.subtype<256 then + if id == glyph_code and s.subtype<256 then if s.font == currentfont then local char = s.char if skipmark and marks[char] then @@ -8378,7 +8391,7 @@ function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or ma else break end - elseif id == disc then + elseif id == disc_code then discfound = true s = s.next else @@ -8408,12 +8421,12 @@ function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence) local markchar = start.char if marks[markchar] then local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if not marks[basechar] then break @@ -8470,13 +8483,13 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence) if marks[markchar] then local base = start.prev -- [glyph] [optional marks] [start=mark] local index = 1 - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then index = index + 1 while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if marks[basechar] then index = index + 1 @@ -8540,7 +8553,7 @@ function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence) --~ local alreadydone = markonce and has_attribute(start,markmark) --~ if not alreadydone then local base = start.prev -- [glyph] [basemark] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go local basechar = base.char local baseanchors = descriptions[basechar] if baseanchors then @@ -8594,7 +8607,7 @@ function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to end else local nxt = start.next - while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + while not done and nxt and nxt.id == glyph_code and nxt.subtype<256 and nxt.font == currentfont do local nextchar = nxt.char if marks[nextchar] then -- should not happen (maybe warning) @@ -8657,9 +8670,9 @@ function handlers.gpos_pair(start,kind,lookupname,kerns,sequence) else local prev, done = start, false local factor = tfmdata.factor - while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do + while snext and snext.id == glyph_code and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char -local krn = kerns[nextchar] + local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext snext = snext.next @@ -8837,7 +8850,7 @@ function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,c local current = start local subtables = currentlookup.subtables while current do - if current.id == glyph then + if current.id == glyph_code then local currentchar = current.char local lookupname = subtables[1] local replacement = cache.gsub_single[lookupname] @@ -8925,7 +8938,7 @@ function chainprocs.gsub_alternate(start,stop,kind,chainname,currentcontext,cach local current = start local subtables = currentlookup.subtables while current do - if current.id == glyph then + if current.id == glyph_code then local currentchar = current.char local lookupname = subtables[1] local alternatives = cache.gsub_alternate[lookupname] @@ -8982,7 +8995,7 @@ function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache local s, discfound, last, nofreplacements = start.next, false, stop, 0 while s do local id = s.id - if id == disc then + if id == disc_code then s = s.next discfound = true else @@ -9043,12 +9056,12 @@ function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,cach end if markanchors then local base = start.prev -- [glyph] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if not marks[basechar] then break @@ -9108,13 +9121,13 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext, if markanchors then local base = start.prev -- [glyph] [optional marks] [start=mark] local index = 1 - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then local basechar = base.char if marks[basechar] then index = index + 1 while true do base = base.prev - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then basechar = base.char if marks[basechar] then index = index + 1 @@ -9184,7 +9197,7 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,cach end if markanchors then local base = start.prev -- [glyph] [basemark] [start=mark] - if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go + if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go local basechar = base.char local baseanchors = descriptions[basechar].anchors if baseanchors then @@ -9244,7 +9257,7 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache, end else local nxt = start.next - while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do + while not done and nxt and nxt.id == glyph_code and nxt.subtype<256 and nxt.font == currentfont do local nextchar = nxt.char if marks[nextchar] then -- should not happen (maybe warning) @@ -9324,7 +9337,7 @@ function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,cur if kerns then local prev, done = start, false local factor = tfmdata.factor - while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do + while snext and snext.id == glyph_code and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char local krn = kerns[nextchar] if not krn and marks[nextchar] then @@ -9412,7 +9425,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- f..l = mid string if s == 1 then -- never happens - match = current.id == glyph and current.subtype<256 and current.font == currentfont and seq[1][current.char] + match = current.id == glyph_code and current.subtype<256 and current.font == currentfont and seq[1][current.char] else -- todo: better space check (maybe check for glue) local f, l = ck[4], ck[5] @@ -9426,12 +9439,12 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence -- we cannot optimize for n=2 because there can be disc nodes -- if not someskip and n == l then -- -- n=2 and no skips then faster loop - -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and seq[n][last.char] + -- match = last and last.id == glyph_code and last.subtype<256 and last.font == currentfont and seq[n][last.char] -- else while n <= l do if last then local id = last.id - if id == glyph then + if id == glyph_code then if last.subtype<256 and last.font == currentfont then local char = last.char local ccd = descriptions[char] @@ -9457,7 +9470,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then -- what to do with kerns? + elseif id == disc_code then -- what to do with kerns? last = last.next else match = false break @@ -9476,7 +9489,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence while n >= 1 do if prev then local id = prev.id - if id == glyph then + if id == glyph_code then if prev.subtype<256 and prev.font == currentfont then -- normal char local char = prev.char local ccd = descriptions[char] @@ -9498,7 +9511,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then + elseif id == disc_code then -- skip 'm elseif seq[n][32] then n = n -1 @@ -9531,7 +9544,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence while n <= s do if current then local id = current.id - if id == glyph then + if id == glyph_code then if current.subtype<256 and current.font == currentfont then -- normal char local char = current.char local ccd = descriptions[char] @@ -9553,7 +9566,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence else match = false break end - elseif id == disc then + elseif id == disc_code then -- skip 'm elseif seq[n][32] then -- brrr n = n + 1 @@ -9855,7 +9868,7 @@ function fonts.methods.node.otf.features(head,font,attr) local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -9904,7 +9917,7 @@ function fonts.methods.node.otf.features(head,font,attr) else while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -9929,7 +9942,7 @@ function fonts.methods.node.otf.features(head,font,attr) else start = start.next end - -- elseif id == glue then + -- elseif id == glue_code then -- if p[5] then -- chain -- local pc = pp[32] -- if pc then @@ -9944,9 +9957,9 @@ function fonts.methods.node.otf.features(head,font,attr) -- else -- start = start.next -- end - elseif id == whatsit then + elseif id == whatsit_code then local subtype = start.subtype - if subtype == 7 then + if subtype == dir_code then local dir = start.dir if dir == "+TRT" or dir == "+TLT" then insert(txtdir,dir) @@ -9964,7 +9977,7 @@ function fonts.methods.node.otf.features(head,font,attr) if trace_directions then report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) end - elseif subtype == 6 then + elseif subtype == localpar_code then local dir = start.dir if dir == "TRT" then pardir = -1 @@ -9988,7 +10001,7 @@ function fonts.methods.node.otf.features(head,font,attr) else while start do local id = start.id - if id == glyph then + if id == glyph_code then if start.subtype<256 and start.font == font then local a = has_attribute(start,0) if a then @@ -10022,7 +10035,7 @@ function fonts.methods.node.otf.features(head,font,attr) else start = start.next end - -- elseif id == glue then + -- elseif id == glue_code then -- if p[5] then -- chain -- local pc = pp[32] -- if pc then @@ -10037,9 +10050,9 @@ function fonts.methods.node.otf.features(head,font,attr) -- else -- start = start.next -- end - elseif id == whatsit then + elseif id == whatsit_code then local subtype = start.subtype - if subtype == 7 then + if subtype == dir_code then local dir = start.dir if dir == "+TRT" or dir == "+TLT" then insert(txtdir,dir) @@ -10057,7 +10070,7 @@ function fonts.methods.node.otf.features(head,font,attr) if trace_directions then report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode) end - elseif subtype == 6 then + elseif subtype == localpar_code then local dir = start.dir if dir == "TRT" then pardir = -1 @@ -10570,34 +10583,37 @@ local trace_cjk = false trackers.register("cjk.injections", function(v) t trackers.register("cjk.analyzing","otf.analyzing") -fonts = fonts or { } -fonts.analyzers = fonts.analyzers or { } -fonts.analyzers.initializers = fonts.analyzers.initializers or { node = { otf = { } } } -fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } } +local fonts, nodes = fonts, nodes +local node = node local otf = fonts.otf local tfm = fonts.tfm -local initializers = fonts.analyzers.initializers -local methods = fonts.analyzers.methods +fonts.analyzers = fonts.analyzers or { } +local analyzers = fonts.analyzers + +analyzers.initializers = analyzers.initializers or { node = { otf = { } } } +analyzers.methods = analyzers.methods or { node = { otf = { } } } + +local initializers = analyzers.initializers +local methods = analyzers.methods -local glyph = node.id('glyph') -local glue = node.id('glue') -local penalty = node.id('penalty') +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph local set_attribute = node.set_attribute local has_attribute = node.has_attribute local traverse_id = node.traverse_id local traverse_node_list = node.traverse -local fontdata = fonts.ids -local state = attributes.private('state') +local fontdata = fonts.ids +local state = attributes.private('state') -local fcs = (fonts.color and fonts.color.set) or function() end -local fcr = (fonts.color and fonts.color.reset) or function() end +local fcs = (fonts.color and fonts.color.set) or function() end +local fcr = (fonts.color and fonts.color.reset) or function() end -local a_to_script = otf.a_to_script -local a_to_language = otf.a_to_language +local a_to_script = otf.a_to_script +local a_to_language = otf.a_to_language -- in the future we will use language/script attributes instead of the -- font related value, but then we also need dynamic features which is @@ -10651,7 +10667,7 @@ table.insert(fonts.triggers,"analyze") -- we need a proper function for doing t -- latin -fonts.analyzers.methods.latn = fonts.analyzers.aux.setstate +analyzers.methods.latn = analyzers.aux.setstate -- this info eventually will go into char-def @@ -10733,8 +10749,8 @@ local function warning(current,what) end end -function fonts.analyzers.methods.nocolor(head,font,attr) - for n in traverse_node_list(head,glyph) do +function analyzers.methods.nocolor(head,font,attr) + for n in traverse_id(glyph_code,head) do if not font or n.font == font then fcr(n) end @@ -10783,12 +10799,12 @@ local function finish(first,last) return first, last end -function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace +function analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace local tfmdata = fontdata[font] local marks = tfmdata.marks local first, last, current, done = nil, nil, head, false while current do - if current.id == glyph and current.subtype<256 and current.font == font and not has_attribute(current,state) then + if current.id == glyph_code and current.subtype<256 and current.font == font and not has_attribute(current,state) then done = true local char = current.char if marks[char] then @@ -10858,10 +10874,10 @@ local type, next = type, next local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) -local report_otf = logs.new("load otf") +local fonts = fonts +local otf = fonts.otf -local otf = fonts.otf -local tfm = fonts.tfm +local report_otf = logs.new("load otf") -- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to -- have always); some day we can write a "force always when true" trick for other @@ -10953,11 +10969,11 @@ local extra_features = { -- maybe just 1..n so that we prescribe order }, } -fonts.otf.enhancers["add some missing characters"] = function(data,filename) +otf.enhancers["add some missing characters"] = function(data,filename) -- todo end -fonts.otf.enhancers["enrich with features"] = function(data,filename) +otf.enhancers["enrich with features"] = function(data,filename) -- could be done elsewhere (true can be #) local used = { } for i=1,#otf.glists do @@ -11040,24 +11056,33 @@ fonts.otf.enhancers["enrich with features"] = function(data,filename) end end -otf.tables.features['tlig'] = 'TeX Ligatures' -otf.tables.features['trep'] = 'TeX Replacements' -otf.tables.features['anum'] = 'Arabic Digits' +local features = otf.tables.features + +features['tlig'] = 'TeX Ligatures' +features['trep'] = 'TeX Replacements' +features['anum'] = 'Arabic Digits' + +local register_base_substitution = otf.features.register_base_substitution -otf.features.register_base_substitution('tlig') -otf.features.register_base_substitution('trep') -otf.features.register_base_substitution('anum') +register_base_substitution('tlig') +register_base_substitution('trep') +register_base_substitution('anum') -- the functionality is defined elsewhere -fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits -fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits +local initializers = fonts.initializers +local common_initializers = initializers.common +local base_initializers = initializers.base.otf +local node_initializers = initializers.node.otf -fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight -fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight +base_initializers.equaldigits = common_initializers.equaldigits +node_initializers.equaldigits = common_initializers.equaldigits -fonts.initializers.base.otf.compose = fonts.initializers.common.compose -fonts.initializers.node.otf.compose = fonts.initializers.common.compose +base_initializers.lineheight = common_initializers.lineheight +node_initializers.lineheight = common_initializers.lineheight + +base_initializers.compose = common_initializers.compose +node_initializers.compose = common_initializers.compose end -- closure @@ -11089,34 +11114,33 @@ local report_afm = logs.new("load afm") default loader that only handles <l n='tfm'/>.</p> --ldx]]-- -fonts = fonts or { } -fonts.define = fonts.define or { } -fonts.tfm = fonts.tfm or { } -fonts.ids = fonts.ids or { } -fonts.vf = fonts.vf or { } -fonts.used = fonts.used or { } +local fonts = fonts +local tfm = fonts.tfm +local vf = fonts.vf +local fontids = fonts.ids -local tfm = fonts.tfm -local vf = fonts.vf -local define = fonts.define +fonts.used = fonts.used or { } -tfm.version = 1.01 -tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm +tfm.readers = tfm.readers or { } +tfm.fonts = tfm.fonts or { } +tfm.internalized = tfm.internalized or { } -- internal tex numbers -define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm -define.specify = fonts.define.specify or { } -define.methods = fonts.define.methods or { } +local readers = tfm.readers +local sequence = { 'otf', 'ttf', 'afm', 'tfm' } +readers.sequence = sequence -tfm.fonts = tfm.fonts or { } -tfm.readers = tfm.readers or { } -tfm.internalized = tfm.internalized or { } -- internal tex numbers +tfm.version = 1.01 +tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm +tfm.auto_afm = true -tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' } +fonts.define = fonts.define or { } +local define = fonts.define -tfm.auto_afm = true +define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm +define.specify = define.specify or { } +define.methods = define.methods or { } -local readers = tfm.readers -local sequence = readers.sequence +local findbinfile = resolvers.findbinfile --[[ldx-- <p>We hardly gain anything when we cache the final (pre scaled) @@ -11192,10 +11216,6 @@ function define.makespecification(specification, lookup, name, sub, method, deta specification, (lookup ~= "" and lookup) or "[file]", (name ~= "" and name) or "-", (sub ~= "" and sub) or "-", (method ~= "" and method) or "-", (detail ~= "" and detail) or "-") end ---~ if specification.lookup then ---~ lookup = specification.lookup -- can come from xetex [] syntax ---~ specification.lookup = nil ---~ end if not lookup or lookup == "" then lookup = define.defaultlookup end @@ -11275,7 +11295,7 @@ function tfm.hash_instance(specification,force) specification.hash = hash end if size < 1000 and fonts.designsizes[hash] then - size = math.round(tfm.scaled(size, fonts.designsizes[hash])) + size = math.round(tfm.scaled(size,fonts.designsizes[hash])) specification.size = size end --~ local mathsize = specification.mathsize or 0 @@ -11299,11 +11319,12 @@ end <p>We can resolve the filename using the next function:</p> --ldx]]-- -define.resolvers = resolvers +define.resolvers = define.resolvers or { } +local resolvers = define.resolvers -- todo: reporter -function define.resolvers.file(specification) +function resolvers.file(specification) local suffix = file.suffix(specification.name) if fonts.formats[suffix] then specification.forced = suffix @@ -11311,7 +11332,7 @@ function define.resolvers.file(specification) end end -function define.resolvers.name(specification) +function resolvers.name(specification) local resolve = fonts.names.resolve if resolve then local resolved, sub = fonts.names.resolve(specification.name,specification.sub) @@ -11326,11 +11347,11 @@ function define.resolvers.name(specification) end end else - define.resolvers.file(specification) + resolvers.file(specification) end end -function define.resolvers.spec(specification) +function resolvers.spec(specification) local resolvespec = fonts.names.resolvespec if resolvespec then specification.resolved, specification.sub = fonts.names.resolvespec(specification.name,specification.sub) @@ -11339,13 +11360,13 @@ function define.resolvers.spec(specification) specification.name = file.removesuffix(specification.resolved) end else - define.resolvers.name(specification) + resolvers.name(specification) end end function define.resolve(specification) if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash - local r = define.resolvers[specification.lookup] + local r = resolvers[specification.lookup] if r then r(specification) end @@ -11355,7 +11376,7 @@ function define.resolve(specification) else specification.forced = specification.forced end - -- for the moment here (goodies eset outside features) + -- for the moment here (goodies set outside features) local goodies = specification.goodies if goodies and goodies ~= "" then local normalgoodies = specification.features.normal.goodies @@ -11467,9 +11488,9 @@ evolved. Each one has its own way of dealing with its format.</p> local function check_tfm(specification,fullname) -- ofm directive blocks local path search unless set; btw, in context we -- don't support ofm files anyway as this format is obsolete - local foundname = resolvers.findbinfile(fullname, 'tfm') or "" -- just to be sure + local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure if foundname == "" then - foundname = resolvers.findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context + foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context end if foundname ~= "" then specification.filename, specification.format = foundname, "ofm" @@ -11478,11 +11499,11 @@ local function check_tfm(specification,fullname) end local function check_afm(specification,fullname) - local foundname = resolvers.findbinfile(fullname, 'afm') or "" -- just to be sure + local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure if foundname == "" and tfm.auto_afm then local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* if encoding and shortname and fonts.enc.known[encoding] then - shortname = resolvers.findbinfile(shortname,'afm') or "" -- just to be sure + shortname = findbinfile(shortname,'afm') or "" -- just to be sure if shortname ~= "" then foundname = shortname -- tfm.set_normal_feature(specification,'encoding',encoding) -- will go away @@ -11546,17 +11567,17 @@ local function check_otf(forced,specification,suffix,what) if forced then name = file.addsuffix(name,suffix,true) end - local fullname, tfmtable = resolvers.findbinfile(name,suffix) or "", nil -- one shot + local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot if fullname == "" then local fb = fonts.names.old_to_new[name] if fb then - fullname = resolvers.findbinfile(fb,suffix) or "" + fullname = findbinfile(fb,suffix) or "" end end if fullname == "" then local fb = fonts.names.new_to_old[name] if fb then - fullname = resolvers.findbinfile(fb,suffix) or "" + fullname = findbinfile(fb,suffix) or "" end end if fullname ~= "" then @@ -11715,7 +11736,7 @@ function vf.find(name) if trace_defining then report_define("locating vf for %s",name) end - return resolvers.findbinfile(name,"ovf") + return findbinfile(name,"ovf") else if trace_defining then report_define("vf for %s is already taken care of",name) @@ -11726,7 +11747,7 @@ function vf.find(name) if trace_defining then report_define("locating vf for %s",name) end - return resolvers.findbinfile(name,"ovf") + return findbinfile(name,"ovf") end end @@ -11774,38 +11795,16 @@ well and that does not work too well with the general design of the specifier.</p> --ldx]]-- ---~ function fonts.define.specify.colonized(specification) -- xetex mode ---~ local list = { } ---~ if specification.detail and specification.detail ~= "" then ---~ for v in gmatch(specification.detail,"%s*([^;]+)%s*") do ---~ local a, b = match(v,"^(%S*)%s*=%s*(%S*)$") ---~ if a and b then ---~ list[a] = b:is_boolean() ---~ if type(list[a]) == "nil" then ---~ list[a] = b ---~ end ---~ else ---~ local a, b = match(v,"^([%+%-]?)%s*(%S+)$") ---~ if a and b then ---~ list[b] = a ~= "-" ---~ end ---~ end ---~ end ---~ end ---~ specification.features.normal = list ---~ return specification ---~ end - ---~ check("oeps/BI:+a;-b;c=d") ---~ check("[oeps]/BI:+a;-b;c=d") ---~ check("file:oeps/BI:+a;-b;c=d") ---~ check("name:oeps/BI:+a;-b;c=d") +local fonts = fonts +local define = fonts.define +local specify = define.specify +local normalize_meanings = fonts.otf.meanings.normalize local list = { } -fonts.define.specify.colonized_default_lookup = "file" +specify.colonized_default_lookup = "file" -local function issome () list.lookup = fonts.define.specify.colonized_default_lookup end +local function issome () list.lookup = specify.colonized_default_lookup end local function isfile () list.lookup = 'file' end local function isname () list.lookup = 'name' end local function thename(s) list.name = s end @@ -11818,32 +11817,32 @@ local function iskey (k,v) list[k] = v end local function istrue (s) list[s] = true end local function isfalse(s) list[s] = false end -local spaces = lpeg.P(" ")^0 -local namespec = (1-lpeg.S("/:("))^0 -- was: (1-lpeg.S("/: ("))^0 -local crapspec = spaces * lpeg.P("/") * (((1-lpeg.P(":"))^0)/iscrap) * spaces -local filename = (lpeg.P("file:")/isfile * (namespec/thename)) + (lpeg.P("[") * lpeg.P(true)/isname * (((1-lpeg.P("]"))^0)/thename) * lpeg.P("]")) -local fontname = (lpeg.P("name:")/isname * (namespec/thename)) + lpeg.P(true)/issome * (namespec/thename) -local sometext = (lpeg.R("az","AZ","09") + lpeg.S("+-."))^1 -local truevalue = lpeg.P("+") * spaces * (sometext/istrue) -local falsevalue = lpeg.P("-") * spaces * (sometext/isfalse) -local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(sometext))/iskey +local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C + +local spaces = P(" ")^0 +local namespec = (1-S("/:("))^0 -- was: (1-S("/: ("))^0 +local crapspec = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces +local filename = (P("file:")/isfile * (namespec/thename)) + (P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]")) +local fontname = (P("name:")/isname * (namespec/thename)) + P(true)/issome * (namespec/thename) +local sometext = (R("az","AZ","09") + S("+-."))^1 +local truevalue = P("+") * spaces * (sometext/istrue) +local falsevalue = P("-") * spaces * (sometext/isfalse) +local keyvalue = (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey local somevalue = sometext/istrue -local subvalue = lpeg.P("(") * (lpeg.C(lpeg.P(1-lpeg.S("()"))^1)/issub) * lpeg.P(")") -- for Kim +local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces -local options = lpeg.P(":") * spaces * (lpeg.P(";")^0 * option)^0 +local options = P(":") * spaces * (P(";")^0 * option)^0 local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0 -local normalize_meanings = fonts.otf.meanings.normalize - -function fonts.define.specify.colonized(specification) -- xetex mode +local function colonized(specification) -- xetex mode list = { } lpegmatch(pattern,specification.specification) ---~ for k, v in next, list do ---~ list[k] = v:is_boolean() ---~ if type(list[a]) == "nil" then ---~ list[k] = v ---~ end ---~ end + -- for k, v in next, list do + -- list[k] = v:is_boolean() + -- if type(list[a]) == "nil" then + -- list[k] = v + -- end + -- end list.crap = nil -- style not supported, maybe some day if list.name then specification.name = list.name @@ -11857,12 +11856,14 @@ function fonts.define.specify.colonized(specification) -- xetex mode specification.sub = list.sub list.sub = nil end --- specification.features.normal = list + -- specification.features.normal = list specification.features.normal = normalize_meanings(list) return specification end -fonts.define.register_split(":", fonts.define.specify.colonized) +specify.colonized = colonized + +define.register_split(":",colonized) end -- closure diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua index 542b36f9d..03a7d4b51 100644 --- a/web2c/contextcnf.lua +++ b/web2c/contextcnf.lua @@ -33,8 +33,8 @@ return { TEXMF = "{$TEXMFHOME,!!$TEXMFPROJECT,!!$TEXMFFONTS,!!$TEXMFLOCAL,!!$TEXMFCONTEXT,!!$TEXMFSYSTEM,!!$TEXMFMAIN}", - TEXFONTMAPS = ".;$TEXMF/fonts/{data,map}/{pdftex,dvips}//", - ENCFONTS = ".;$TEXMF/fonts/{data,enc}/{dvips,pdftex}//", + TEXFONTMAPS = ".;$TEXMF/fonts/data//;$TEXMF/fonts/map/{pdftex,dvips}//", + ENCFONTS = ".;$TEXMF/fonts/data//;$TEXMF/fonts/enc/{dvips,pdftex}//", VFFONTS = ".;$TEXMF/fonts/{data,vf}//", TFMFONTS = ".;$TEXMF/fonts/{data,tfm}//", T1FONTS = ".;$TEXMF/fonts/{data,type1,pfb}//;$OSFONTDIR", @@ -64,6 +64,10 @@ return { BIBINPUTS = ".;$TEXMF/bibtex/bib//", BSTINPUTS = ".;$TEXMF/bibtex/bst//", + -- Experimental + + ICCPROFILES = ".;$TEXMF/colors/icc/{context,profiles}//;$OSCOLORDIR", + -- Sort of obsolete. OTPINPUTS = ".;$TEXMF/omega/otp//", @@ -106,6 +110,7 @@ return { -- system_checkglobals = "10", -- system.nostatistics = "yes", system_errorcontext = "10", + mplib_texerrors = "yes", }, experiments = { |