diff options
127 files changed, 4515 insertions, 2858 deletions
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 4cb00301d..73ff481fd 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -670,7 +670,6 @@ function scripts.context.run(ctxdata,filename) -- this catches the command line if not formatfile or not scriptfile then logs.simple("warning: no format found, forcing remake (commandline driven)") - scripts.context.generate() scripts.context.make(formatname) formatfile, scriptfile = resolvers.locateformat(formatname) end @@ -718,7 +717,6 @@ function scripts.context.run(ctxdata,filename) -- this catches the command line if not formatfile or not scriptfile then logs.simple("warning: no format found, forcing remake (source driven)") - scripts.context.generate() scripts.context.make(formatname) formatfile, scriptfile = resolvers.locateformat(formatname) end @@ -788,7 +786,6 @@ function scripts.context.run(ctxdata,filename) local okay = statistics.checkfmtstatus(formatfile) if okay ~= true then logs.simple("warning: %s, forcing remake",tostring(okay)) - scripts.context.generate() scripts.context.make(formatname) end -- @@ -815,7 +812,6 @@ function scripts.context.run(ctxdata,filename) logs.simple("run %s: %s",i,command) local returncode, errorstring = os.spawn(command) --~ if returncode == 3 then - --~ scripts.context.generate() --~ scripts.context.make(formatname) --~ returncode, errorstring = os.spawn(command) --~ if returncode == 3 then @@ -936,7 +932,6 @@ function scripts.context.pipe() local formatfile, scriptfile = resolvers.locateformat(formatname) if not formatfile or not scriptfile then logs.simple("warning: no format found, forcing remake (commandline driven)") - scripts.context.generate() scripts.context.make(formatname) formatfile, scriptfile = resolvers.locateformat(formatname) end @@ -944,7 +939,6 @@ function scripts.context.pipe() local okay = statistics.checkfmtstatus(formatfile) if okay ~= true then logs.simple("warning: %s, forcing remake",tostring(okay)) - scripts.context.generate() scripts.context.make(formatname) end local flags = { @@ -990,7 +984,16 @@ local function make_mkii_format(name,engine) end end +function scripts.context.generate() + resolvers.instance.renewcache = true + trackers.enable("resolvers.locating") + resolvers.load() +end + function scripts.context.make(name) + if not environment.argument("fast") then -- as in texexec + scripts.context.generate() + end local list = (name and { name }) or (environment.files[1] and environment.files) or scripts.context.defaultformats for i=1,#list do local name = list[i] @@ -1003,12 +1006,6 @@ function scripts.context.make(name) end end -function scripts.context.generate() - resolvers.instance.renewcache = true - trackers.enable("resolvers.locating") - resolvers.load() -end - function scripts.context.ctx() local ctxdata = ctxrunner.new() ctxdata.jobname = environment.files[1] @@ -1440,9 +1437,6 @@ function scripts.context.update() end end if force then - -- os.execute("context --generate") - -- os.execute("context --make") - scripts.context.generate() scripts.context.make() end end @@ -1537,15 +1531,10 @@ end if environment.argument("run") then -- scripts.context.timed(scripts.context.run) scripts.context.timed(scripts.context.autoctx) -elseif environment.argument("make") or environment.argument("generate") then - scripts.context.timed(function() - if environment.argument("generate") then - scripts.context.generate() - end - if environment.argument("make") then - scripts.context.make() - end - end) +elseif environment.argument("make") then + scripts.context.timed(function() scripts.context.make() end) +elseif environment.argument("generate") then + scripts.context.timed(function() scripts.context.generate() end) elseif environment.argument("ctx") then scripts.context.timed(scripts.context.ctx) elseif environment.argument("mp") or environment.argument("metapost") then diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua index cd97672bd..b7a815678 100644 --- a/scripts/context/lua/mtx-update.lua +++ b/scripts/context/lua/mtx-update.lua @@ -336,24 +336,12 @@ function scripts.update.synchronize() end end end - --~ for k, v in next, combined do - --~ logs.report("update", k) - --~ for i=1,#v do - --~ logs.report("update", " <= " .. v[i]) - --~ end - --~ end for destination, archive in next, combined do local archives, command = concat(archive," "), "" - -- local normalflags, deleteflags = states.get("rsync.flags.normal"), states.get("rsync.flags.delete") - -- if environment.argument("keep") or destination:find("%.$") then - -- command = format("%s %s %s'%s' '%s'", bin, normalflags, url, archives, destination) - -- else - -- command = format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) - -- end local normalflags, deleteflags = states.get("rsync.flags.normal"), "" -if os.name == "windows" then - normalflags = normalflags .. " -L" -- no symlinks -end + if os.name == "windows" then + normalflags = normalflags .. " -L" -- no symlinks + end local dryrunflags = "" if not environment.argument("force") then dryrunflags = "--dry-run" diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index f414d1707..bf3a4453e 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -431,6 +431,14 @@ function lpeg.keeper(str) end end +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end + +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + -- Just for fun I looked at the used bytecode and -- p = (p and p + pp) or pp gets one more (testset). @@ -2739,8 +2747,10 @@ local path = slash * Cs((escaped+(1- qmark-hash))^0) local query = qmark * Cs((escaped+(1- hash))^0) + nothing local fragment = hash * Cs((escaped+(1- endofstring))^0) + nothing -local parser = Ct(scheme * authority * path * query * fragment) +local validurl = scheme * authority * path * query * fragment +local parser = Ct(validurl) +lpegpatterns.url = validurl lpegpatterns.urlsplitter = parser local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end @@ -9420,6 +9430,13 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- profiler.start("luatex-profile.log") -- end +-- a forward definition + +if not resolvers.resolve then + function resolvers.resolve (s) return s end + function resolvers.unresolve(s) return s end +end + end -- of closure @@ -9616,7 +9633,8 @@ end local cache = { } -local splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +---- splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +local splitter = Ct(lpeg.splitat(";")) -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") @@ -9723,15 +9741,16 @@ local function scan(files,spec,path,n,m,r) return files, n, m, r end -function resolvers.scanfiles(path) +function resolvers.scanfiles(path,branch) if trace_locating then - report_resolvers("scanning path '%s'",path) - end - local files, n, m, r = scan({ },path .. '/',"",0,0,0) - files.__path__ = path - files.__files__ = n - files.__directories__ = m - files.__remappings__ = r + report_resolvers("scanning path '%s', branch '%s'",path, branch or path) + end + local realpath = resolvers.resolve(path) -- no shortcut + local files, n, m, r = scan({ },realpath .. '/',"",0,0,0) + files.__path__ = path -- can be selfautoparent:texmf-whatever + files.__files__ = n + files.__directories__ = m + files.__remappings__ = r if trace_locating then report_resolvers("%s files found on %s directories with %s uppercase remappings",n,m,r) end @@ -10087,16 +10106,17 @@ end -- end of intermezzo -caches = caches or { } -local caches = caches +caches = caches or { } +local caches = caches -caches.base = caches.base or "luatex-cache" -caches.more = caches.more or "context" -caches.direct = false -- true is faster but may need huge amounts of memory -caches.tree = false -caches.force = true -caches.ask = false -caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } +caches.base = caches.base or "luatex-cache" +caches.more = caches.more or "context" +caches.direct = false -- true is faster but may need huge amounts of memory +caches.tree = false +caches.force = true +caches.ask = false +caches.relocate = false +caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } local writable, readables, usedreadables = nil, { }, { } @@ -10216,7 +10236,14 @@ function caches.configfiles() end function caches.hashed(tree) - return md5.hex(gsub(lower(tree),"[\\\/]+","/")) + tree = gsub(tree,"\\$","/") + tree = gsub(tree,"/+$","") + tree = lower(tree) + local hash = md5.hex(tree) + if trace_cache or trace_locating then + report_cache("hashing tree %s, hash %s",tree,hash) + end + return hash end function caches.treehash() @@ -10592,15 +10619,25 @@ 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' -resolvers.configbanner = '' -resolvers.homedir = environment.homedir -resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } -resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- rubish path -resolvers.luacnfname = 'texmfcnf.lua' -resolvers.luacnfstate = "unknown" +resolvers.cacheversion = '1.0.1' +resolvers.configbanner = '' +resolvers.homedir = environment.homedir +resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } +resolvers.luacnfname = 'texmfcnf.lua' +resolvers.luacnfstate = "unknown" + +-- resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- what a rubish path +-- resolvers.luacnfspec = 'selfautoparent:{/texmf{-local,}{,/web2c},}}' + +resolvers.luacnfspec = { + "selfautoparent:/texmf-local", + "selfautoparent:/texmf-local/web2c", + "selfautoparent:/texmf", + "selfautoparent:/texmf/web2c", + "selfautoparent:", +} -local unset_variable = "unset" +local unset_variable = "unset" local formats = resolvers.formats local suffixes = resolvers.suffixes @@ -10685,10 +10722,6 @@ end resolvers.getenv = getenv resolvers.env = getenv -local function resolve(key) - local value = instance.variables[key] or "" - return (value ~= "" and value) or getenv(key) or "" -end local dollarstripper = lpeg.stripper("$") local inhibitstripper = P("!")^0 * Cs(P(1)^0) @@ -10700,15 +10733,6 @@ local somethingelse = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "") + P(";") * (P(";") / "") + P(1) -local pattern = Cs( (somevariable * (somekey/resolve) + somethingelse)^1 ) - -local function expandvars(lst) -- simple vars - for k=1,#lst do - local lk = lst[k] - lst[k] = lpegmatch(pattern,lk) or lk - end -end - local slash = P("/") @@ -10719,18 +10743,24 @@ local pattern = Cs ( + slash^2 / "/.-/" + (1-slash) * P(-1) * Cc("/") + P(1) - )^1 * Cc("$") + )^1 * Cc("$") -- yes or no $ ) +local cache = { } + local function makepathexpression(str) if str == "." then return "^%./$" else - return lpegmatch(pattern,str) + local c = cache[str] + if not c then + c = lpegmatch(pattern,str) + cache[str] = c + end + return c end end - local function resolve(key) local value = instance.variables[key] if value and value ~= "" then @@ -10750,7 +10780,6 @@ local function expandedvariable(var) -- simple vars return lpegmatch(pattern,var) or var end - local function entry(entries,name) if name and name ~= "" then name = lpegmatch(dollarstripper,name) @@ -10802,14 +10831,26 @@ local function identify_configuration_files() reportcriticalvariables() resolvers.expandvariables() local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) - expandvars(cnfpaths) --- hm + -- expandvars(cnfpaths) --- hm local luacnfname = resolvers.luacnfname for i=1,#cnfpaths do local filename = collapsepath(filejoin(cnfpaths[i],luacnfname)) - if lfs.isfile(filename) then - specification[#specification+1] = filename + local realname = resolvers.resolve(filename) -- no shortcut + -- if trace_locating then + -- report_resolvers("checking configuration file '%s'",filename) + -- end + if lfs.isfile(realname) then + specification[#specification+1] = filename -- or realname? + if trace_locating then + report_resolvers("found configuration file '%s'",realname) + end + elseif trace_locating then + report_resolvers("unknown configuration file '%s'",realname) end end + if trace_locating then + report_resolvers() + end end end @@ -10821,7 +10862,8 @@ local function load_configuration_files() local filename = specification[i] local pathname = filedirname(filename) local filename = filejoin(pathname,luacnfname) - local blob = loadfile(filename) + local realname = resolvers.resolve(filename) -- no shortcut + local blob = loadfile(realname) if blob then local setups = instance.setups local data = blob() @@ -10923,6 +10965,8 @@ local function collapse_configuration_data() -- potential optimization: pass sta end end +-- scheme magic + -- database loading local function load_file_databases() @@ -10942,34 +10986,24 @@ local function locate_file_databases() local texmfpaths = resolvers.expandedpathlist('TEXMF') for i=1,#texmfpaths do local path = collapsepath(texmfpaths[i]) - local stripped = lpegmatch(inhibitstripper,path) + local stripped = lpegmatch(inhibitstripper,path) -- the !! thing if stripped ~= "" then local runtime = stripped == path path = resolvers.cleanpath(path) - if lfs.isdir(path) then - local spec = resolvers.splitmethod(stripped) - if spec.scheme == "cache" or spec.scheme == "file" then - stripped = spec.path - elseif runtime and (spec.noscheme or spec.scheme == "file") then - stripped = "tree:///" .. stripped - end - if trace_locating then - if runtime then - report_resolvers("locating list of '%s' (runtime)",path) - else - report_resolvers("locating list of '%s' (cached)",path) - end - end - methodhandler('locators',stripped) -- nothing done with result - else - if trace_locating then - if runtime then - report_resolvers("skipping list of '%s' (runtime)",path) - else - report_resolvers("skipping list of '%s' (cached)",path) - end + local spec = resolvers.splitmethod(stripped) + if spec.scheme == "cache" or spec.scheme == "file" then + stripped = spec.path + elseif runtime and (spec.noscheme or spec.scheme == "file") then + stripped = "tree:///" .. stripped + end + if trace_locating then + if runtime then + report_resolvers("locating list of '%s' (runtime)",path) + else + report_resolvers("locating list of '%s' (cached)",path) end end + methodhandler('locators',stripped) end end if trace_locating then @@ -11097,16 +11131,16 @@ function resolvers.expandvariables() local engine, progname = instance.engine, instance.progname if type(engine) ~= "string" then instance.engine, engine = "", "" end if type(progname) ~= "string" then instance.progname, progname = "", "" end - if engine ~= "" then environment['engine'] = engine end - if progname ~= "" then environment['progname'] = progname end + if engine ~= "" then environment.engine = engine end + if progname ~= "" then environment.progname = progname end for k,v in next, environment do expansions[k] = v end - for k,v in next, environment do -- move environment to expansions (variables are already in there) - if not expansions[k] then expansions[k] = v end - end + -- for k,v in next, environment do -- move environment to expansions (variables are already in there) + -- if expansions[k] == nil then expansions[k] = v end + -- end for k,v in next, variables do -- move variables to expansions - if not expansions[k] then expansions[k] = v end + if expansions[k] == nil then expansions[k] = v end end repeat local busy = false @@ -11360,7 +11394,7 @@ local function collect_files(names) if type(blobfile) == 'string' then if not dname or find(blobfile,dname) then local kind = hash.type - local search = filejoin(blobpath,blobfile,bname) +local search = filejoin(blobroot,blobfile,bname) local result = methodhandler('concatinators',hash.type,blobroot,blobfile,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11373,7 +11407,7 @@ local function collect_files(names) local vv = blobfile[kk] if not dname or find(vv,dname) then local kind = hash.type - local search = filejoin(blobpath,vv,bname) +local search = filejoin(blobroot,vv,bname) local result = methodhandler('concatinators',hash.type,blobroot,vv,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11613,8 +11647,8 @@ local function collect_instance_files(filename,askedformat,allresults) -- todo : local f = fl[2] local d = dirlist[k] if find(d,expression) then - --- todo, test for readable - result[#result+1] = fl[3] + -- todo, test for readable + result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut done = true if allresults then if trace_detail then @@ -11980,6 +12014,13 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } +-- It could be interesting to hook the resolver in the file +-- opener so that unresolved prefixes travel around and we +-- get more abstraction. + +-- As we use this beforehand we will move this up in the chain +-- of loading. + local upper, lower, gsub = string.upper, string.lower, string.gsub @@ -11987,10 +12028,10 @@ local resolvers = resolvers local prefixes = { } -local getenv = resolvers.getenv +local getenv, cleanpath, findgivenfile = resolvers.getenv, resolvers.cleanpath, resolvers.findgivenfile prefixes.environment = function(str) -- getenv is case insensitive anyway - return resolvers.cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") + return cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") end prefixes.relative = function(str,n) @@ -12009,7 +12050,7 @@ prefixes.relative = function(str,n) end end end - return resolvers.cleanpath(str) + return cleanpath(str) end prefixes.auto = function(str) @@ -12021,20 +12062,38 @@ prefixes.auto = function(str) end prefixes.locate = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath((fullname ~= "" and fullname) or str) + local fullname = findgivenfile(str) or "" + return cleanpath((fullname ~= "" and fullname) or str) end prefixes.filename = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.basename((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.basename((fullname ~= "" and fullname) or str)) end prefixes.pathname = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.dirname((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.dirname((fullname ~= "" and fullname) or str)) end +prefixes.selfautoloc = function(str) + return cleanpath(file.join(getenv('SELFAUTOLOC'),str)) +end + +prefixes.selfautoparent = function(str) + return cleanpath(file.join(getenv('SELFAUTOPARENT'),str)) +end + +prefixes.selfautodir = function(str) + return cleanpath(file.join(getenv('SELFAUTODIR'),str)) +end + +prefixes.home = function(str) + return cleanpath(file.join(getenv('HOME'),str)) +end + +prefixes["~"] = prefixes.home + prefixes.env = prefixes.environment prefixes.rel = prefixes.relative prefixes.loc = prefixes.locate @@ -12061,19 +12120,26 @@ local function _resolve_(method,target) end end -local function resolve(str) - if type(str) == "table" then - for k=1,#str do - local v = str[k] - str[k] = resolve(v) or v - end - elseif str and str ~= "" then - str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_) + +local resolved = { } +local abstract = { } + +local function resolve(str) -- use schemes, this one is then for the commandline only + local res = resolved[str] + if not res then + res = gsub(str,"([a-z][a-z]+):([^ \"\']*)",_resolve_) + resolved[str] = res + abstract[res] = str end - return str + return res end -resolvers.resolve = resolve +local function unresolve(str) + return abstract[str] or str +end + +resolvers.resolve = resolve +resolvers.unresolve = unresolve if os.uname then @@ -12166,9 +12232,10 @@ local checkgarbage = utilities.garbagecollector and utilities.garbagecollector.c function locators.file(specification) local name = specification.filename - if name and name ~= '' and lfs.isdir(name) then + local realname = resolvers.resolve(name) -- no shortcut + if realname and realname ~= '' and lfs.isdir(realname) then if trace_locating then - report_resolvers("file locator '%s' found",name) + report_resolvers("file locator '%s' found as '%s'",name,realname) end resolvers.appendhash('file',name,true) -- cache elseif trace_locating then @@ -12183,9 +12250,9 @@ function hashers.file(specification) end function generators.file(specification) - local name = specification.filename - local content = resolvers.scanfiles(name) - resolvers.registerfilehash(name,content,true) + local path = specification.filename + local content = resolvers.scanfiles(path) + resolvers.registerfilehash(path,content,true) end concatinators.file = file.join diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index f414d1707..bf3a4453e 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -431,6 +431,14 @@ function lpeg.keeper(str) end end +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end + +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + -- Just for fun I looked at the used bytecode and -- p = (p and p + pp) or pp gets one more (testset). @@ -2739,8 +2747,10 @@ local path = slash * Cs((escaped+(1- qmark-hash))^0) local query = qmark * Cs((escaped+(1- hash))^0) + nothing local fragment = hash * Cs((escaped+(1- endofstring))^0) + nothing -local parser = Ct(scheme * authority * path * query * fragment) +local validurl = scheme * authority * path * query * fragment +local parser = Ct(validurl) +lpegpatterns.url = validurl lpegpatterns.urlsplitter = parser local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end @@ -9420,6 +9430,13 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- profiler.start("luatex-profile.log") -- end +-- a forward definition + +if not resolvers.resolve then + function resolvers.resolve (s) return s end + function resolvers.unresolve(s) return s end +end + end -- of closure @@ -9616,7 +9633,8 @@ end local cache = { } -local splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +---- splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +local splitter = Ct(lpeg.splitat(";")) -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") @@ -9723,15 +9741,16 @@ local function scan(files,spec,path,n,m,r) return files, n, m, r end -function resolvers.scanfiles(path) +function resolvers.scanfiles(path,branch) if trace_locating then - report_resolvers("scanning path '%s'",path) - end - local files, n, m, r = scan({ },path .. '/',"",0,0,0) - files.__path__ = path - files.__files__ = n - files.__directories__ = m - files.__remappings__ = r + report_resolvers("scanning path '%s', branch '%s'",path, branch or path) + end + local realpath = resolvers.resolve(path) -- no shortcut + local files, n, m, r = scan({ },realpath .. '/',"",0,0,0) + files.__path__ = path -- can be selfautoparent:texmf-whatever + files.__files__ = n + files.__directories__ = m + files.__remappings__ = r if trace_locating then report_resolvers("%s files found on %s directories with %s uppercase remappings",n,m,r) end @@ -10087,16 +10106,17 @@ end -- end of intermezzo -caches = caches or { } -local caches = caches +caches = caches or { } +local caches = caches -caches.base = caches.base or "luatex-cache" -caches.more = caches.more or "context" -caches.direct = false -- true is faster but may need huge amounts of memory -caches.tree = false -caches.force = true -caches.ask = false -caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } +caches.base = caches.base or "luatex-cache" +caches.more = caches.more or "context" +caches.direct = false -- true is faster but may need huge amounts of memory +caches.tree = false +caches.force = true +caches.ask = false +caches.relocate = false +caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } local writable, readables, usedreadables = nil, { }, { } @@ -10216,7 +10236,14 @@ function caches.configfiles() end function caches.hashed(tree) - return md5.hex(gsub(lower(tree),"[\\\/]+","/")) + tree = gsub(tree,"\\$","/") + tree = gsub(tree,"/+$","") + tree = lower(tree) + local hash = md5.hex(tree) + if trace_cache or trace_locating then + report_cache("hashing tree %s, hash %s",tree,hash) + end + return hash end function caches.treehash() @@ -10592,15 +10619,25 @@ 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' -resolvers.configbanner = '' -resolvers.homedir = environment.homedir -resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } -resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- rubish path -resolvers.luacnfname = 'texmfcnf.lua' -resolvers.luacnfstate = "unknown" +resolvers.cacheversion = '1.0.1' +resolvers.configbanner = '' +resolvers.homedir = environment.homedir +resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } +resolvers.luacnfname = 'texmfcnf.lua' +resolvers.luacnfstate = "unknown" + +-- resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- what a rubish path +-- resolvers.luacnfspec = 'selfautoparent:{/texmf{-local,}{,/web2c},}}' + +resolvers.luacnfspec = { + "selfautoparent:/texmf-local", + "selfautoparent:/texmf-local/web2c", + "selfautoparent:/texmf", + "selfautoparent:/texmf/web2c", + "selfautoparent:", +} -local unset_variable = "unset" +local unset_variable = "unset" local formats = resolvers.formats local suffixes = resolvers.suffixes @@ -10685,10 +10722,6 @@ end resolvers.getenv = getenv resolvers.env = getenv -local function resolve(key) - local value = instance.variables[key] or "" - return (value ~= "" and value) or getenv(key) or "" -end local dollarstripper = lpeg.stripper("$") local inhibitstripper = P("!")^0 * Cs(P(1)^0) @@ -10700,15 +10733,6 @@ local somethingelse = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "") + P(";") * (P(";") / "") + P(1) -local pattern = Cs( (somevariable * (somekey/resolve) + somethingelse)^1 ) - -local function expandvars(lst) -- simple vars - for k=1,#lst do - local lk = lst[k] - lst[k] = lpegmatch(pattern,lk) or lk - end -end - local slash = P("/") @@ -10719,18 +10743,24 @@ local pattern = Cs ( + slash^2 / "/.-/" + (1-slash) * P(-1) * Cc("/") + P(1) - )^1 * Cc("$") + )^1 * Cc("$") -- yes or no $ ) +local cache = { } + local function makepathexpression(str) if str == "." then return "^%./$" else - return lpegmatch(pattern,str) + local c = cache[str] + if not c then + c = lpegmatch(pattern,str) + cache[str] = c + end + return c end end - local function resolve(key) local value = instance.variables[key] if value and value ~= "" then @@ -10750,7 +10780,6 @@ local function expandedvariable(var) -- simple vars return lpegmatch(pattern,var) or var end - local function entry(entries,name) if name and name ~= "" then name = lpegmatch(dollarstripper,name) @@ -10802,14 +10831,26 @@ local function identify_configuration_files() reportcriticalvariables() resolvers.expandvariables() local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) - expandvars(cnfpaths) --- hm + -- expandvars(cnfpaths) --- hm local luacnfname = resolvers.luacnfname for i=1,#cnfpaths do local filename = collapsepath(filejoin(cnfpaths[i],luacnfname)) - if lfs.isfile(filename) then - specification[#specification+1] = filename + local realname = resolvers.resolve(filename) -- no shortcut + -- if trace_locating then + -- report_resolvers("checking configuration file '%s'",filename) + -- end + if lfs.isfile(realname) then + specification[#specification+1] = filename -- or realname? + if trace_locating then + report_resolvers("found configuration file '%s'",realname) + end + elseif trace_locating then + report_resolvers("unknown configuration file '%s'",realname) end end + if trace_locating then + report_resolvers() + end end end @@ -10821,7 +10862,8 @@ local function load_configuration_files() local filename = specification[i] local pathname = filedirname(filename) local filename = filejoin(pathname,luacnfname) - local blob = loadfile(filename) + local realname = resolvers.resolve(filename) -- no shortcut + local blob = loadfile(realname) if blob then local setups = instance.setups local data = blob() @@ -10923,6 +10965,8 @@ local function collapse_configuration_data() -- potential optimization: pass sta end end +-- scheme magic + -- database loading local function load_file_databases() @@ -10942,34 +10986,24 @@ local function locate_file_databases() local texmfpaths = resolvers.expandedpathlist('TEXMF') for i=1,#texmfpaths do local path = collapsepath(texmfpaths[i]) - local stripped = lpegmatch(inhibitstripper,path) + local stripped = lpegmatch(inhibitstripper,path) -- the !! thing if stripped ~= "" then local runtime = stripped == path path = resolvers.cleanpath(path) - if lfs.isdir(path) then - local spec = resolvers.splitmethod(stripped) - if spec.scheme == "cache" or spec.scheme == "file" then - stripped = spec.path - elseif runtime and (spec.noscheme or spec.scheme == "file") then - stripped = "tree:///" .. stripped - end - if trace_locating then - if runtime then - report_resolvers("locating list of '%s' (runtime)",path) - else - report_resolvers("locating list of '%s' (cached)",path) - end - end - methodhandler('locators',stripped) -- nothing done with result - else - if trace_locating then - if runtime then - report_resolvers("skipping list of '%s' (runtime)",path) - else - report_resolvers("skipping list of '%s' (cached)",path) - end + local spec = resolvers.splitmethod(stripped) + if spec.scheme == "cache" or spec.scheme == "file" then + stripped = spec.path + elseif runtime and (spec.noscheme or spec.scheme == "file") then + stripped = "tree:///" .. stripped + end + if trace_locating then + if runtime then + report_resolvers("locating list of '%s' (runtime)",path) + else + report_resolvers("locating list of '%s' (cached)",path) end end + methodhandler('locators',stripped) end end if trace_locating then @@ -11097,16 +11131,16 @@ function resolvers.expandvariables() local engine, progname = instance.engine, instance.progname if type(engine) ~= "string" then instance.engine, engine = "", "" end if type(progname) ~= "string" then instance.progname, progname = "", "" end - if engine ~= "" then environment['engine'] = engine end - if progname ~= "" then environment['progname'] = progname end + if engine ~= "" then environment.engine = engine end + if progname ~= "" then environment.progname = progname end for k,v in next, environment do expansions[k] = v end - for k,v in next, environment do -- move environment to expansions (variables are already in there) - if not expansions[k] then expansions[k] = v end - end + -- for k,v in next, environment do -- move environment to expansions (variables are already in there) + -- if expansions[k] == nil then expansions[k] = v end + -- end for k,v in next, variables do -- move variables to expansions - if not expansions[k] then expansions[k] = v end + if expansions[k] == nil then expansions[k] = v end end repeat local busy = false @@ -11360,7 +11394,7 @@ local function collect_files(names) if type(blobfile) == 'string' then if not dname or find(blobfile,dname) then local kind = hash.type - local search = filejoin(blobpath,blobfile,bname) +local search = filejoin(blobroot,blobfile,bname) local result = methodhandler('concatinators',hash.type,blobroot,blobfile,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11373,7 +11407,7 @@ local function collect_files(names) local vv = blobfile[kk] if not dname or find(vv,dname) then local kind = hash.type - local search = filejoin(blobpath,vv,bname) +local search = filejoin(blobroot,vv,bname) local result = methodhandler('concatinators',hash.type,blobroot,vv,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11613,8 +11647,8 @@ local function collect_instance_files(filename,askedformat,allresults) -- todo : local f = fl[2] local d = dirlist[k] if find(d,expression) then - --- todo, test for readable - result[#result+1] = fl[3] + -- todo, test for readable + result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut done = true if allresults then if trace_detail then @@ -11980,6 +12014,13 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } +-- It could be interesting to hook the resolver in the file +-- opener so that unresolved prefixes travel around and we +-- get more abstraction. + +-- As we use this beforehand we will move this up in the chain +-- of loading. + local upper, lower, gsub = string.upper, string.lower, string.gsub @@ -11987,10 +12028,10 @@ local resolvers = resolvers local prefixes = { } -local getenv = resolvers.getenv +local getenv, cleanpath, findgivenfile = resolvers.getenv, resolvers.cleanpath, resolvers.findgivenfile prefixes.environment = function(str) -- getenv is case insensitive anyway - return resolvers.cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") + return cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") end prefixes.relative = function(str,n) @@ -12009,7 +12050,7 @@ prefixes.relative = function(str,n) end end end - return resolvers.cleanpath(str) + return cleanpath(str) end prefixes.auto = function(str) @@ -12021,20 +12062,38 @@ prefixes.auto = function(str) end prefixes.locate = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath((fullname ~= "" and fullname) or str) + local fullname = findgivenfile(str) or "" + return cleanpath((fullname ~= "" and fullname) or str) end prefixes.filename = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.basename((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.basename((fullname ~= "" and fullname) or str)) end prefixes.pathname = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.dirname((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.dirname((fullname ~= "" and fullname) or str)) end +prefixes.selfautoloc = function(str) + return cleanpath(file.join(getenv('SELFAUTOLOC'),str)) +end + +prefixes.selfautoparent = function(str) + return cleanpath(file.join(getenv('SELFAUTOPARENT'),str)) +end + +prefixes.selfautodir = function(str) + return cleanpath(file.join(getenv('SELFAUTODIR'),str)) +end + +prefixes.home = function(str) + return cleanpath(file.join(getenv('HOME'),str)) +end + +prefixes["~"] = prefixes.home + prefixes.env = prefixes.environment prefixes.rel = prefixes.relative prefixes.loc = prefixes.locate @@ -12061,19 +12120,26 @@ local function _resolve_(method,target) end end -local function resolve(str) - if type(str) == "table" then - for k=1,#str do - local v = str[k] - str[k] = resolve(v) or v - end - elseif str and str ~= "" then - str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_) + +local resolved = { } +local abstract = { } + +local function resolve(str) -- use schemes, this one is then for the commandline only + local res = resolved[str] + if not res then + res = gsub(str,"([a-z][a-z]+):([^ \"\']*)",_resolve_) + resolved[str] = res + abstract[res] = str end - return str + return res end -resolvers.resolve = resolve +local function unresolve(str) + return abstract[str] or str +end + +resolvers.resolve = resolve +resolvers.unresolve = unresolve if os.uname then @@ -12166,9 +12232,10 @@ local checkgarbage = utilities.garbagecollector and utilities.garbagecollector.c function locators.file(specification) local name = specification.filename - if name and name ~= '' and lfs.isdir(name) then + local realname = resolvers.resolve(name) -- no shortcut + if realname and realname ~= '' and lfs.isdir(realname) then if trace_locating then - report_resolvers("file locator '%s' found",name) + report_resolvers("file locator '%s' found as '%s'",name,realname) end resolvers.appendhash('file',name,true) -- cache elseif trace_locating then @@ -12183,9 +12250,9 @@ function hashers.file(specification) end function generators.file(specification) - local name = specification.filename - local content = resolvers.scanfiles(name) - resolvers.registerfilehash(name,content,true) + local path = specification.filename + local content = resolvers.scanfiles(path) + resolvers.registerfilehash(path,content,true) end concatinators.file = file.join diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index f414d1707..bf3a4453e 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -431,6 +431,14 @@ function lpeg.keeper(str) end end +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end + +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + -- Just for fun I looked at the used bytecode and -- p = (p and p + pp) or pp gets one more (testset). @@ -2739,8 +2747,10 @@ local path = slash * Cs((escaped+(1- qmark-hash))^0) local query = qmark * Cs((escaped+(1- hash))^0) + nothing local fragment = hash * Cs((escaped+(1- endofstring))^0) + nothing -local parser = Ct(scheme * authority * path * query * fragment) +local validurl = scheme * authority * path * query * fragment +local parser = Ct(validurl) +lpegpatterns.url = validurl lpegpatterns.urlsplitter = parser local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end @@ -9420,6 +9430,13 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- profiler.start("luatex-profile.log") -- end +-- a forward definition + +if not resolvers.resolve then + function resolvers.resolve (s) return s end + function resolvers.unresolve(s) return s end +end + end -- of closure @@ -9616,7 +9633,8 @@ end local cache = { } -local splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +---- splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +local splitter = Ct(lpeg.splitat(";")) -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") @@ -9723,15 +9741,16 @@ local function scan(files,spec,path,n,m,r) return files, n, m, r end -function resolvers.scanfiles(path) +function resolvers.scanfiles(path,branch) if trace_locating then - report_resolvers("scanning path '%s'",path) - end - local files, n, m, r = scan({ },path .. '/',"",0,0,0) - files.__path__ = path - files.__files__ = n - files.__directories__ = m - files.__remappings__ = r + report_resolvers("scanning path '%s', branch '%s'",path, branch or path) + end + local realpath = resolvers.resolve(path) -- no shortcut + local files, n, m, r = scan({ },realpath .. '/',"",0,0,0) + files.__path__ = path -- can be selfautoparent:texmf-whatever + files.__files__ = n + files.__directories__ = m + files.__remappings__ = r if trace_locating then report_resolvers("%s files found on %s directories with %s uppercase remappings",n,m,r) end @@ -10087,16 +10106,17 @@ end -- end of intermezzo -caches = caches or { } -local caches = caches +caches = caches or { } +local caches = caches -caches.base = caches.base or "luatex-cache" -caches.more = caches.more or "context" -caches.direct = false -- true is faster but may need huge amounts of memory -caches.tree = false -caches.force = true -caches.ask = false -caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } +caches.base = caches.base or "luatex-cache" +caches.more = caches.more or "context" +caches.direct = false -- true is faster but may need huge amounts of memory +caches.tree = false +caches.force = true +caches.ask = false +caches.relocate = false +caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } local writable, readables, usedreadables = nil, { }, { } @@ -10216,7 +10236,14 @@ function caches.configfiles() end function caches.hashed(tree) - return md5.hex(gsub(lower(tree),"[\\\/]+","/")) + tree = gsub(tree,"\\$","/") + tree = gsub(tree,"/+$","") + tree = lower(tree) + local hash = md5.hex(tree) + if trace_cache or trace_locating then + report_cache("hashing tree %s, hash %s",tree,hash) + end + return hash end function caches.treehash() @@ -10592,15 +10619,25 @@ 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' -resolvers.configbanner = '' -resolvers.homedir = environment.homedir -resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } -resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- rubish path -resolvers.luacnfname = 'texmfcnf.lua' -resolvers.luacnfstate = "unknown" +resolvers.cacheversion = '1.0.1' +resolvers.configbanner = '' +resolvers.homedir = environment.homedir +resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } +resolvers.luacnfname = 'texmfcnf.lua' +resolvers.luacnfstate = "unknown" + +-- resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- what a rubish path +-- resolvers.luacnfspec = 'selfautoparent:{/texmf{-local,}{,/web2c},}}' + +resolvers.luacnfspec = { + "selfautoparent:/texmf-local", + "selfautoparent:/texmf-local/web2c", + "selfautoparent:/texmf", + "selfautoparent:/texmf/web2c", + "selfautoparent:", +} -local unset_variable = "unset" +local unset_variable = "unset" local formats = resolvers.formats local suffixes = resolvers.suffixes @@ -10685,10 +10722,6 @@ end resolvers.getenv = getenv resolvers.env = getenv -local function resolve(key) - local value = instance.variables[key] or "" - return (value ~= "" and value) or getenv(key) or "" -end local dollarstripper = lpeg.stripper("$") local inhibitstripper = P("!")^0 * Cs(P(1)^0) @@ -10700,15 +10733,6 @@ local somethingelse = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "") + P(";") * (P(";") / "") + P(1) -local pattern = Cs( (somevariable * (somekey/resolve) + somethingelse)^1 ) - -local function expandvars(lst) -- simple vars - for k=1,#lst do - local lk = lst[k] - lst[k] = lpegmatch(pattern,lk) or lk - end -end - local slash = P("/") @@ -10719,18 +10743,24 @@ local pattern = Cs ( + slash^2 / "/.-/" + (1-slash) * P(-1) * Cc("/") + P(1) - )^1 * Cc("$") + )^1 * Cc("$") -- yes or no $ ) +local cache = { } + local function makepathexpression(str) if str == "." then return "^%./$" else - return lpegmatch(pattern,str) + local c = cache[str] + if not c then + c = lpegmatch(pattern,str) + cache[str] = c + end + return c end end - local function resolve(key) local value = instance.variables[key] if value and value ~= "" then @@ -10750,7 +10780,6 @@ local function expandedvariable(var) -- simple vars return lpegmatch(pattern,var) or var end - local function entry(entries,name) if name and name ~= "" then name = lpegmatch(dollarstripper,name) @@ -10802,14 +10831,26 @@ local function identify_configuration_files() reportcriticalvariables() resolvers.expandvariables() local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) - expandvars(cnfpaths) --- hm + -- expandvars(cnfpaths) --- hm local luacnfname = resolvers.luacnfname for i=1,#cnfpaths do local filename = collapsepath(filejoin(cnfpaths[i],luacnfname)) - if lfs.isfile(filename) then - specification[#specification+1] = filename + local realname = resolvers.resolve(filename) -- no shortcut + -- if trace_locating then + -- report_resolvers("checking configuration file '%s'",filename) + -- end + if lfs.isfile(realname) then + specification[#specification+1] = filename -- or realname? + if trace_locating then + report_resolvers("found configuration file '%s'",realname) + end + elseif trace_locating then + report_resolvers("unknown configuration file '%s'",realname) end end + if trace_locating then + report_resolvers() + end end end @@ -10821,7 +10862,8 @@ local function load_configuration_files() local filename = specification[i] local pathname = filedirname(filename) local filename = filejoin(pathname,luacnfname) - local blob = loadfile(filename) + local realname = resolvers.resolve(filename) -- no shortcut + local blob = loadfile(realname) if blob then local setups = instance.setups local data = blob() @@ -10923,6 +10965,8 @@ local function collapse_configuration_data() -- potential optimization: pass sta end end +-- scheme magic + -- database loading local function load_file_databases() @@ -10942,34 +10986,24 @@ local function locate_file_databases() local texmfpaths = resolvers.expandedpathlist('TEXMF') for i=1,#texmfpaths do local path = collapsepath(texmfpaths[i]) - local stripped = lpegmatch(inhibitstripper,path) + local stripped = lpegmatch(inhibitstripper,path) -- the !! thing if stripped ~= "" then local runtime = stripped == path path = resolvers.cleanpath(path) - if lfs.isdir(path) then - local spec = resolvers.splitmethod(stripped) - if spec.scheme == "cache" or spec.scheme == "file" then - stripped = spec.path - elseif runtime and (spec.noscheme or spec.scheme == "file") then - stripped = "tree:///" .. stripped - end - if trace_locating then - if runtime then - report_resolvers("locating list of '%s' (runtime)",path) - else - report_resolvers("locating list of '%s' (cached)",path) - end - end - methodhandler('locators',stripped) -- nothing done with result - else - if trace_locating then - if runtime then - report_resolvers("skipping list of '%s' (runtime)",path) - else - report_resolvers("skipping list of '%s' (cached)",path) - end + local spec = resolvers.splitmethod(stripped) + if spec.scheme == "cache" or spec.scheme == "file" then + stripped = spec.path + elseif runtime and (spec.noscheme or spec.scheme == "file") then + stripped = "tree:///" .. stripped + end + if trace_locating then + if runtime then + report_resolvers("locating list of '%s' (runtime)",path) + else + report_resolvers("locating list of '%s' (cached)",path) end end + methodhandler('locators',stripped) end end if trace_locating then @@ -11097,16 +11131,16 @@ function resolvers.expandvariables() local engine, progname = instance.engine, instance.progname if type(engine) ~= "string" then instance.engine, engine = "", "" end if type(progname) ~= "string" then instance.progname, progname = "", "" end - if engine ~= "" then environment['engine'] = engine end - if progname ~= "" then environment['progname'] = progname end + if engine ~= "" then environment.engine = engine end + if progname ~= "" then environment.progname = progname end for k,v in next, environment do expansions[k] = v end - for k,v in next, environment do -- move environment to expansions (variables are already in there) - if not expansions[k] then expansions[k] = v end - end + -- for k,v in next, environment do -- move environment to expansions (variables are already in there) + -- if expansions[k] == nil then expansions[k] = v end + -- end for k,v in next, variables do -- move variables to expansions - if not expansions[k] then expansions[k] = v end + if expansions[k] == nil then expansions[k] = v end end repeat local busy = false @@ -11360,7 +11394,7 @@ local function collect_files(names) if type(blobfile) == 'string' then if not dname or find(blobfile,dname) then local kind = hash.type - local search = filejoin(blobpath,blobfile,bname) +local search = filejoin(blobroot,blobfile,bname) local result = methodhandler('concatinators',hash.type,blobroot,blobfile,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11373,7 +11407,7 @@ local function collect_files(names) local vv = blobfile[kk] if not dname or find(vv,dname) then local kind = hash.type - local search = filejoin(blobpath,vv,bname) +local search = filejoin(blobroot,vv,bname) local result = methodhandler('concatinators',hash.type,blobroot,vv,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -11613,8 +11647,8 @@ local function collect_instance_files(filename,askedformat,allresults) -- todo : local f = fl[2] local d = dirlist[k] if find(d,expression) then - --- todo, test for readable - result[#result+1] = fl[3] + -- todo, test for readable + result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut done = true if allresults then if trace_detail then @@ -11980,6 +12014,13 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } +-- It could be interesting to hook the resolver in the file +-- opener so that unresolved prefixes travel around and we +-- get more abstraction. + +-- As we use this beforehand we will move this up in the chain +-- of loading. + local upper, lower, gsub = string.upper, string.lower, string.gsub @@ -11987,10 +12028,10 @@ local resolvers = resolvers local prefixes = { } -local getenv = resolvers.getenv +local getenv, cleanpath, findgivenfile = resolvers.getenv, resolvers.cleanpath, resolvers.findgivenfile prefixes.environment = function(str) -- getenv is case insensitive anyway - return resolvers.cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") + return cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") end prefixes.relative = function(str,n) @@ -12009,7 +12050,7 @@ prefixes.relative = function(str,n) end end end - return resolvers.cleanpath(str) + return cleanpath(str) end prefixes.auto = function(str) @@ -12021,20 +12062,38 @@ prefixes.auto = function(str) end prefixes.locate = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath((fullname ~= "" and fullname) or str) + local fullname = findgivenfile(str) or "" + return cleanpath((fullname ~= "" and fullname) or str) end prefixes.filename = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.basename((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.basename((fullname ~= "" and fullname) or str)) end prefixes.pathname = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.dirname((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.dirname((fullname ~= "" and fullname) or str)) end +prefixes.selfautoloc = function(str) + return cleanpath(file.join(getenv('SELFAUTOLOC'),str)) +end + +prefixes.selfautoparent = function(str) + return cleanpath(file.join(getenv('SELFAUTOPARENT'),str)) +end + +prefixes.selfautodir = function(str) + return cleanpath(file.join(getenv('SELFAUTODIR'),str)) +end + +prefixes.home = function(str) + return cleanpath(file.join(getenv('HOME'),str)) +end + +prefixes["~"] = prefixes.home + prefixes.env = prefixes.environment prefixes.rel = prefixes.relative prefixes.loc = prefixes.locate @@ -12061,19 +12120,26 @@ local function _resolve_(method,target) end end -local function resolve(str) - if type(str) == "table" then - for k=1,#str do - local v = str[k] - str[k] = resolve(v) or v - end - elseif str and str ~= "" then - str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_) + +local resolved = { } +local abstract = { } + +local function resolve(str) -- use schemes, this one is then for the commandline only + local res = resolved[str] + if not res then + res = gsub(str,"([a-z][a-z]+):([^ \"\']*)",_resolve_) + resolved[str] = res + abstract[res] = str end - return str + return res end -resolvers.resolve = resolve +local function unresolve(str) + return abstract[str] or str +end + +resolvers.resolve = resolve +resolvers.unresolve = unresolve if os.uname then @@ -12166,9 +12232,10 @@ local checkgarbage = utilities.garbagecollector and utilities.garbagecollector.c function locators.file(specification) local name = specification.filename - if name and name ~= '' and lfs.isdir(name) then + local realname = resolvers.resolve(name) -- no shortcut + if realname and realname ~= '' and lfs.isdir(realname) then if trace_locating then - report_resolvers("file locator '%s' found",name) + report_resolvers("file locator '%s' found as '%s'",name,realname) end resolvers.appendhash('file',name,true) -- cache elseif trace_locating then @@ -12183,9 +12250,9 @@ function hashers.file(specification) end function generators.file(specification) - local name = specification.filename - local content = resolvers.scanfiles(name) - resolvers.registerfilehash(name,content,true) + local path = specification.filename + local content = resolvers.scanfiles(path) + resolvers.registerfilehash(path,content,true) end concatinators.file = file.join diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua index 1e40bbc7b..132ad32c7 100644 --- a/tex/context/base/anch-pos.lua +++ b/tex/context/base/anch-pos.lua @@ -12,9 +12,15 @@ can we store much more information in <l n='lua'/> but it's also more efficient.</p> --ldx]]-- -local concat, format = table.concat, string.format +-- to be considered: store as numbers instead of string +-- maybe replace texsp by our own converter (stay at the lua end) + +local tostring = tostring +local concat, format, gmatch = table.concat, string.format, string.gmatch local lpegmatch = lpeg.match local allocate, mark = utilities.storage.allocate, utilities.storage.mark +local texsp = tex.sp +----- texsp = string.todimen -- because we cache this is much faster but no rounding local collected, tobesaved = allocate(), allocate() @@ -27,7 +33,7 @@ job.positions = jobpositions _ptbs_, _pcol_ = tobesaved, collected -- global -local dx, dy = "0pt", "0pt" +local dx, dy, nx, ny = "0pt", "0pt", 0, 0 local function initializer() tobesaved = mark(jobpositions.tobesaved) @@ -35,8 +41,8 @@ local function initializer() _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" + -- dx, nx = p[2] or "0pt", 0 + -- dy, ny = p[3] or "0pt", 0 end end @@ -52,49 +58,239 @@ end function jobpositions.page(id) local jpi = collected[id] or tobesaved[id] - context(jpi and jpi[1] or '0') + if jpi then + return texsp(jpi[1]) + else + return 0 + end +end + +function jobpositions.x(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) - nx + else + return 0 + end +end + +function jobpositions.y(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[3]) - ny + else + return 0 + end end function jobpositions.width(id) local jpi = collected[id] or tobesaved[id] - context(jpi and jpi[4] or '0pt') + if jpi then + return texsp(jpi[4]) + else + return 0 + end end function jobpositions.height(id) local jpi = collected[id] or tobesaved[id] - context(jpi and jpi[5] or '0pt') + if jpi then + return texsp(jpi[5]) + else + return 0 + end end function jobpositions.depth(id) local jpi = collected[id] or tobesaved[id] - context(jpi and jpi[6] or '0pt') + if jpi then + return texsp(jpi[6]) + else + return 0 + end end -function jobpositions.x(id) +function jobpositions.xy(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) - nx, texsp(jpi[3]) - ny + else + return 0, 0 + end +end + +function jobpositions.lowerleft(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) - nx, texsp(jpi[3]) - texsp(jpi[6]) - ny + else + return 0, 0 + end +end + +function jobpositions.lowerright(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) + texsp(jpi[4]) - nx, texsp(jpi[3]) - texsp(jpi[6]) - ny + else + return 0, 0 + end +end + +function jobpositions.upperright(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) + texsp(jpi[4]) - nx, texsp(jpi[3]) + texsp(jpi[5]) - ny + else + return 0, 0 + end +end + +function jobpositions.upperleft(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[2]) - nx, texsp(jpi[3]) + texsp(jpi[5]) - ny + else + return 0, 0 + end +end + +function jobpositions.position(id) + local jpi = collected[id] or tobesaved[id] + if jpi then + return texsp(jpi[1]), texsp(jpi[2]), texsp(jpi[3]), texsp(jpi[4]), texsp(jpi[5]), texsp(jpi[6]) + else + return 0, 0, 0, 0, 0, 0 + end +end + +function jobpositions.extra(id,n,default) -- assume numbers + local jpi = collected[id] or tobesaved[id] + if not jpi then + return default + else + local split = jpi[0] + if not split then + split = lpegmatch(splitter,jpi[7]) + jpi[0] = split + end + return texsp(split[n]) or default + end +end + +local function overlapping(one,two,overlappingmargin) + one = collected[one] or tobesaved[one] + two = collected[two] or tobesaved[two] + if one and two and one[1] == two[1] then + if not overlappingmargin then + overlappingmargin = 2 + end + local x_one = one[2] + local x_two = two[2] + local w_two = two[4] + local llx_one = x_one - overlappingmargin + local urx_two = x_two + w_two + overlappingmargin + if llx_one > urx_two then + return false + end + local w_one = one[4] + local urx_one = x_one + w_one + overlappingmargin + local llx_two = x_two - overlappingmargin + if urx_one < llx_two then + return false + end + local y_one = one[3] + local y_two = two[3] + local d_one = one[6] + local h_two = two[5] + local lly_one = y_one - d_one - overlappingmargin + local ury_two = y_two + h_two + overlappingmargin + if lly_one > ury_two then + return false + end + local h_one = one[5] + local d_two = two[6] + local ury_one = y_one + h_one + overlappingmargin + local lly_two = y_two - d_two - overlappingmargin + if ury_one < lly_two then + return false + end + return true + end +end + +local function onsamepage(list,page) + for id in gmatch(list,"(, )") do + local jpi = collected[id] or tobesaved[id] + if jpi then + local p = jpi[1] + if not page then + page = p + elseif page ~= p then + return false + end + end + end + return page +end + +jobpositions.overlapping = overlapping +jobpositions.onsamepage = onsamepage + +-- interface + +commands.replacepospxywhd = jobpositions.replace +commands.copyposition = jobpositions.copy + +function commands.MPp(id) + local jpi = collected[id] or tobesaved[id] + context(jpi and jpi[1] or '0') +end + +function commands.MPx(id) local jpi = collected[id] or tobesaved[id] local x = jpi and jpi[2] if x then - context('\\the\\dimexpr%s-%s\\relax',x,dx) + if nx == 0 then + context(x) + else + context('\\the\\dimexpr%s-%s\\relax',x,dx) + end else context('0pt') end end -function jobpositions.y(id) +function commands.MPy(id) local jpi = collected[id] or tobesaved[id] local y = jpi and jpi[3] if y then - context('\\the\\dimexpr%s-%s\\relax',y,dy) + if ny == 0 then + context(y) + else + context('\\the\\dimexpr%s-%s\\relax',y,dy) + end else context('0pt') end end --- the following are only for MP so there we can leave out the pt +function commands.MPw(id) + local jpi = collected[id] or tobesaved[id] + context(jpi and jpi[4] or '0pt') +end --- can be writes and no format needed any more +function commands.MPh(id) + local jpi = collected[id] or tobesaved[id] + context(jpi and jpi[5] or '0pt') +end -function jobpositions.xy(id) +function commands.MPd(id) + local jpi = collected[id] or tobesaved[id] + context(jpi and jpi[6] or '0pt') +end + +function commands.MPxy(id) local jpi = collected[id] or tobesaved[id] if jpi then context('(%s-%s,%s-%s)',jpi[2],dx,jpi[3],dy) @@ -103,7 +299,7 @@ function jobpositions.xy(id) end end -function jobpositions.lowerleft(id) +function commands.MPll(id) local jpi = collected[id] or tobesaved[id] if jpi then context('(%s-%s,%s-%s-%s)',jpi[2],dx,jpi[3],jpi[6],dy) @@ -112,7 +308,7 @@ function jobpositions.lowerleft(id) end end -function jobpositions.lowerright(id) +function commands.MPlr(id) local jpi = collected[id] or tobesaved[id] if jpi then context('(%s+%s-%s,%s-%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[6],dy) @@ -121,7 +317,7 @@ function jobpositions.lowerright(id) end end -function jobpositions.upperright(id) +function commands.MPur(id) local jpi = collected[id] or tobesaved[id] if jpi then context('(%s+%s-%s,%s+%s-%s)',jpi[2],jpi[4],dx,jpi[3],jpi[5],dy) @@ -130,7 +326,7 @@ function jobpositions.upperright(id) end end -function jobpositions.upperleft(id) +function commands.MPul(id) local jpi = collected[id] or tobesaved[id] if jpi then context('(%s-%s,%s+%s-%s)',jpi[2],dx,jpi[3],jpi[5],dy) @@ -139,7 +335,7 @@ function jobpositions.upperleft(id) end end -function jobpositions.position(id) +function commands.MPpos(id) local jpi = collected[id] or tobesaved[id] if jpi then context(concat(jpi,',',1,6)) @@ -150,7 +346,7 @@ end local splitter = lpeg.Ct(lpeg.splitat(",")) -function jobpositions.pardata(id,n,default) +function commands.MPplus(id,n,default) local jpi = collected[id] or tobesaved[id] if not jpi then context(default) @@ -164,30 +360,25 @@ function jobpositions.pardata(id,n,default) end end -function jobpositions.extradata(id,default) +function commands.MPrest(id,default) local jpi = collected[id] or tobesaved[id] context(jpi and jpi[7] or default) end --- interface - -commands.replacepospxywhd = jobpositions.replace -commands.copyposition = jobpositions.copy -commands.MPp = jobpositions.page -commands.MPx = jobpositions.x -commands.MPy = jobpositions.y -commands.MPw = jobpositions.width -commands.MPh = jobpositions.height -commands.MPd = jobpositions.depth -commands.MPxy = jobpositions.xy -commands.MPll = jobpositions.lowerleft -commands.MPlr = jobpositions.lowerright -commands.MPur = jobpositions.upperright -commands.MPul = jobpositions.upperleft -commands.MPpos = jobpositions.position -commands.MPplus = jobpositions.pardata -commands.MPrest = jobpositions.extradata +-- is testcase already defined? if so, then local function commands.doifpositionelse(name) commands.testcase(collected[name] or tobesaved[name]) end + +function commands.doifoverlappingelse(one,two,overlappingmargin) + commands.testcase(overlapping(one,two,overlappingmargin)) +end + +function commands.doifpositionsonsamepageelse(list,page) + commands.testcase(onsamepage(list)) +end + +function commands.doifpositionsonthispageelse(list) + commands.testcase(onsamepage(list,tostring(tex.count.realpageno))) +end diff --git a/tex/context/base/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv index 888cb60eb..dc231bcff 100644 --- a/tex/context/base/anch-pos.mkiv +++ b/tex/context/base/anch-pos.mkiv @@ -15,7 +15,6 @@ % related code to meta-pos % shorter tags, ..:achtergrond:.. etc in pos actions - % dubbele text- * pos's eruit % class pos -> als gelijk aan vorige, dan niet niet definieren @@ -107,8 +106,6 @@ %D method is implemented in a special driver. If needed, the %D driver can fall back on the following macros. -% 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"}}}} @@ -156,7 +153,7 @@ %D Sometimes we want to trick the position handler a bit: -\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{commands.replacepospxywhd('#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{\ctxcommand{replacepospxywhd('#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. @@ -193,18 +190,18 @@ %D with short names that are clearly meant for \METAPOST\ but %D nowadays also used for other purposes. -\def\MPp #1{\ctxlua{commands.MPp("#1")}} -\def\MPx #1{\ctxlua{commands.MPx("#1")}} -\def\MPy #1{\ctxlua{commands.MPy("#1")}} -\def\MPw #1{\ctxlua{commands.MPw("#1")}} -\def\MPh #1{\ctxlua{commands.MPh("#1")}} -\def\MPd #1{\ctxlua{commands.MPd("#1")}} -\def\MPxy #1{\ctxlua{commands.MPxy("#1")}} -\def\MPll #1{\ctxlua{commands.MPll("#1")}} -\def\MPlr #1{\ctxlua{commands.MPlr("#1")}} -\def\MPur #1{\ctxlua{commands.MPur("#1")}} -\def\MPul #1{\ctxlua{commands.MPul("#1")}} -\def\MPpos#1{\ctxlua{commands.MPpos("#1")}} +\def\MPp #1{\ctxcommand{MPp("#1")}} +\def\MPx #1{\ctxcommand{MPx("#1")}} +\def\MPy #1{\ctxcommand{MPy("#1")}} +\def\MPw #1{\ctxcommand{MPw("#1")}} +\def\MPh #1{\ctxcommand{MPh("#1")}} +\def\MPd #1{\ctxcommand{MPd("#1")}} +\def\MPxy #1{\ctxcommand{MPxy("#1")}} +\def\MPll #1{\ctxcommand{MPll("#1")}} +\def\MPlr #1{\ctxcommand{MPlr("#1")}} +\def\MPur #1{\ctxcommand{MPur("#1")}} +\def\MPul #1{\ctxcommand{MPul("#1")}} +\def\MPpos#1{\ctxcommand{MPpos("#1")}} %D \macros %D {MPplus, MPrest, MPv, MPvv} @@ -226,8 +223,8 @@ %D %D The extra parameters are not treated. -\def\MPplus#1#2#3{\ctxlua{commands.MPplus("#1",#2,"#3")}} \let\MPv \MPplus -\def\MPrest #1#2{\ctxlua{commands.MPrest("#1","#2")}} \let\MPvv\MPrest +\def\MPplus#1#2#3{\ctxcommand{MPplus("#1",#2,"#3")}} \let\MPv \MPplus +\def\MPrest #1#2{\ctxcommand{MPrest("#1","#2")}} \let\MPvv\MPrest %D \macros %D {MPanchor} @@ -243,9 +240,7 @@ \def\initializenextposition {\ifpositioning \else \global\positioningtrue - \dosetpositionpapersize - {\printpaperwidth }% - {\printpaperheight}% + \dosetpositionpapersize\printpaperwidth\printpaperheight \fi \global\advance\currentpositions\plusone} @@ -380,7 +375,7 @@ %D %D Again, this is a global action. -\def\copyposition#1#2{\ctxlua{commands.copyposition('#1','#2')}} +\def\copyposition#1#2{\ctxcommand{copyposition('#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 @@ -390,7 +385,7 @@ %D \doifpositionelse {identifier} {found action} {not found action} %D \stoptyping -\def\doifpositionelse#1{\ctxlua{commands.doifpositionelse('#1')}} +\def\doifpositionelse#1{\ctxcommand{doifpositionelse('#1')}} %D We have now arrived at a few macros that would make sense as %D support macros, but ended up in the core. @@ -493,27 +488,12 @@ \let\registerparoptions\relax -% \def\doregisterparoptions -% {\ifpositioningpar \ifpositioning \iftrialtypesetting \else -% \ifinpagebody \else \ifmmode \else \ifinformula \else -% % \ifprocessingverbatim -% % \iflinepar -% % % obsolete: \dodoregisterparoptions -% % \fi -% % \else -% \dodoregisterparoptions -% % \fi -% \fi \fi \fi -% \fi \fi \fi} - \def\doregisterparoptions - {%\ifpositioningpar \ifpositioning % true anyway - \iftrialtypesetting \else - \ifinpagebody \else \ifmmode \else \ifinformula \else - \dodoregisterparoptions - \fi \fi \fi - \fi - }%\fi \fi} + {\iftrialtypesetting \else + \ifinpagebody \else \ifmmode \else \ifinformula \else + \dodoregisterparoptions + \fi \fi \fi + \fi} \def\dodoregisterparoptions {\global\advance\parposcounter\plusone @@ -676,60 +656,7 @@ %D {action when not overlapping} %D \stoptyping -\def\overlappingmargin{-2\scaledpoint} - -\def\overlappingcheckone#1#2% - {\ifdim#1<\!!dimena \else \ifdim#1>\!!dimenb \else - \ifdim#2<\!!dimenc \else \ifdim#2>\!!dimend \else - \donetrue - \fi\fi - \fi\fi} - -\def\overlappingchecktwo#1#2% - {\ifdim#1<\!!dimene \else \ifdim#1>\!!dimenf \else - \ifdim#2<\!!dimeng \else \ifdim#2>\!!dimenh \else - \donetrue - \fi\fi - \fi\fi} - -\def\doifoverlappingelse#1#2% maybe do this in lua - {\begingroup - \donefalse - \edef\!!stringa{#1}\edef\!!stringb{#2}% - \ifnum\MPp\!!stringa=\MPp\!!stringb\relax - \!!dimena\MPx\!!stringa - \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax - \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax - \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax - \!!dimene\MPx\!!stringb - \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax - \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax - \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax - \ifdim\overlappingmargin=\zeropoint\else - \advance\!!dimena-\overlappingmargin - \advance\!!dimenb+\overlappingmargin - \advance\!!dimenc-\overlappingmargin - \advance\!!dimend+\overlappingmargin - \advance\!!dimene-\overlappingmargin - \advance\!!dimenf+\overlappingmargin - \advance\!!dimeng-\overlappingmargin - \advance\!!dimenh+\overlappingmargin - \fi - % more often eh fb eg fg - \overlappingcheckone\!!dimene\!!dimeng \ifdone \else - \overlappingcheckone\!!dimene\!!dimenh \ifdone \else - \overlappingcheckone\!!dimenf\!!dimeng \ifdone \else - \overlappingcheckone\!!dimenf\!!dimenh \ifdone \else - \overlappingchecktwo\!!dimena\!!dimenc \ifdone \else - \overlappingchecktwo\!!dimena\!!dimend \ifdone \else - \overlappingchecktwo\!!dimenb\!!dimene \ifdone \else - \overlappingchecktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi - \fi - \ifdone - \endgroup\expandafter\firstoftwoarguments - \else - \endgroup\expandafter\secondoftwoarguments - \fi} +\def\doifoverlappingelse#1#2{\ctxcommand{doifoverlappingelse("#1","#2")}} %D \macros %D {doifpositionsonsamepageelse, @@ -747,33 +674,13 @@ %D {action when not on this page} %D \stoptyping -% todo: move to lua when we really use it - -\def\dododoifpositionsonsamepageelse#1% - {\ifcase\scratchcounter - \scratchcounter\MPp{#1}\donetrue - \else - \ifnum\scratchcounter=\MPp{#1}\relax\else\donefalse\fi - \fi}% - -\def\dodoifpositionsonsamepageelse#1#2% - {\begingroup - \scratchcounter#1\donefalse - \rawprocesscommalist[#2]\dododoifpositionsonsamepageelse - \ifdone - \endgroup\expandafter\firstoftwoarguments - \else - \endgroup\expandafter\secondoftwoarguments - \fi} - -\def\doifpositionsonsamepageelse{\dodoifpositionsonsamepageelse\zerocount } -\def\doifpositionsonthispageelse{\dodoifpositionsonsamepageelse\realpageno} +\def\doifpositionsonsamepageelse#1{\ctxcommand{doifpositionsonsamepageelse("#1")}} +\def\doifpositionsonthispageelse#1{\ctxcommand{doifpositionsonthispageelse("#1")}} %D Plugins: -\let\MPv \MPplus -\let\MPvv\MPrest - +\let\MPv \MPplus +\let\MPvv \MPrest \let\MPanchor\MPpos %D \macros diff --git a/tex/context/base/attr-col.mkiv b/tex/context/base/attr-col.mkiv index 5b09bf38b..8d61ee8ae 100644 --- a/tex/context/base/attr-col.mkiv +++ b/tex/context/base/attr-col.mkiv @@ -28,29 +28,29 @@ % % color (layer on top) % % \def\dosetcolormodel#1% overloaded later -% {\ctxlua{commands.setcolormodel('#1')}} % sets attribute +% {\ctxcommand{setcolormodel('#1')}} % sets attribute % % \dosetcolormodel{all} % % \def\registerrgbcolor#1#2#3#4% not used -% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxlua{commands.registercolor('#1','rgb' ,#2,#3,#4)}}} +% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxcommand{registercolor('#1','rgb' ,#2,#3,#4)}}} % % \def\registercmykcolor#1#2#3#4#5% not used -% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxlua{commands.registercolor('#1','cmyk',#2,#3,#4,#5)}}} +% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxcommand{registercolor('#1','cmyk',#2,#3,#4,#5)}}} % % \def\registergraycolor#1#2% not used -% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxlua{commands.registercolor('#1','gray',#2)}}} +% {\setevalue{(cs:#1)}{\attribute\colorattribute\ctxcommand{registercolor('#1','gray',#2)}}} % % transparency (layer on top) % % \def\registertransparency#1#2#3% -% {\setevalue{(ts:#1)}{\attribute\transparencyattribute\ctxlua{commands.registertransparency(#2,#3)} }} +% {\setevalue{(ts:#1)}{\attribute\transparencyattribute\ctxcommand{registertransparency(#2,#3)} }} % % \def\sometransparencyswitch#1% % {\csname(ts:#1)\endcsname} % % \def\sometransparencyswitch -% {\ctxlua{commands.enabletransparency()}% +% {\ctxcommand{enabletransparency()}% % \gdef\sometransparencyswitch##1{\csname(ts:##1)\endcsname}% % \sometransparencyswitch} % @@ -60,10 +60,10 @@ % overprint \def\registercolorintent#1#2% - {\setevalue{(os:#1)}{\attribute\colorintentattribute\ctxlua{commands.registercolorintent('#2')} }} + {\setevalue{(os:#1)}{\attribute\colorintentattribute\ctxcommand{registercolorintent('#2')} }} \def\dotriggercolorintent - {\ctxlua{commands.enablecolorintents()}% + {\ctxcommand{enablecolorintents()}% \gdef\dotriggercolorintent##1{\csname(os:##1)\endcsname}% \dotriggercolorintent} diff --git a/tex/context/base/attr-eff.mkiv b/tex/context/base/attr-eff.mkiv index 1b9adf718..3526276c7 100644 --- a/tex/context/base/attr-eff.mkiv +++ b/tex/context/base/attr-eff.mkiv @@ -19,10 +19,10 @@ % \def\registereffect#1#2#3% #2=stretch #3=rulethickness % {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}% todo: set attribute at lua end -% {\attribute\effectattribute\ctxlua{commands.registereffect('#1',#2,\number\dimexpr#3\relax)}\relax}} +% {\attribute\effectattribute\ctxcommand{registereffect('#1',#2,\number\dimexpr#3\relax)}\relax}} % % \def\dotriggereffect -% {\ctxlua{commands.enableeffect()}% can then move to caller +% {\ctxcommand{enableeffect()}% can then move to caller % \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}% @@ -30,10 +30,10 @@ % % \def\registereffect#1#2#3% #2=stretch #3=rulethickness % {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}% todo: set attribute at lua end -% {\attribute\effectattribute\ctxlua{commands.registereffect('#1',#2,\number\dimexpr#3\relax)}\relax}} +% {\attribute\effectattribute\ctxcommand{registereffect('#1',#2,\number\dimexpr#3\relax)}\relax}} \gdef\dotriggereffect#1#2#3% - {\ctxlua{commands.triggereffect('#1',#2,\number\dimexpr#3\relax)}} + {\ctxcommand{triggereffect('#1',#2,\number\dimexpr#3\relax)}} \unexpanded\def\setupeffect {\dodoubleargument\dosetupeffect} diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv index eccb5ffbc..5de366ed9 100644 --- a/tex/context/base/attr-ini.mkiv +++ b/tex/context/base/attr-ini.mkiv @@ -43,7 +43,7 @@ {\expandafter\newattribute\csname @attr@#1\endcsname \expandafter\newconstant \csname :attr:#1\endcsname \csname :attr:#1\endcsname\lastallocatedattribute - \ctxlua{commands.defineattribute("#1",\number\lastallocatedattribute)}% + \ctxcommand{defineattribute("#1",\number\lastallocatedattribute)}% %\writestatus\m!systems{defining attribute #1 with number \number\lastallocatedattribute}% \doifnotinset\s!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}% \doifinset \s!public{#2}{\expandafter\let\csname#1attribute\expandafter\endcsname\csname :attr:#1\endcsname}} @@ -52,7 +52,7 @@ {\dodoubleempty\dodefinesystemattribute} \def\dodefinesystemattribute[#1][#2]% alternatively we can let lua do the housekeeping - {\scratchcounter\ctxlua{commands.getprivateattribute("#1")}\relax + {\scratchcounter\ctxcommand{getprivateattribute("#1")}\relax \expandafter\attributedef\csname @attr@#1\endcsname\scratchcounter \expandafter\newconstant \csname :attr:#1\endcsname \csname :attr:#1\endcsname\scratchcounter diff --git a/tex/context/base/attr-neg.mkiv b/tex/context/base/attr-neg.mkiv index 402af0bf5..2b817bb71 100644 --- a/tex/context/base/attr-neg.mkiv +++ b/tex/context/base/attr-neg.mkiv @@ -19,7 +19,7 @@ % positive and negative are preregistered -\def\dotriggernegative#1{\ctxlua{commands.triggernegative('#1'))}} +\def\dotriggernegative#1{\ctxcommand{triggernegative('#1'))}} \unexpanded\def\startnegative{\dotriggernegative\v!negative} \unexpanded\def\stopnegative {\dotriggernegative\v!positive} diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv index f4200635c..681be325f 100644 --- a/tex/context/base/bibl-bib.mkiv +++ b/tex/context/base/bibl-bib.mkiv @@ -123,11 +123,11 @@ \unexpanded\def\setupbibtexsession {\dodoubleargument\dosetupbibtexsession} \def\dodefinebibtexsession [#1]{\edef\currentbibtexsession{#1}% - \ctxlua{commands.definebibtexsession("#1")}% + \ctxcommand{definebibtexsession("#1")}% \the\everydefinebibtexsession} \def\dopreparebibtexsession[#1][#2]{\edef\currentbibtexsession{#1}% - \ctxlua{commands.preparebibtexsession("#1","bibtex:#1","#2")}% + \ctxcommand{preparebibtexsession("#1","bibtex:#1","#2")}% \the\everypreparebibtexsession} \def\dosetupbibtexsession [#1][#2]{\edef\currentbibtexsession{#1}% @@ -138,8 +138,8 @@ \def\registerbibtexentry {\dodoubleargument\doregisterbibtexentry} \def\applytobibtexsession {\dodoubleargument\doapplytobibtexsession} -\def\doregisterbibtexfile [#1][#2]{\ctxlua{commands.registerbibtexfile("#1","#2")}} -\def\doregisterbibtexentry [#1][#2]{\ctxlua{commands.registerbibtexentry("#1","#2")}} +\def\doregisterbibtexfile [#1][#2]{\ctxcommand{registerbibtexfile("#1","#2")}} +\def\doregisterbibtexentry [#1][#2]{\ctxcommand{registerbibtexentry("#1","#2")}} \def\doapplytobibtexsession[#1][#2]{\xmlprocessregistered{bibtex:#1}{#2}{#2}} \unexpanded\def\bibtexcommand#1% diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv index c90e08e7f..7bd382fe2 100644 --- a/tex/context/base/buff-ini.mkiv +++ b/tex/context/base/buff-ini.mkiv @@ -25,13 +25,13 @@ \let\currentbuffer\empty \def\doifelsebuffer#1% - {\ctxlua{commands.doifelsebuffer("#1")}} + {\ctxcommand{doifelsebuffer("#1")}} \def\resetbuffer {\dosingleempty\doresetbuffer} \def\doresetbuffer[#1]% - {\ctxlua{commands.erasebuffer("#1")}} + {\ctxcommand{erasebuffer("#1")}} \unexpanded\def\dostartdefinedbuffer {\bgroup @@ -65,13 +65,13 @@ \unexpanded\long\def\dodowithbuffer#1#2#3#4#5% name, startsequence, stopsequence, before, after {#4% \bgroup - \ctxlua{commands.erasebuffer("#1")}% + \ctxcommand{erasebuffer("#1")}% \setcatcodetable \vrbcatcodes \long\def\nododowithbuffer {\egroup #5}% \long\def\dododowithbuffer##1#3% is detokenize needed? TEST - {\ctxlua{commands.grabbuffer("#1","#2","#3",\!!bs\detokenize{##1}\!!es)} % space ? + {\ctxcommand{grabbuffer("#1","#2","#3",\!!bs\detokenize{##1}\!!es)} % space ? \dododowithbuffer \nododowithbuffer}% \dododowithbuffer} @@ -82,7 +82,7 @@ \let\endbuffer\relax \long\def\dosetbuffer[#1]#2\endbuffer % seldom used so we just pass #2 - {\ctxlua{commands.assignbuffer("#1", \!!bs\detokenize{#2}\!!es)}} + {\ctxcommand{assignbuffer("#1", \!!bs\detokenize{#2}\!!es)}} \def\namedbufferparameter#1#2{\csname\??bu#1#2\endcsname} @@ -147,7 +147,7 @@ \namedbufferparameter{#1}\c!after} \def\dododogetbuffer#1% - {\ctxlua{commands.getbuffer("#1")}} + {\ctxcommand{getbuffer("#1")}} \definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!before=,\c!after=] @@ -167,7 +167,7 @@ \unexpanded\def\savebuffer{\dodoubleempty\dosavebuffer} -\def\dosavebuffer[#1][#2]{\ctxlua{commands.savebuffer("#1","#2")}} +\def\dosavebuffer[#1][#2]{\ctxcommand{savebuffer("#1","#2")}} %D Experimental: no expansion of commands in buffer! @@ -184,7 +184,7 @@ \def\mkvibuffer {\dosingleempty\domkvibuffer} \def\mkvibufferraw{\dosingleempty\domkvibufferraw} -\def\doctxluabuffer [#1]{\ctxlua{commands.getbufferctxlua("#1")}} -\def\domkvibuffer [#1]{\ctxlua{commands.getbuffermkvi("#1")}} +\def\doctxluabuffer [#1]{\ctxcommand{getbufferctxlua("#1")}} +\def\domkvibuffer [#1]{\ctxcommand{getbuffermkvi("#1")}} \protect \endinput diff --git a/tex/context/base/buff-par.mkiv b/tex/context/base/buff-par.mkiv index ad7d298e0..c44a75050 100644 --- a/tex/context/base/buff-par.mkiv +++ b/tex/context/base/buff-par.mkiv @@ -37,7 +37,7 @@ {\dodoubleargument\dodefineparallel} \def\dodefineparallel[#1][#2]% - {\ctxlua{commands.defineparallel("#1","#2")}% + {\ctxcommand{defineparallel("#1","#2")}% \processcommalist[#2]\dododefineparallel \setuvalue{\e!start#1}{\dostartparallelset{#1}}% \setuvalue{\e!stop #1}{\dostopparallelset}} @@ -48,13 +48,13 @@ \def\dostartparallelset#1% {\def\currentparallel{#1}% - \ctxlua{commands.nextparallel("\currentparallel")}} + \ctxcommand{nextparallel("\currentparallel")}} \def\dostopparallelset#1% {} \def\dowithparallel#1% defined moet ook aan de lua kant kunnen - {\ctxlua{commands.saveparallel("\currentparallel","#1",buffers.raw("\thedefinedbuffer{#1}"))}} + {\ctxcommand{saveparallel("\currentparallel","#1",buffers.raw("\thedefinedbuffer{#1}"))}} \unexpanded\def\placeparallel {\dotripleempty\doplaceparallel} @@ -62,7 +62,7 @@ \def\doplaceparallel[#1][#2][#3]% {\begingroup \def\currentparallel{#1}% - \ctxlua{commands.placeparallel("\currentparallel","#2","#3")}% + \ctxcommand{placeparallel("\currentparallel","#2","#3")}% \endgroup} % was: \parallelparameter\c!command} @@ -124,7 +124,7 @@ {\dodoubleempty\doresetparallel} \def\resetparallel[#1][#2]% - {\ctxlua{commands.resetparallel("#1","#2"))}} + {\ctxcommand{resetparallel("#1","#2"))}} % default @@ -148,4 +148,4 @@ % {\grabuntil{\e!stop#1}{\dododostartparallel{#1}}} % % \def\dododostartparallel#1#2% -% {\ctxlua{commands.saveparallel("\currentparallel","#1",\!!bs\detokenize{#2}\!!es)}} +% {\ctxcommand{saveparallel("\currentparallel","#1",\!!bs\detokenize{#2}\!!es)}} diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index 3e571bab1..6cb8e9cac 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -346,7 +346,7 @@ \def\dodotypenormal#1% {\secondstageinitializetype \dostarttagged\t!verbatim\currenttype - \ctxlua{commands.typestring { + \ctxcommand{typestring { data = \!!bs\detokenize{#1}\!!es, tab = "\typeparameter\c!tab", method = "\typeparameter\c!option", @@ -359,7 +359,7 @@ \def\dodotypenested#1% {\secondstageinitializetype \dostarttagged\t!verbatim\currenttype - \ctxlua{commands.typestring { + \ctxcommand{typestring { data = \!!bs\detokenize{#1}\!!es, tab = "\typeparameter\c!tab", method = "nested", % we force a special visualizer @@ -468,7 +468,7 @@ {\secondstageinitializetyping \beginofverbatimlines \dostarttagged\t!verbatimblock\currenttyping - \ctxlua{commands.typebuffer { + \ctxcommand{typebuffer { name = "_typing_", strip = "\typingparameter\c!strip", range = "\typingparameter\c!range", @@ -580,7 +580,7 @@ \secondstageinitializetyping \beginofverbatimlines \dostarttagged\t!verbatimblock\currenttyping - \ctxlua{commands.typefile { + \ctxcommand{typefile { name = "#2", strip = "\typingparameter\c!strip", range = "\typingparameter\c!range", @@ -742,7 +742,7 @@ \secondstageinitializetyping \beginofverbatimlines \dostarttagged\t!verbatim{#1}% - \ctxlua{commands.typebuffer { + \ctxcommand{typebuffer { name = "#2", strip = "\typingparameter\c!strip", range = "\typingparameter\c!range", @@ -782,7 +782,7 @@ \def\dodoprocessbuffer#1#2% {\edef\currenttyping{#1}% - \ctxlua{commands.processbuffer { + \ctxcommand{processbuffer { name = "#2", strip = "\typingparameter\c!strip", tab = "\typingparameter\c!tab", diff --git a/tex/context/base/chem-ini.mkiv b/tex/context/base/chem-ini.mkiv index 5184fe1a7..c64575181 100644 --- a/tex/context/base/chem-ini.mkiv +++ b/tex/context/base/chem-ini.mkiv @@ -35,7 +35,7 @@ %D %D \typebuffer \getbuffer -\def\molecule#1{\ctxlua{commands.molecule(\!!bs#1\!!es)}} +\def\molecule#1{\ctxcommand{molecule(\!!bs#1\!!es)}} %D For old times sake: diff --git a/tex/context/base/cldf-com.lua b/tex/context/base/cldf-com.lua index caffe44ce..e966b167b 100644 --- a/tex/context/base/cldf-com.lua +++ b/tex/context/base/cldf-com.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['cldf-com'] = { version = 1.001, - comment = "companion to cldf-ini.mkiv", + comment = "companion to cldf-com.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" diff --git a/tex/context/base/cldf-com.mkiv b/tex/context/base/cldf-com.mkiv new file mode 100644 index 000000000..43071a580 --- /dev/null +++ b/tex/context/base/cldf-com.mkiv @@ -0,0 +1,19 @@ +%D \module +%D [ file=cldf-com, +%D version=2010.10.19,, +%D title=\CONTEXT\ \LUA\ Document Functions, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=Hans Hagen] +%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 Lua Documents / Functions} + +\registerctxluafile{cldf-com}{1.001} +\registerctxluafile{cldf-ver}{1.001} + +\endinput diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua index 89c5bfe58..42333a65f 100644 --- a/tex/context/base/cldf-ini.lua +++ b/tex/context/base/cldf-ini.lua @@ -6,4 +6,748 @@ if not modules then modules = { } end modules ['cldf-ini'] = { license = "see context related readme files" } --- This is a placeholder, maybe mult-cld moves here. +-- This is an experiment: generating context code at the lua end. After all +-- it is surprisingly simple to implement due to metatables. I was wondering +-- if there was a more natural way to deal with commands at the lua end. +-- Of course it's a bit slower but often more readable when mixed with lua +-- code. It can also be handy when generating documents from databases or +-- when constructing large tables or so. +-- +-- Todo: optional checking against interface +-- Todo: coroutine trickery +-- Todo: maybe use txtcatcodes + +-- tflush needs checking ... sort of weird that it's not a table + +-- __flushlines is an experiment and rather ugly so it will go away + +context = context or { } +local context = context + +local format, find, gmatch, splitlines = string.format, string.find, string.gmatch, string.splitlines +local next, type, tostring, setmetatable = next, type, tostring, setmetatable +local insert, remove, concat = table.insert, table.remove, table.concat +local lpegmatch = lpeg.match + +local tex = tex + +local texsprint = tex.sprint +local textprint = tex.tprint +local texprint = tex.print +local texiowrite = texio.write +local texcount = tex.count + +local isnode = node.is_node -- after 0.65 just node.type +local writenode = node.write +local copynodelist = node.copylist + +local ctxcatcodes = tex.ctxcatcodes +local prtcatcodes = tex.prtcatcodes +local texcatcodes = tex.texcatcodes +local txtcatcodes = tex.txtcatcodes +local vrbcatcodes = tex.vrbcatcodes +local xmlcatcodes = tex.xmlcatcodes + +local flush = texsprint + +local report_context = logs.new("context") -- here +local report_cld = logs.new("cld") + +local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end) + +-- for tracing it's easier to have two stacks + +local _stack_f_, _n_f_ = { }, 0 +local _stack_n_, _n_n_ = { }, 0 + +local function _store_f_(ti) + _n_f_ = _n_f_ + 1 + _stack_f_[_n_f_] = ti + return _n_f_ +end + +local function _store_n_(ti) + _n_n_ = _n_n_ + 1 + _stack_n_[_n_n_] = ti + return _n_n_ +end + +local function _flush_f_(n) + local sn = _stack_f_[n] + if not sn then + report_cld("data with id %s cannot be found on stack",n) + else + local tn = type(sn) + if tn == "function" then + if not sn() and texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! + _stack_f_[n] = nil + else + -- keep, beware, that way the stack can grow + end + else + if texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! + writenode(sn) + _stack_f_[n] = nil + else + writenode(copynodelist(sn)) + -- keep, beware, that way the stack can grow + end + end + end +end + +local function _flush_n_(n) + local sn = _stack_n_[n] + if not sn then + report_cld("data with id %s cannot be found on stack",n) + elseif texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! + writenode(sn) + _stack_n_[n] = nil + else + writenode(copynodelist(sn)) + -- keep, beware, that way the stack can grow + end +end + +function context.restart() + _stack_f_, _n_f_ = { }, 0 + _stack_n_, _n_n_ = { }, 0 +end + +context._stack_f_ = _stack_f_ +context._store_f_ = _store_f_ +context._flush_f_ = _flush_f_ cldff = _flush_f_ + +context._stack_n_ = _stack_n_ +context._store_n_ = _store_n_ +context._flush_n_ = _flush_n_ cldfn = _flush_n_ + +-- Should we keep the catcodes with the function? + +local catcodestack = { } +local currentcatcodes = ctxcatcodes +local contentcatcodes = ctxcatcodes + +local catcodes = { + ctx = ctxcatcodes, ctxcatcodes = ctxcatcodes, context = ctxcatcodes, + prt = prtcatcodes, prtcatcodes = prtcatcodes, protect = prtcatcodes, + tex = texcatcodes, texcatcodes = texcatcodes, plain = texcatcodes, + txt = txtcatcodes, txtcatcodes = txtcatcodes, text = txtcatcodes, + vrb = vrbcatcodes, vrbcatcodes = vrbcatcodes, verbatim = vrbcatcodes, + xml = xmlcatcodes, xmlcatcodes = xmlcatcodes, +} + +function context.pushcatcodes(c) + insert(catcodestack,currentcatcodes) + currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes + contentcatcodes = currentcatcodes +end + +function context.popcatcodes() + currentcatcodes = remove(catcodestack) or currentcatcodes + contentcatcodes = currentcatcodes +end + +function tex.fprint(...) -- goodie + texsprint(currentcatcodes,format(...)) +end + +-- -- -- todo: tracing + +local newline = lpeg.patterns.newline +local space = lpeg.patterns.spacer +local spacing = newline * space^0 +local content = lpeg.C((1-spacing)^1) +local emptyline = space^0 * newline^2 +local endofline = space^0 * newline * space^0 +local simpleline = endofline * lpeg.P(-1) + +local function n_content(s) + flush(contentcatcodes,s) +end + +local function n_endofline() + texsprint(" \r") +end + +local function n_emptyline() + texprint("\r") +end + +local function n_simpleline() + texprint("\r") +end + +function lpeg.texlinesplitter(f_content,f_endofline,f_emptyline,f_simpleline) + local splitlines = + simpleline / (f_simpleline or n_simpleline) + + ( + emptyline / (f_emptyline or n_emptyline) + + endofline / (f_endofline or n_emptyline) + + content / (f_content or n_content) + )^0 + return function(str) return lpegmatch(splitlines,str) end +end + +local flushlines = lpeg.texlinesplitter(n_content,n_endofline,n_emptyline,n_simpleline) + +context.__flushlines = flushlines -- maybe context.helpers.flushtexlines +context.__flush = flush + +local printlines_ctx = ( + (newline) / function() texprint("") end + + (1-newline)^1 / function(s) texprint(ctxcatcodes,s) end * newline^-1 +)^0 + +local printlines_raw = ( + (newline) / function() texprint("") end + + (1-newline)^1 / function(s) texprint(s) end * newline^-1 +)^0 + +function context.printlines(str,raw) + if raw then + lpegmatch(printlines_raw,str) + else + lpegmatch(printlines_ctx,str) + end +end + +-- -- -- + +local methodhandler = resolvers.methodhandler + +function context.viafile(data) + -- this is the only way to deal with nested buffers + -- and other catcode sensitive data + local filename = resolvers.savers.byscheme("virtual","viafile",data) + context.input(filename) +end + +-- -- -- + +local function writer(parent,command,first,...) + local t = { first, ... } + flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + local direct = false + for i=1,#t do + local ti = t[i] + local typ = type(ti) + if direct then + if typ == "string" or typ == "number" then + flush(currentcatcodes,ti) + else -- node.write + report_context("error: invalid use of direct in '%s', only strings and numbers can be flushed directly, not '%s'",command,typ) + end + direct = false + elseif ti == nil then + -- nothing + elseif ti == "" then + flush(currentcatcodes,"{}") + elseif typ == "string" then + if processlines and find(ti,"[\n\r]") then -- we can check for ti == "\n" + flush(currentcatcodes,"{") + local flushlines = parent.__flushlines or flushlines + flushlines(ti) + flush(currentcatcodes,"}") + elseif currentcatcodes == contentcatcodes then + flush(currentcatcodes,"{",ti,"}") + else + flush(currentcatcodes,"{") + flush(contentcatcodes,ti) + flush(currentcatcodes,"}") + end + elseif typ == "number" then + -- numbers never have funny catcodes + flush(currentcatcodes,"{",ti,"}") + elseif typ == "table" then + local tn = #ti + if tn == 0 then + local done = false + for k, v in next, ti do + if done then + if v == "" then + flush(currentcatcodes,",",k,'=') + else + flush(currentcatcodes,",",k,'=',v) + end + else + if v == "" then + flush(currentcatcodes,"[",k,'=') + else + flush(currentcatcodes,"[",k,'=',v) + end + done = true + end + end + flush(currentcatcodes,"]") + elseif tn == 1 then -- some 20% faster than the next loop + local tj = ti[1] + if type(tj) == "function" then + flush(currentcatcodes,"[\\cldff{",_store_f_(tj),"}]") + else + flush(currentcatcodes,"[",tj,"]") + end + else -- is concat really faster than flushes here? probably needed anyway (print artifacts) + for j=1,tn do + local tj = ti[j] + if type(tj) == "function" then + ti[j] = "\\cldff{" .. _store_f_(tj) .. "}" + end + end + flush(currentcatcodes,"[",concat(ti,","),"]") + end + elseif typ == "function" then + flush(currentcatcodes,"{\\cldff{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if ti then + -- flush(currentcatcodes,"^^M") + texprint("") + else + direct = true + end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(ti) then -- slow + flush(currentcatcodes,"{\\cldfn{",_store_n_(ti),"}}") + else + report_context("error: '%s' gets a weird argument '%s'",command,tostring(ti)) + end + end +end + +local generics = { } context.generics = generics + +local function indexer(parent,k) + local c = "\\" .. tostring(generics[k] or k) + local f = function(first,...) + if first == nil then + flush(currentcatcodes,c) + else + return writer(parent,c,first,...) + end + end + parent[k] = f + return f +end + +local function caller(parent,f,a,...) + if not parent then + -- so we don't need to test in the calling (slower but often no issue) (will go) + elseif f ~= nil then + local typ = type(f) + if typ == "string" then + if a then + flush(contentcatcodes,format(f,a,...)) -- was currentcatcodes + elseif processlines and find(f,"[\n\r]") then + local flushlines = parent.__flushlines or flushlines + flushlines(f) + else + flush(contentcatcodes,f) + end + elseif typ == "number" then + if a then + flush(currentcatcodes,f,a,...) + else + flush(currentcatcodes,f) + end + elseif typ == "function" then + -- ignored: a ... + flush(currentcatcodes,"{\\cldff{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if f then + if a ~= nil then + local flushlines = parent.__flushlines or flushlines + flushlines(f) + -- ignore ... maybe some day + else + -- flush(currentcatcodes,"^^M") + texprint("") + end + else + if a ~= nil then + -- no command, same as context(a,...) + writer(parent,"",a,...) + else + -- ignored + end + end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(f) then -- slow + -- writenode(f) + flush(currentcatcodes,"\\cldfn{",_store_n_(f),"}") + else + report_context("error: 'context' gets a weird argument '%s'",tostring(f)) + end + end +end + +local defaultcaller = caller + +setmetatable(context, { __index = indexer, __call = caller } ) + +-- now we tweak unprotect and protect + +function context.unprotect() + -- at the lua end + insert(catcodestack,currentcatcodes) + currentcatcodes = prtcatcodes + contentcatcodes = currentcatcodes + -- at the tex end + flush("\\unprotect") +end + +function context.protect() + -- at the tex end + flush("\\protect") + -- at the lua end + currentcatcodes = remove(catcodestack) or currentcatcodes + contentcatcodes = currentcatcodes +end + +-- logging + +local trace_stack = { } + +local normalflush = flush +local normalwriter = writer +local currenttrace = nil +local nofwriters = 0 +local nofflushes = 0 + +statistics.register("traced context", function() + if nofwriters > 0 or nofflushes > 0 then + return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,_n_f_) + end +end) + +local tracedwriter = function(parent,...) + nofwriters = nofwriters + 1 + local t, f, n = { "w : " }, flush, 0 + flush = function(...) + n = n + 1 + t[n] = concat({...},"",2) + normalflush(...) + end + normalwriter(parent,...) + flush = f + currenttrace(concat(t)) +end + +local tracedflush = function(...) + nofflushes = nofflushes + 1 + normalflush(...) + local t = { ... } + t[1] = "f : " -- replaces the catcode + for i=2,#t do + local ti = t[i] + local tt = type(ti) + if tt == "string" then + -- ok + elseif tt == "number" then + -- ok + else + t[i] = format("<%s>",tostring(ti)) + end + -- currenttrace(format("%02i: %s",i-1,tostring(t[i]))) + end + currenttrace(concat(t)) +end + +local function pushlogger(trace) + insert(trace_stack,currenttrace) + currenttrace = trace + flush, writer = tracedflush, tracedwriter + context.__flush = flush +end + +local function poplogger() + currenttrace = remove(trace_stack) + if not currenttrace then + flush, writer = normalflush, normalwriter + context.__flush = flush + end +end + +local function settracing(v) + if v then + pushlogger(report_context) + else + poplogger() + end +end + +-- todo: share flushers so that we can define in other files + +trackers.register("context.trace",settracing) + +context.pushlogger = pushlogger +context.poplogger = poplogger +context.settracing = settracing + +local trace_cld = false trackers.register("context.files", function(v) trace_cld = v end) + +function context.runfile(filename) + local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or "" + if foundname ~= "" then + local ok = dofile(foundname) + if type(ok) == "function" then + if trace_cld then + report_context("begin of file '%s' (function call)",foundname) + end + ok() + if trace_cld then + report_context("end of file '%s' (function call)",foundname) + end + elseif ok then + report_context("file '%s' is processed and returns true",foundname) + else + report_context("file '%s' is processed and returns nothing",foundname) + end + else + report_context("unknown file '%s'",filename) + end +end + +-- some functions + +function context.direct(first,...) + if first ~= nil then + return writer(context,"",first,...) + end +end + +-- context.delayed (todo: lines) + +local delayed = { } context.delayed = delayed -- maybe also store them + +local function indexer(parent,k) + local f = function(...) + local a = { ... } + return function() + return context[k](unpack(a)) + end + end + parent[k] = f + return f +end + +local function caller(parent,...) -- todo: nodes + local a = { ... } + return function() + return context(unpack(a)) + end +end + +setmetatable(delayed, { __index = indexer, __call = caller } ) + +-- context.nested (todo: lines) + +local nested = { } context.nested = nested + +local function indexer(parent,k) + local f = function(...) + local t, savedflush, n = { }, flush, 0 + flush = function(c,f,s,...) -- catcodes are ignored + n = n + 1 + t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 + end + context[k](...) + flush = savedflush + return concat(t) + end + parent[k] = f + return f +end + +local function caller(parent,...) + local t, savedflush, n = { }, flush, 0 + flush = function(c,f,s,...) -- catcodes are ignored + n = n + 1 + t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 + end + context(...) + flush = savedflush + return concat(t) +end + +setmetatable(nested, { __index = indexer, __call = caller } ) + +-- verbatim + +local verbatim = { } context.verbatim = verbatim + +local function indexer(parent,k) + local command = context[k] + local f = function(...) + local savedcatcodes = contentcatcodes + contentcatcodes = vrbcatcodes + command(...) + contentcatcodes = savedcatcodes + end + parent[k] = f + return f +end + +local function caller(parent,...) + local savedcatcodes = contentcatcodes + contentcatcodes = vrbcatcodes + defaultcaller(parent,...) + contentcatcodes = savedcatcodes +end + +setmetatable(verbatim, { __index = indexer, __call = caller } ) + +-- metafun (this will move to another file) + +local metafun = { } context.metafun = metafun + +local mpdrawing = "\\MPdrawing" + +local function caller(parent,f,a,...) + if not parent then + -- skip + elseif f then + local typ = type(f) + if typ == "string" then + if a then + flush(currentcatcodes,mpdrawing,"{",format(f,a,...),"}") + else + flush(currentcatcodes,mpdrawing,"{",f,"}") + end + elseif typ == "number" then + if a then + flush(currentcatcodes,mpdrawing,"{",f,a,...,"}") + else + flush(currentcatcodes,mpdrawing,"{",f,"}") + end + elseif typ == "function" then + -- ignored: a ... + flush(currentcatcodes,mpdrawing,"{\\cldff{",store_(f),"}}") + elseif typ == "boolean" then + -- ignored: a ... + if f then + flush(currentcatcodes,mpdrawing,"{^^M}") + else + report_context("warning: 'metafun' gets argument 'false' which is currently unsupported") + end + else + report_context("error: 'metafun' gets a weird argument '%s'",tostring(f)) + end + end +end + +setmetatable(metafun, { __call = caller } ) + +function metafun.start() + context.resetMPdrawing() +end + +function metafun.stop() + context.MPdrawingdonetrue() + context.getMPdrawing() +end + +function metafun.color(name) + return format([[\MPcolor{%s}]],name) +end + +-- metafun.delayed + +local delayed = { } metafun.delayed = delayed + +local function indexer(parent,k) + local f = function(...) + local a = { ... } + return function() + return metafun[k](unpack(a)) + end + end + parent[k] = f + return f +end + + +local function caller(parent,...) + local a = { ... } + return function() + return metafun(unpack(a)) + end +end + +setmetatable(delayed, { __index = indexer, __call = caller } ) + +--~ Not that useful yet. Maybe something like this when the main loop +--~ is a coroutine. It also does not help taking care of nested calls. +--~ Even worse, it interferes with other mechanisms using context calls. +--~ +--~ local create, yield, resume = coroutine.create, coroutine.yield, coroutine.resume +--~ local getflush, setflush = context.getflush, context.setflush +--~ local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +--~ +--~ function context.getflush() +--~ return flush +--~ end +--~ +--~ function context.setflush(newflush) +--~ local oldflush = flush +--~ flush = newflush or flush +--~ return oldflush +--~ end +--~ +--~ function context.direct(f) +--~ local routine = create(f) +--~ local oldflush = getflush() +--~ function newflush(...) +--~ oldflush(...) +--~ yield(true) +--~ end +--~ setflush(newflush) +--~ +--~ -- local function resumecontext() +--~ -- local done = resume(routine) +--~ -- if not done then +--~ -- return +--~ -- end +--~ -- resumecontext() -- stack overflow ... no tail recursion +--~ -- end +--~ -- context.resume = resumecontext +--~ -- texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") +--~ +--~ local function resumecontext() +--~ local done = resume(routine) +--~ if not done then +--~ return +--~ end +--~ -- texsprint(ctxcatcodes,"\\exitloop") +--~ texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") -- can be simple macro call +--~ end +--~ context.resume = resumecontext +--~ -- texsprint(ctxcatcodes,"\\doloop{\\ctxlua{context.resume()}}") -- can be fast loop at the tex end +--~ texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") +--~ +--~ end +--~ +--~ function something() +--~ context("\\setbox0") +--~ context("\\hbox{hans hagen xx}") +--~ context("\\the\\wd0/\\box0") +--~ end +--~ +--~ context.direct(something) + +-- helpers: + +function context.concat(t,separator) + local done = false + for i=1,#t do + local ti = t[i] + if ti ~= "" then + if done then + context(separator) + end + context(ti) + done = true + end + end +end diff --git a/tex/context/base/cldf-ini.mkiv b/tex/context/base/cldf-ini.mkiv index 44e9e7873..f1aa5f260 100644 --- a/tex/context/base/cldf-ini.mkiv +++ b/tex/context/base/cldf-ini.mkiv @@ -11,10 +11,12 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\writestatus{loading}{ConTeXt Lua Documents / Functions} +\writestatus{loading}{ConTeXt Lua Documents / Initialization} \registerctxluafile{cldf-ini}{1.001} -\registerctxluafile{cldf-com}{1.001} -\registerctxluafile{cldf-ver}{1.001} + +\normalprotected\def\cldprocessfile#1{\directlua\zerocount{context.runfile("#1")}} + \def\cldcontext #1{\directlua\zerocount{context(#1)}} + \def\cldcommand #1{\directlua\zerocount{context.#1}} \endinput diff --git a/tex/context/base/mult-clm.lua b/tex/context/base/cldf-int.lua index e2fff18dc..e2fff18dc 100644 --- a/tex/context/base/mult-clm.lua +++ b/tex/context/base/cldf-int.lua diff --git a/tex/context/base/mult-cld.mkiv b/tex/context/base/cldf-int.mkiv index 3106941f3..a256ac17b 100644 --- a/tex/context/base/mult-cld.mkiv +++ b/tex/context/base/cldf-int.mkiv @@ -13,7 +13,6 @@ \writestatus{loading}{ConTeXt Multilingual Macros / Lua} -\registerctxluafile{mult-cld}{1.001} \registerctxluafile{mult-clm}{1.001} \unprotect @@ -22,10 +21,6 @@ \unexpanded\def\mkivdefstop #1{\unexpanded\expandafter\def\csname\e!stop #1\endcsname} \unexpanded\def\mkivdef #1{\unexpanded\expandafter\def\csname #1\endcsname} -\unexpanded\def\cldprocessfile#1{\directlua\zerocount{context.runfile("#1")}} - \def\cldcontext #1{\directlua\zerocount{context(#1)}} - \def\cldcommand #1{\directlua\zerocount{context.#1}} - \def\cldff #1{\directlua\zerocount{cldff(#1)}} % global (functions) \def\cldfn #1{\directlua\zerocount{cldfn(#1)}} % global (nodes) diff --git a/tex/context/base/cldf-ver.lua b/tex/context/base/cldf-ver.lua index 6490b7f89..fc681e830 100644 --- a/tex/context/base/cldf-ver.lua +++ b/tex/context/base/cldf-ver.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['cldf-ver'] = { version = 1.001, - comment = "companion to cldf-ini.mkiv", + comment = "companion to cldf-ver.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" diff --git a/tex/context/base/cldf-ver.mkiv b/tex/context/base/cldf-ver.mkiv new file mode 100644 index 000000000..f85b28a0c --- /dev/null +++ b/tex/context/base/cldf-ver.mkiv @@ -0,0 +1,18 @@ +%D \module +%D [ file=cldf-com, +%D version=2010.10.19,, +%D title=\CONTEXT\ \LUA\ Document Functions, +%D subtitle=Verbatim, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=Hans Hagen] +%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 Lua Documents / Verbatim} + +\registerctxluafile{cldf-ver}{1.001} + +\endinput diff --git a/tex/context/base/colo-ext.mkiv b/tex/context/base/colo-ext.mkiv index c1e338469..343b062af 100644 --- a/tex/context/base/colo-ext.mkiv +++ b/tex/context/base/colo-ext.mkiv @@ -105,7 +105,7 @@ \def\dododefineintermediatecolor[#1][#2,#3,#4][#5]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{commands.defineintermediatecolor("#1","#2", + \ctxcommand{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-ini.mkiv b/tex/context/base/colo-ini.mkiv index 3818ea37b..b842337a9 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -209,7 +209,7 @@ %D \usecolors[rgb] %D \stoptyping -\unexpanded\def\usecolors[#1]{\ctxlua{commands.usecolors(\!!bs#1\!!es)}} +\unexpanded\def\usecolors[#1]{\ctxcommand{usecolors(\!!bs#1\!!es)}} \let\setupcolor\usecolors @@ -702,7 +702,7 @@ \def\currentcolormodel{\attribute\colormodelattribute} \def\dosetcolormodel#1% no message - {\ctxlua{commands.setcolormodel('#1',\ifweightGRAY true\else false\fi)}} % sets attribute + {\ctxcommand{setcolormodel('#1',\ifweightGRAY true\else false\fi)}} % sets attribute \dosetcolormodel{all} @@ -766,7 +766,7 @@ \def\doactivatecolor {\ifproductionrun - \ctxlua{commands.enablecolor() commands.enabletransparency()}% not that efficient but at least robust + \ctxcommand{enablecolor() commands.enabletransparency()}% not that efficient but at least robust \let\doactivatecolor\normaldoactivatecolor \expandafter\doactivatecolor \else @@ -786,44 +786,44 @@ \def\collectcolorinlist#1{\doglobal\addtocommalist{#1}\colorlist} \def\doregistercolor#1#2% - {\ctxlua{commands.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}} + {\ctxcommand{defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}} \def\dodefinecolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{commands.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \ctxcommand{defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} \def\dodefineglobalcolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{commands.defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}% + \ctxcommand{defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setgvalue{#1}} \def\dodefinenamedcolor[#1][#2]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{commands.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + \ctxcommand{defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} \def\dodefinespotcolor[#1][#2][#3]% {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi - \ctxlua{commands.definespotcolor("#1","#2","#3",true)}% + \ctxcommand{definespotcolor("#1","#2","#3",true)}% \dodefinecolorcommand\setxvalue{#1}} \def\dodefinemultitonecolor[#1][#2][#3][#4]% - {\ctxlua{commands.definemultitonecolor("#1","#2","#3","#4",true)}% + {\ctxcommand{definemultitonecolor("#1","#2","#3","#4",true)}% \dodefinecolorcommand\setxvalue{#1}} \def\dodefinetransparency[#1][#2]% - {\ctxlua{commands.definetransparency("#1",#2)}} + {\ctxcommand{definetransparency("#1",#2)}} \def\dosetrastercolor#1% slow, we need a fast one {\edef\@@rastervalue{#1}% \ifx\@@rastervalue\empty \let\@@rastervalue\@@rsscreen \fi - \ctxlua{commands.setrastercolor("_raster_",\@@rastervalue)}} % sets attribute + \ctxcommand{setrastercolor("_raster_",\@@rastervalue)}} % sets attribute \def\dodefinefastcolor[#1][#2]% still not fast but ok - {\ctxlua{commands.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% + {\ctxcommand{defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}% \dodefinecolorcommand\setvalue{#1}} %D \macros @@ -857,7 +857,7 @@ %D A bit like \type {\definedfont}: \unexpanded\def\colored[#1]% - {\ctxlua{commands.defineprocesscolor("@colored@","#1",false,false)}% + {\ctxcommand{defineprocesscolor("@colored@","#1",false,false)}% \groupedcommand{\doactivatecolor{@colored@}}{}} %D \macros @@ -898,7 +898,7 @@ \to \everybeforeoutput \def\registermaintextcolor - {\ctxlua{commands.registermaintextcolor(\thecolorattribute\maintextcolor)}} + {\ctxcommand{registermaintextcolor(\thecolorattribute\maintextcolor)}} \unexpanded\def\starttextcolor[#1]% {\doifsomething{#1} @@ -983,23 +983,23 @@ \let\colorformatseparator\space -\def\MPcolor #1{\ctxlua{commands.mpcolor(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1})}} +\def\MPcolor #1{\ctxcommand{mpcolor(\number\currentcolormodel,\number\doinheritca{#1},\number\doinheritta{#1})}} \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{commands.spotcolorname(\thecolorattribute{#1})}} -\def\internalspotcolorparent #1{\ctxlua{commands.spotcolorparent(\thecolorattribute{#1})}} -\def\internalspotcolorsize #1{\ctxlua{commands.spotcolorvalue(\thecolorattribute{#1})}} +\def\internalspotcolorname #1{\ctxcommand{spotcolorname(\thecolorattribute{#1})}} +\def\internalspotcolorparent #1{\ctxcommand{spotcolorparent(\thecolorattribute{#1})}} +\def\internalspotcolorsize #1{\ctxcommand{spotcolorvalue(\thecolorattribute{#1})}} -\def\colorcomponents #1{\ctxlua{commands.colorcomponents(\thecolorattribute{#1})}} -\def\transparencycomponents #1{\ctxlua{commands.transparencycomponents(\thetransparencyattribute{#1})}} +\def\colorcomponents #1{\ctxcommand{colorcomponents(\thecolorattribute{#1})}} +\def\transparencycomponents #1{\ctxcommand{transparencycomponents(\thetransparencyattribute{#1})}} -\def\colorvalue #1{\ctxlua{commands.formatcolor(\thecolorattribute{#1},"\colorformatseparator")}} -\def\grayvalue #1{\ctxlua{commands.formatgray (\thecolorattribute{#1},"\colorformatseparator")}} +\def\colorvalue #1{\ctxcommand{formatcolor(\thecolorattribute{#1},"\colorformatseparator")}} +\def\grayvalue #1{\ctxcommand{formatgray (\thecolorattribute{#1},"\colorformatseparator")}} -\def\doifblackelse #1{\ctxlua{commands.doifblackelse(\thecolorattribute{#1})}} -\def\doifdrawingblackelse {\ctxlua{commands.doifdrawingblackelse()}} +\def\doifblackelse #1{\ctxcommand{doifblackelse(\thecolorattribute{#1})}} +\def\doifdrawingblackelse {\ctxcommand{doifdrawingblackelse()}} %D \macros %D {forcecolorhack} diff --git a/tex/context/base/colo-imp-run.mkiv b/tex/context/base/colo-run.mkiv index d94ea9801..d94ea9801 100644 --- a/tex/context/base/colo-imp-run.mkiv +++ b/tex/context/base/colo-run.mkiv diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 990a94a90..d58f5d6e6 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.01.26 11:02} +\newcontextversion{2011.01.31 16:59} %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/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 0fa55848f..d0ed28064 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.01.26 11:02} +\newcontextversion{2011.01.31 16:59} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new @@ -238,7 +238,7 @@ \stopluacode \gdef\setpercentdimen#1#2% - {#1=\ctxlua{commands.percentageof("#2",\number#1)}\relax} + {#1=\ctxcommand{percentageof("#2",\number#1)}\relax} % \scratchdimen=100pt \setpercentdimen\scratchdimen{10\letterpercent} \the\scratchdimen % \scratchdimen=100pt \setpercentdimen\scratchdimen{5pt} \the\scratchdimen diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 01fb8ff08..ebb06407e 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.01.26 11:02} +\edef\contextversion{2011.01.31 16:59} %D For those who want to use this: @@ -107,6 +107,7 @@ \loadmarkfile{mult-sys} \loadmarkfile{mult-def} \loadmarkfile{mult-chk} +\loadmarkfile{mult-aux} %D Now we're ready for some general support modules. These %D modules implement some basic typesetting functionality. diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 6bc1036fd..9c4c6896e 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.01.26 11:02} +\edef\contextversion{2011.01.31 16:59} %D For those who want to use this: @@ -79,6 +79,8 @@ \loadmarkfile{catc-ctx} \loadmarkfile{catc-sym} +\loadmarkfile{cldf-ini} + % From here on we have \unexpanded being \normalprotected, as we % already had \unexpanded long before etex came around. @@ -87,7 +89,6 @@ \loadmarkfile{syst-con} \loadmarkfile{syst-fnt} -\loadmarkfile{syst-str} \loadmarkfile{syst-rtp} \loadmarkfile{supp-fil} @@ -102,9 +103,10 @@ \loadmarkfile{mult-sys} \loadmarkfile{mult-def} \loadmarkfile{mult-chk} -\loadmarkfile{mult-cld} \loadmarkfile{mult-aux} +\loadmarkfile{cldf-int} % interface + \loadmarkfile{luat-ini} \loadmarkfile{toks-ini} @@ -368,8 +370,6 @@ \loadmarkfile{lang-spa} % will become obsolete -\loadmarkfile{cldf-ini} % this can come later - \loadmarkfile{bibl-bib} \loadmarkfile{bibl-tra} @@ -381,6 +381,9 @@ \loadmarkfile{task-ini} +\loadmarkfile{cldf-ver} % verbatim, this can come late +\loadmarkfile{cldf-com} % commands, this can come late + \loadmarkfile{core-ctx} \loadmarkfile{core-ini} diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua index efdb0e1bc..318616db4 100644 --- a/tex/context/base/core-con.lua +++ b/tex/context/base/core-con.lua @@ -32,27 +32,13 @@ local converters = converters languages = languages or { } local languages = languages -function converters.convert(method,n,direct) - local method = converters[method] - if method then - return method(n,direct) - else - return direct and n or context(n) - end +local function number(n) + return tonumber(n) end -function converters.numberst(n,direct) - return direct and n or context(n) -end +converters.number = number ---~ ['arabic-digits'] = { ---~ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, ---~ 0x0665, 0x0666, 0x0667, 0x0668, 0x0669 ---~ }, ---~ ['persian-digits'] = { ---~ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, ---~ 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9 ---~ }, +function commands.number(n) context(n) end -- to be reconsidered ... languages namespace here, might become local plus a register command @@ -144,38 +130,25 @@ counters['kr-c'] = counters['korean-circle'] local fallback = utf.byte('0') -local function chr(n,m,direct) - local s = (n > 0 and n < 27 and utfchar(n+m)) or "" - if direct then return s else context(s) end +local function chr(n,m) + return (n > 0 and n < 27 and utfchar(n+m)) or "" end ---~ local function chrs(n,m,direct) ---~ if n > 26 then ---~ chrs(floor((n-1)/26),m) ---~ n = (n-1)%26 + 1 ---~ end ---~ context(utfchar(n+m)) ---~ end - -local function chrs(n,m,direct,t) +local function chrs(n,m,t) if not t then t = { } end if n > 26 then - chrs(floor((n-1)/26),m,direct,t) + chrs(floor((n-1)/26),m,t) n = (n-1)%26 + 1 end t[#t+1] = utfchar(n+m) if n <= 26 then - if direct then - return concat(t) - else - context(concat(t)) - end + return concat(t) end end -local function maxchrs(n,m,cmd,direct,t) -- direct is not ok +local function maxchrs(n,m,cmd,t) if not t then t = { } end @@ -185,11 +158,7 @@ local function maxchrs(n,m,cmd,direct,t) -- direct is not ok end t[#t+1] = format("%s{%s}",cmd,n) if n <= m then - if direct then - return concat(t) - else - context(concat(t)) - end + return concat(t) end end @@ -197,47 +166,11 @@ converters.chr = chr converters.chrs = chrs converters.maxchrs = maxchrs ---~ more efficient but needs testing ---~ ---~ local escapes = utffilters.private.escapes ---~ ---~ local function do_alphabetic(n,mapping,chr) ---~ local max = #mapping ---~ if n > max then ---~ do_alphabetic(floor((n-1)/max),max,chr) ---~ n = (n-1)%max+1 ---~ end ---~ n = chr(n,mapping) ---~ context(escapes[n] or utfchar(n)) ---~ end - ---~ local lccodes, uccodes = characters.lccode, characters.uccode - ---~ local function do_alphabetic(n,mapping,chr) ---~ local max = #mapping ---~ if n > max then ---~ do_alphabetic(floor((n-1)/max),mapping,chr) ---~ n = (n-1)%max+1 ---~ end ---~ characters.flush(chr(n,mapping)) ---~ end ---~ ---~ local function lowercased(n,mapping) return characters.lccode(mapping[n] or fallback) end ---~ local function uppercased(n,mapping) return characters.uccode(mapping[n] or fallback) end ---~ ---~ function converters.alphabetic(n,code) ---~ do_alphabetic(n,counters[code] or counters['**'],lowercased) -- lccode catches wrong tables ---~ end ---~ ---~ function converters.Alphabetic(n,code) ---~ do_alphabetic(n,counters[code] or counters['**'],uppercased) ---~ end - local flushcharacter = characters and characters.flush or function(s) return utfchar(s) end local lowercharacter = characters and characters.lccode or function(s) return s end local uppercharacter = characters and characters.uccode or function(s) return s end -local function do_alphabetic(n,mapping,mapper,direct,verbose,t) +local function do_alphabetic(n,mapping,mapper,verbose,t) if not t then t = { } end @@ -247,67 +180,114 @@ local function do_alphabetic(n,mapping,mapper,direct,verbose,t) end local max = #mapping if n > max then - do_alphabetic(floor((n-1)/max),mapping,mapper,direct,verbose,t) + do_alphabetic(floor((n-1)/max),mapping,mapper,verbose,t) n = (n-1)%max+1 end if verbose or type(chr) ~= "number" then t[#t+1] = chr else - t[#t+1] = utfchar(chr) -- flushcharacter(chr,true) -- force direct here; can't we just use utfchar(chr) nowadays? + t[#t+1] = utfchar(chr) end if n <= max then - if direct then - return concat(t) - else - context(concat(t)) - end + return concat(t) end end -function converters.alphabetic(n,code,direct) - return do_alphabetic(n,counters[code] or counters['**'],lowercharacter,direct) +local function alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters['**'],lowercharacter) end -function converters.Alphabetic(n,code,direct) - return do_alphabetic(n,counters[code] or counters['**'],uppercharacter,direct) + +local function Alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters['**'],uppercharacter) end -function converters.character (n,direct) return chr (n,96,direct) end -function converters.Character (n,direct) return chr (n,64,direct) end -function converters.characters(n,direct) return chrs(n,96,direct) end -function converters.Characters(n,direct) return chrs(n,64,direct) end +local function character (n) return chr (n,96) end +local function Character (n) return chr (n,64) end +local function characters(n) return chrs(n,96) end +local function Characters(n) return chrs(n,64) end + +converters.alphabetic = alphabetic +converters.Alphabetic = Alphabetic +converters.character = character +converters.Character = Character +converters.characters = characters +converters.Characters = Characters + +function commands.alphabetic(n) context(alphabetic(n)) end +function commands.Alphabetic(n) context(Alphabetic(n)) end +function commands.character (n) context(character (n)) end +function commands.Character (n) context(Character (n)) end +function commands.characters(n) context(characters(n)) end +function commands.Characters(n) context(Characters(n)) end -function converters.weekday(day,month,year,direct) - local s = date("%w",time{year=year,month=month,day=day}) + 1 - if direct then return s else context(s) end +local days = { + [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +} + +local function weekday(day,month,year) + return date("%w",time{year=year,month=month,day=day}) + 1 end -function converters.isleapyear(year) +local function isleapyear(year) return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0)) end -function converters.leapyear(year) - local s = converters.isleapyear(year) and 1 or 0 - if direct then return s else context(s) end +local function leapyear(year) + return isleapyear(year) and 1 or 0 end -local days = { - [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -} +local function nofdays(year,month) + return days[sleapyear(year)][month] +end + +local function year () return date("%Y") end +local function month () return date("%m") end +local function hour () return date("%H") end +local function minute() return date("%M") end +local function second() return date("%S") end -function converters.nofdays(year,month,direct) - local s = days[converters.isleapyear(year)][month] - if direct then return s else context(s) end +local function textime() + return tonumber(date("%H")) * 60 + tonumber(date("%M")) end -function converters.year (direct) local s = date("%Y") if direct then return s else context(s) end end -function converters.year (direct) local s = date("%Y") if direct then return s else context(s) end end -function converters.month (direct) local s = date("%m") if direct then return s else context(s) end end -function converters.hour (direct) local s = date("%H") if direct then return s else context(s) end end -function converters.minute (direct) local s = date("%M") if direct then return s else context(s) end end -function converters.second (direct) local s = date("%S") if direct then return s else context(s) end end -function converters.textime(direct) local s = tonumber(date("%H")) * 60 + tonumber(date("%M")) - if direct then return s else context(s) end end +converters.weekday = weekday +converters.isleapyear = isleapyear +converters.leapyear = leapyear +converters.nofdays = nofdays +converters.year = year +converters.month = month +converters.hour = hour +converters.minute = minute +converters.second = second +converters.textime = textime + +function commands.weekday(day,month,year) + context(weekday(day,month,year)) +end + +function commands.isleapyear(year) + context(isleapyear(year)) +end + +function commands.leapyear(year) + context(leapyear(year)) +end + +function commands.nofdays(year,month) + context(nofdays(year,month)) +end + +function commands.year () context(year ()) end +function commands.month () context(month ()) end +function commands.hour () context(hour ()) end +function commands.minute () context(minute ()) end +function commands.second () context(second ()) end +function commands.textime() context(textime()) end + +function commands.doifleapyearelse(year) + commands.testcase(leapyear(year)) +end local roman = { { [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' }, @@ -323,10 +303,16 @@ local function toroman(n) end end -function converters.romannumerals(n,direct) local s = lower(toroman(n)) if direct then return s else context(s) end end -function converters.Romannumerals(n,direct) local s = toroman(n) if direct then return s else context(s) end end +local Romannumerals = toroman -converters.toroman = toroman +local function romannumerals(n) return lower(toroman(n)) end + +converters.toroman = toroman +converters.Romannumerals = toroman +converters.romannumerals = romannumerals + +function commands.romannumerals(n) context(lower(toroman(n))) end +function commands.Romannumerals(n) context( toroman(n)) end --~ local small = { --~ 0x0627, 0x066E, 0x062D, 0x062F, 0x0647, 0x0648, 0x0631 @@ -357,7 +343,7 @@ local large = { { "غ" }, } -function converters.toabjad(n,what) +local function toabjad(n,what) if n <= 0 or n >= 2000 then return tostring(n) elseif what == 2 and n <= 7 then @@ -374,8 +360,16 @@ function converters.toabjad(n,what) end end -function converters.abjadnumerals (n,direct) local s = converters.toabjad(n,false) if direct then return s else context(s) end end -function converters.abjadnodotnumerals(n,direct) local s = converters.toabjad(n,true ) if direct then return s else context(s) end end +converters.toabjad = toabjad + +local function abjadnumerals (n) return toabjad(n,false) end +local function abjadnodotnumerals(n) return toabjad(n,true ) end + +converters.abjadnumerals = abjadnumerals +converters.abjadnodotnumerals = abjadnodotnumerals + +function commands.abjadnumerals (n) context(toabjad(n,false)) end +function commands.abjadnodotnumerals(n) context(toabjad(n,true )) end local vector = { normal = { @@ -509,115 +503,25 @@ local function tochinese(n,name) -- normal, caps, all return concat(result) end ---~ local t = { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } ---~ for k=1,#t do ---~ local v = t[k] ---~ print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap")) ---~ end - -function converters.chinesenumerals (n) local s = tochinese(n,"normal") if direct then return s else context(s) end end -function converters.chinesecapnumerals(n) local s = tochinese(n,"cap" ) if direct then return s else context(s) end end -function converters.chineseallnumerals(n) local s = tochinese(n,"all" ) if direct then return s else context(s) end end - ---~ Well, since the one asking for this didn't test it the following code is not ---~ enabled. ---~ ---~ -- This Lua version is based on a Javascript by Behdad Esfahbod which in turn ---~ -- is based on GPL'd code by Roozbeh Pournader of the The FarsiWeb Project ---~ -- Group: http://www.farsiweb.info/jalali/jalali.js. ---~ -- ---~ -- We start tables at one, I kept it zero based in order to stay close to ---~ -- the original. ---~ -- ---~ -- Conversion by Hans Hagen ---~ ---~ local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } ---~ local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } ---~ ---~ local function div(a,b) ---~ return math.floor(a/b) ---~ end ---~ ---~ local function remainder(a,b) ---~ return a - div(a,b)*b ---~ end ---~ ---~ function gregorian_to_jalali(gy,gm,gd) ---~ local jy, jm, jd, g_day_no, j_day_no, j_np, i ---~ gy, gm, gd = gy - 1600, gm - 1, gd - 1 ---~ g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) ---~ i = 0 ---~ while i < gm do ---~ g_day_no = g_day_no + g_days_in_month[i] ---~ i = i + 1 ---~ end ---~ if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then ---~ g_day_no = g_day_no + 1 ---~ end ---~ g_day_no = g_day_no + gd ---~ j_day_no = g_day_no - 79 ---~ j_np = div(j_day_no,12053) ---~ j_day_no = remainder(j_day_no,12053) ---~ jy = 979 + 33*j_np + 4*div(j_day_no,1461) ---~ j_day_no = remainder(j_day_no,1461) ---~ if j_day_no >= 366 then ---~ jy = jy + div((j_day_no-1),365) ---~ j_day_no = remainder((j_day_no-1),365) ---~ end ---~ i = 0 ---~ while i < 11 and j_day_no >= j_days_in_month[i] do ---~ j_day_no = j_day_no - j_days_in_month[i] ---~ i = i + 1 ---~ end ---~ jm = i + 1 ---~ jd = j_day_no + 1 ---~ return jy, jm, jd ---~ end ---~ ---~ function jalali_to_gregorian(jy,jm,jd) ---~ local gy, gm, gd, g_day_no, j_day_no, leap, i ---~ jy, jm, jd = jy - 979, jm - 1, jd - 1 ---~ j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4) ---~ i = 0 ---~ while i < jm do ---~ j_day_no = j_day_no + j_days_in_month[i] ---~ i = i + 1 ---~ end ---~ j_day_no = j_day_no + jd ---~ g_day_no = j_day_no + 79 ---~ gy = 1600 + 400*div(g_day_no,146097) ---~ g_day_no = remainder (g_day_no, 146097) ---~ leap = 1 ---~ if g_day_no >= 36525 then ---~ g_day_no = g_day_no - 1 ---~ gy = gy + 100*div(g_day_no,36524) ---~ g_day_no = remainder (g_day_no, 36524) ---~ if g_day_no >= 365 then ---~ g_day_no = g_day_no + 1 ---~ else ---~ leap = 0 ---~ end ---~ end ---~ gy = gy + 4*div(g_day_no,1461) ---~ g_day_no = remainder (g_day_no, 1461) ---~ if g_day_no >= 366 then ---~ leap = 0 ---~ g_day_no = g_day_no - 1 ---~ gy = gy + div(g_day_no, 365) ---~ g_day_no = remainder(g_day_no, 365) ---~ end ---~ i = 0 ---~ while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do ---~ g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0) ---~ i = i + 1 ---~ end ---~ gm = i + 1 ---~ gd = g_day_no + 1 ---~ return gy, gm, gd ---~ end ---~ ---~ print(gregorian_to_jalali(2009,02,24)) ---~ print(jalali_to_gregorian(1387,12,06)) +-- local t = { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } +-- for k=1,#t do +-- local v = t[k] +-- print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap")) +-- end + +converters.tochinese = tochinese + +local function chinesenumerals (n) return tochinese(n,"normal") end +local function chinesecapnumerals(n) return tochinese(n,"cap" ) end +local function chineseallnumerals(n) return tochinese(n,"all" ) end + +converters.chinesenumerals = chinesenumerals +converters.chinesecapnumerals = chinesecapnumerals +converters.chineseallnumerals = chineseallnumerals + +function commands.chinesenumerals (n) context(tochinese(n,"normal")) end +function commands.chinesecapnumerals(n) context(tochinese(n,"cap" )) end +function commands.chineseallnumerals(n) context(tochinese(n,"all" )) end converters.sequences = converters.sequences or { } @@ -629,20 +533,164 @@ function converters.define(name,set) sequences[name] = settings_to_array(set) end -function converters.convert(method,n,direct) -- todo: language +commands.defineconversion = converters.define + +local function convert(method,n) -- todo: language local converter = converters[method] if converter then - return converter(n,direct) + return converter(n) else local lowermethod = lower(method) local linguistic = counters[lowermethod] local sequence = sequences[method] if linguistic then - return do_alphabetic(n,linguistic,lowermethod == method and lowercharacter or uppercharacter,direct,false) + return do_alphabetic(n,linguistic,lowermethod == method and lowercharacter or uppercharacter,false) elseif sequence then - return do_alphabetic(n,sequence,false,direct,true) + return do_alphabetic(n,sequence,false,true) else - return direct and n or context(n) + return context(n) end end end + +converters.convert = convert + +function commands.checkedconversion(method,n) + context(convert(method,n)) +end + +-- Well, since the one asking for this didn't test it the following code is not +-- enabled. +-- +-- -- This Lua version is based on a Javascript by Behdad Esfahbod which in turn +-- -- is based on GPL'd code by Roozbeh Pournader of the The FarsiWeb Project +-- -- Group: http://www.farsiweb.info/jalali/jalali.js. +-- -- +-- -- We start tables at one, I kept it zero based in order to stay close to +-- -- the original. +-- -- +-- -- Conversion by Hans Hagen +-- +-- local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +-- local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } +-- +-- local function div(a,b) +-- return math.floor(a/b) +-- end +-- +-- local function remainder(a,b) +-- return a - div(a,b)*b +-- end +-- +-- function gregorian_to_jalali(gy,gm,gd) +-- local jy, jm, jd, g_day_no, j_day_no, j_np, i +-- gy, gm, gd = gy - 1600, gm - 1, gd - 1 +-- g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) +-- i = 0 +-- while i < gm do +-- g_day_no = g_day_no + g_days_in_month[i] +-- i = i + 1 +-- end +-- if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then +-- g_day_no = g_day_no + 1 +-- end +-- g_day_no = g_day_no + gd +-- j_day_no = g_day_no - 79 +-- j_np = div(j_day_no,12053) +-- j_day_no = remainder(j_day_no,12053) +-- jy = 979 + 33*j_np + 4*div(j_day_no,1461) +-- j_day_no = remainder(j_day_no,1461) +-- if j_day_no >= 366 then +-- jy = jy + div((j_day_no-1),365) +-- j_day_no = remainder((j_day_no-1),365) +-- end +-- i = 0 +-- while i < 11 and j_day_no >= j_days_in_month[i] do +-- j_day_no = j_day_no - j_days_in_month[i] +-- i = i + 1 +-- end +-- jm = i + 1 +-- jd = j_day_no + 1 +-- return jy, jm, jd +-- end +-- +-- function jalali_to_gregorian(jy,jm,jd) +-- local gy, gm, gd, g_day_no, j_day_no, leap, i +-- jy, jm, jd = jy - 979, jm - 1, jd - 1 +-- j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4) +-- i = 0 +-- while i < jm do +-- j_day_no = j_day_no + j_days_in_month[i] +-- i = i + 1 +-- end +-- j_day_no = j_day_no + jd +-- g_day_no = j_day_no + 79 +-- gy = 1600 + 400*div(g_day_no,146097) +-- g_day_no = remainder (g_day_no, 146097) +-- leap = 1 +-- if g_day_no >= 36525 then +-- g_day_no = g_day_no - 1 +-- gy = gy + 100*div(g_day_no,36524) +-- g_day_no = remainder (g_day_no, 36524) +-- if g_day_no >= 365 then +-- g_day_no = g_day_no + 1 +-- else +-- leap = 0 +-- end +-- end +-- gy = gy + 4*div(g_day_no,1461) +-- g_day_no = remainder (g_day_no, 1461) +-- if g_day_no >= 366 then +-- leap = 0 +-- g_day_no = g_day_no - 1 +-- gy = gy + div(g_day_no, 365) +-- g_day_no = remainder(g_day_no, 365) +-- end +-- i = 0 +-- while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do +-- g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0) +-- i = i + 1 +-- end +-- gm = i + 1 +-- gd = g_day_no + 1 +-- return gy, gm, gd +-- end +-- +-- print(gregorian_to_jalali(2009,02,24)) +-- print(jalali_to_gregorian(1387,12,06)) + +-- more efficient but needs testing +-- +-- local escapes = utffilters.private.escapes +-- +-- local function do_alphabetic(n,mapping,chr) +-- local max = #mapping +-- if n > max then +-- do_alphabetic(floor((n-1)/max),max,chr) +-- n = (n-1)%max+1 +-- end +-- n = chr(n,mapping) +-- context(escapes[n] or utfchar(n)) +-- end +-- +-- local lccodes, uccodes = characters.lccode, characters.uccode +-- +-- local function do_alphabetic(n,mapping,chr) +-- local max = #mapping +-- if n > max then +-- do_alphabetic(floor((n-1)/max),mapping,chr) +-- n = (n-1)%max+1 +-- end +-- characters.flush(chr(n,mapping)) +-- end +-- +-- local function lowercased(n,mapping) return characters.lccode(mapping[n] or fallback) end +-- local function uppercased(n,mapping) return characters.uccode(mapping[n] or fallback) end +-- +-- function converters.alphabetic(n,code) +-- do_alphabetic(n,counters[code] or counters['**'],lowercased) -- lccode catches wrong tables +-- end +-- +-- function converters.Alphabetic(n,code) +-- do_alphabetic(n,counters[code] or counters['**'],uppercased) +-- end diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv index 08384a76b..67c378b6d 100644 --- a/tex/context/base/core-con.mkiv +++ b/tex/context/base/core-con.mkiv @@ -74,41 +74,41 @@ %D \showsetup{romannumerals} %D \showsetup{Romannumerals} -\def\romannumerals#1{\ctxlua{converters.romannumerals(\number#1)}} -\def\Romannumerals#1{\ctxlua{converters.Romannumerals(\number#1)}} +\def\romannumerals#1{\ctxcommands{romannumerals(\number#1)}} +\def\Romannumerals#1{\ctxcommands{Romannumerals(\number#1)}} %D Arabic etc: -\def\abjadnumerals #1{\ctxlua{converters.abjadnumerals (\number#1)}} -\def\abjadnodotnumerals#1{\ctxlua{converters.abjadnodotnumerals(\number#1)}} -\def\abjadnaivenumerals#1{\ctxlua{converters.arabicnumerals (\number#1)}} +\def\abjadnumerals #1{\ctxcommands{abjadnumerals (\number#1)}} +\def\abjadnodotnumerals#1{\ctxcommands{abjadnodotnumerals(\number#1)}} +\def\abjadnaivenumerals#1{\ctxcommands{arabicnumerals (\number#1)}} -\def\languagecharacters#1{\ctxlua{converters.alphabetic(\number#1,"\currentlanguage")}} % new -\def\languageCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"\currentlanguage")}} % new +\def\languagecharacters#1{\ctxcommand{alphabetic(\number#1,"\currentlanguage")}} % new +\def\languageCharacters#1{\ctxcommand{Alphabetic(\number#1,"\currentlanguage")}} % new % we could use an auxiliary macro to save some bytes in the format % -% \def\dolanguagecharacters#1#2{\ctxlua{converters.alphabetic(\number#2,"#1")}} +% \def\dolanguagecharacters#1#2{\ctxcommand{alphabetic(\number#2,"#1")}} -\def\thainumerals #1{\ctxlua{converters.alphabetic(\number#1,"thai")}} -\def\devanagarinumerals#1{\ctxlua{converters.alphabetic(\number#1,"devanagari")}} -\def\gurmurkhinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gurmurkhi")}} -\def\gujaratinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gujarati")}} -\def\tibetannumerals #1{\ctxlua{converters.alphabetic(\number#1,"tibetan")}} -\def\greeknumerals #1{\ctxlua{converters.alphabetic(\number#1,"greek")}} -\def\Greeknumerals #1{\ctxlua{converters.Alphabetic(\number#1,"greek")}} -\def\arabicnumerals #1{\ctxlua{converters.alphabetic(\number#1,"arabic")}} -\def\persiannumerals #1{\ctxlua{converters.alphabetic(\number#1,"persian")}} +\def\thainumerals #1{\ctxcommand{alphabetic(\number#1,"thai")}} +\def\devanagarinumerals#1{\ctxcommand{alphabetic(\number#1,"devanagari")}} +\def\gurmurkhinumerals #1{\ctxcommand{alphabetic(\number#1,"gurmurkhi")}} +\def\gujaratinumerals #1{\ctxcommand{alphabetic(\number#1,"gujarati")}} +\def\tibetannumerals #1{\ctxcommand{alphabetic(\number#1,"tibetan")}} +\def\greeknumerals #1{\ctxcommand{alphabetic(\number#1,"greek")}} +\def\Greeknumerals #1{\ctxcommand{Alphabetic(\number#1,"greek")}} +\def\arabicnumerals #1{\ctxcommand{alphabetic(\number#1,"arabic")}} +\def\persiannumerals #1{\ctxcommand{alphabetic(\number#1,"persian")}} -\let\arabicexnumerals \persiannumerals +\let\arabicexnumerals \persiannumerals -\def\koreannumerals #1{\ctxlua{converters.alphabetic(\number#1,"korean")}} -\def\koreannumeralsp#1{\ctxlua{converters.alphabetic(\number#1,"korean-parent")}} -\def\koreannumeralsc#1{\ctxlua{converters.alphabetic(\number#1,"korean-circle")}} +\def\koreannumerals #1{\ctxcommand{alphabetic(\number#1,"korean")}} +\def\koreannumeralsp #1{\ctxcommand{alphabetic(\number#1,"korean-parent")}} +\def\koreannumeralsc #1{\ctxcommand{alphabetic(\number#1,"korean-circle")}} -\def\chinesenumerals #1{\ctxlua{converters.chinesenumerals (\number#1)}} -\def\chinesecapnumerals#1{\ctxlua{converters.chinesecapnumerals(\number#1,"cap")}} -\def\chineseallnumerals#1{\ctxlua{converters.chineseallnumerals(\number#1,"all")}} +\def\chinesenumerals #1{\ctxcommand{chinesenumerals (\number#1)}} +\def\chinesecapnumerals#1{\ctxcommand{chinesecapnumerals(\number#1,"cap")}} +\def\chineseallnumerals#1{\ctxcommand{chineseallnumerals(\number#1,"all")}} %D \macros %D {character,Character} @@ -128,8 +128,8 @@ \def\unknowncharacter{-} % else in lists \relax -\def\character#1{\ctxlua{converters.character (\number#1)}} -\def\Character#1{\ctxlua{converters.Character (\number#1)}} +\def\character#1{\ctxcommand{character(\number#1)}} +\def\Character#1{\ctxcommand{Character(\number#1)}} %D \macros %D {characters,Characters} @@ -141,8 +141,8 @@ %D \showsetup{characters} %D \showsetup{Characters} -\def\characters#1{\ctxlua{converters.characters(\number#1)}} -\def\Characters#1{\ctxlua{converters.Characters(\number#1)}} +\def\characters#1{\ctxcommand{characters(\number#1)}} +\def\Characters#1{\ctxcommand{Characters(\number#1)}} %D \macros %D {greeknumerals,Greeknumerals} @@ -262,8 +262,8 @@ \newcount\normalweekday -\def\getdayoftheweek#1#2#3{\normalweekday\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}} -\def\dayoftheweek #1#2#3{\doconvertday{\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}}} +\def\getdayoftheweek#1#2#3{\normalweekday\ctxcommand{weekday(\number#1,\number#2,\number#3)}} +\def\dayoftheweek #1#2#3{\doconvertday{\ctxcommand{weekday(\number#1,\number#2,\number#3)}}} %D Using this macro in %D @@ -337,24 +337,13 @@ %D {\numberofdays}. \def\doifleapyearelse#1% - {\ifcase\ctxlua{converters.leapyear(\number#1)} - \@EA\secondoftwoarguments - \else - \@EA\firstoftwoarguments - \fi} + {\ctxcommand{doifleapyearelse(\number#1)}} \def\getdayspermonth#1#2% - {\edef\numberofdays{\ctxlua{converters.nofdays(\number#1,\number#2)}}} + {\edef\numberofdays{\ctxcommand{nofdays(\number#1,\number#2)}}} \def\dayspermonth#1#2% - {\ctxlua{converters.nofdays(\number#1,\number#2)}} - -% problem is that we calculate with those numbers -% -% \def\time {\numexpr\ctxlua{converters.textime()}\relax} -% \def\year {\numexpr\ctxlua{converters.year ()}\relax} -% \def\month{\numexpr\ctxlua{converters.month ()}\relax} -% \def\day {\numexpr\ctxlua{converters.day ()}\relax} + {\ctxcommand{nofdays(\number#1,\number#2)}} % \dayoftheweek{2006}{9}{15} % \doifleapyearelse{2000}{OK}{NOT OK} @@ -439,9 +428,7 @@ {\bgroup \the\everycurrentdate \def\betweendates{\let\betweendates\dobetweendates}% - % was \processcommacommandp[#1]\docomplexcurrentdate - \safeedef\ascii{\empty#1}% keep encoded chars - \@EA\processcommalist\@EA[\ascii]\docomplexcurrentdate + \processcommacommand[\ascii]\docomplexcurrentdate \ifdim\lastskip=\datesignal\relax \unskip \fi @@ -451,21 +438,18 @@ {\lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped \expanded{\processaction[\!!stringa]}% [#1] [ \v!day=>\betweendates\the\normalday, - %\v!day+=>\betweendates\ordinaldaynumber\normalday, \v!day+=>\betweendates\convertnumber{\v!day+}\normalday, \v!month=>\betweendates\month\normalmonth, \v!year=>\betweendates\the\normalyear, \v!space=>\unskip\ \hskip\datesignal,% optimization -) \ =>\unskip\ \hskip\datesignal,% optimization -) d=>\convertnumber\v!day\normalday, - %d+=>\ordinaldaynumber\normalday, d+=>\convertnumber{\v!day+}\normalday, m=>\convertnumber\v!month\normalmonth, j=>\convertnumber\v!year\normalyear, y=>\convertnumber\v!year\normalyear, w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear, dd=>\ifnum\normalday >9 \else0\fi\the\normalday, - %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday}, dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday}, mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth, jj=>\expandafter\gobbletwoarguments\the\normalyear, @@ -512,9 +496,9 @@ %D keys \type {h}, \type {m} and a separator. \def\calculatecurrenttime - {\edef\currenthour {\ctxlua{converters.hour ()}}% - \edef\currentminute{\ctxlua{converters.minute()}}% - \edef\currentsecond{\ctxlua{converters.second()}}} + {\edef\currenthour {\ctxcommand{hour ()}}% + \edef\currentminute{\ctxcommand{minute()}}% + \edef\currentsecond{\ctxcommand{second()}}} \let\currenthour \!!plusone \let\currentminute\!!plusone @@ -635,12 +619,12 @@ \def\dododefineconversion#1#2#3% {\ConvertConstantAfter\doifinstringelse{,}{#3} - {\ctxlua{converters.define("#2",\!!bs\detokenize{#3}\!!es)}% + {\ctxcommand{defineconversion("#2",\!!bs\detokenize{#3}\!!es)}% \setgvalue{\??cv#1}{\docheckedconversion{#2}}} {\setgvalue{\??cv#1}{#3}}} -\def\docheckedconversion#1#2% - {\ctxlua{converters.convert("#1",#2)}} +\def\checkedconversion#1#2% + {\ctxcommand{checkedconversion("#1",#2)}} %D If a conversion is just a font switch then we need to make sure %D that the number is indeed end up as number in the input, so we diff --git a/tex/context/base/core-ctx.mkiv b/tex/context/base/core-ctx.mkiv index 5d3e27dc2..f6e5a33f1 100644 --- a/tex/context/base/core-ctx.mkiv +++ b/tex/context/base/core-ctx.mkiv @@ -19,7 +19,7 @@ \registerctxluafile{core-ctx}{1.000} -\def\loadctxpreplist{\ctxlua{commands.loadctxpreplist()}\global\let\loadctxpreplist\relax} +\def\loadctxpreplist{\ctxcommand{loadctxpreplist()}\global\let\loadctxpreplist\relax} % \prependtoks\loadctxpreplist\to\everyjob diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv index 1b70e983f..e4d7bce55 100644 --- a/tex/context/base/core-env.mkiv +++ b/tex/context/base/core-env.mkiv @@ -242,7 +242,7 @@ % We can consider: % -% \setvalue{\??su->\v!auto}#1{\ctxlua{commands.autosetup("#1")}} +% \setvalue{\??su->\v!auto}#1{\ctxcommand{autosetup("#1")}} % % ":\letterpercent" => "->\v!auto" with "\endcsname{#1}" % @@ -267,10 +267,10 @@ % setups={S1,lua(S2),xml(test{123}),S3} \def\dodoprocesslocalsetups - {\ctxlua{commands.autosetups("\tobeprocessedsetups")}} + {\ctxcommand{autosetups("\tobeprocessedsetups")}} \def\autosetups#1% - {\ctxlua{commands.autosetups("#1")}} + {\ctxcommand{autosetups("#1")}} \edef\setupwithargument#1% saves a few expansions {\noexpand\csname\??su:\noexpand\ifcsname\??su:#1\endcsname#1\noexpand\else\letterpercent\noexpand\fi\endcsname} diff --git a/tex/context/base/core-fil.mkiv b/tex/context/base/core-fil.mkiv index e54095bb1..4ab78f082 100644 --- a/tex/context/base/core-fil.mkiv +++ b/tex/context/base/core-fil.mkiv @@ -93,7 +93,7 @@ %D can \type {\end} in modules. \def\dodousemodules#1#2% - {\ctxlua{commands.usemodules("#1","#2","\truefilename{#2}")}} + {\ctxcommand{usemodules("#1","#2","\truefilename{#2}")}} \def\usemodules {\dotripleempty\dousemodules} @@ -218,7 +218,7 @@ \doglobal\setflag{#2}}% \ifx#1\undefined \writestatus\m!systems{command \string#1 not found in file #2}% - \def#1{{\infofont[unknown command \string#1]}}% + \gdef#1{{\infofont[unknown command \string#1]}}% \fi #1} diff --git a/tex/context/base/core-job.mkiv b/tex/context/base/core-job.mkiv index 4f4636ba9..d2e3dee1f 100644 --- a/tex/context/base/core-job.mkiv +++ b/tex/context/base/core-job.mkiv @@ -43,7 +43,7 @@ \def\dostarttextfile#1% {\global\advance\fileprocesslevel\plusone \setxvalue{\c!file::\number\fileprocesslevel}{#1}% - \@EA\doglobal\@EA\addtocommalist\@EA{#1}\processedfiles} + \doglobal\addtocommalist{#1}\processedfiles} \def\dostoptextfile {\global\advance\fileprocesslevel\minusone} @@ -51,15 +51,15 @@ \def\processlocalfile#1#2% {#1{#2}\donothing{\readfile{#2}\donothing\donothing}} -\def\processfile #1{\ctxlua{commands.processfile("#1")}} -\def\doifinputfileelse #1{\ctxlua{commands.doifinputfileelse("#1")}} -\def\locatefilepath #1{\edef\locatedfilepath{\ctxlua{commands.locatefilepath("#1")}}} -\def\usepath [#1]{\edef\allinputpaths{\ctxlua{commands.usepath("#1")}}} -\def\usesubpath [#1]{\edef\allinputpaths{\ctxlua{commands.usesubpath("#1")}}} +\def\processfile #1{\ctxcommand{processfile("#1")}} +\def\doifinputfileelse #1{\ctxcommand{doifinputfileelse("#1")}} +\def\locatefilepath #1{\edef\locatedfilepath{\ctxcommand{locatefilepath("#1")}}} +\def\usepath [#1]{\edef\allinputpaths{\ctxcommand{usepath("#1")}}} +\def\usesubpath [#1]{\edef\allinputpaths{\ctxcommand{usesubpath("#1")}}} \def\usezipfile {\dodoubleempty\dousezipfile} -\def\dousezipfile[#1][#2]{\ctxlua{commands.usezipfile("#1","#2")}} % [filename] [optional subtree] +\def\dousezipfile[#1][#2]{\ctxcommand{usezipfile("#1","#2")}} % [filename] [optional subtree] \def\loadexamodes {\dosingleempty\doloadexamodes} -\def\doloadexamodes [#1]{\ctxlua{commands.loadexamodes("#1")}} +\def\doloadexamodes [#1]{\ctxcommand{loadexamodes("#1")}} \def\registerfileinfo[#1#2]#3% geen \showmessage ? {\writestatus\m!systems{#1#2 file #3 at line \the\inputlineno}} @@ -78,7 +78,7 @@ \def\loadoptionfile % todo : mark document.* tables as storage {\readjobfile{\jobname.\f!optionextension} {\showmessage\m!systems2{\jobname.\f!optionextension}% - \ctxlua{commands.logoptionfile("\jobname.\f!optionextension")}}% + \ctxcommand{logoptionfile("\jobname.\f!optionextension")}}% {\writestatus\m!systems {no \jobname.\f!optionextension}}} % Most natural ... @@ -153,8 +153,8 @@ \def\doexecutefileonce#1% {\beforesplitstring#1\at.\to\currentfile - \fullexpandtwoargsafter\doifnotinset\currentfile\loadedfiles - {\fullexpandoneargafter\addtocommalist\currentfile\loadedfiles + \doifnotinset\currentfile\loadedfiles + {\addtocommalist\currentfile\loadedfiles \doexecutefile{#1}}} \def\doexecutefile#1% @@ -224,7 +224,7 @@ \unexpanded\def\usecomponent [##1]{#6{##1}}% \fi \advance\filelevel\plusone - \fullexpandoneargafter\addtocommalist{#1}\loadedfiles} + \addtocommalist{#1}\loadedfiles} \def\doprevlevel {\popmacro\currentcomponentpath @@ -285,7 +285,7 @@ {\let\loadedlocalenvironments\empty \def\docommand##1% {\beforesplitstring##1\at.\to\someevironment - \fullexpandoneargafter\addtocommalist\someevironment\loadedlocalenvironments}% + \addtocommalist\someevironment\loadedlocalenvironments}% \processcommalist[#1]\docommand \expanded{\doifcommonelse{\currentproject,\currentproduct,\currentcomponent,\currentenvironment}{\loadedlocalenvironments}} % \expanded not needed {\letvalue{\e!stop\v!localenvironment}\relax} diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv index c6fa25070..ec10fa1fa 100644 --- a/tex/context/base/core-sys.mkiv +++ b/tex/context/base/core-sys.mkiv @@ -377,7 +377,7 @@ % end % \stopluacode % -% \unexpanded\def\define#1#{\ctxlua{commands.define([[\detokenize{#1}]])}} +% \unexpanded\def\define#1#{\ctxcommand{define([[\detokenize{#1}]])}} % % \starttext % \define[2]\whatevera{#1+#2} diff --git a/tex/context/base/data-exp.lua b/tex/context/base/data-exp.lua index 22968df1a..feab32273 100644 --- a/tex/context/base/data-exp.lua +++ b/tex/context/base/data-exp.lua @@ -189,7 +189,8 @@ end local cache = { } -local splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +---- splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +local splitter = Ct(lpeg.splitat(";")) -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") @@ -310,15 +311,16 @@ local function scan(files,spec,path,n,m,r) return files, n, m, r end -function resolvers.scanfiles(path) +function resolvers.scanfiles(path,branch) if trace_locating then - report_resolvers("scanning path '%s'",path) + report_resolvers("scanning path '%s', branch '%s'",path, branch or path) end - local files, n, m, r = scan({ },path .. '/',"",0,0,0) - files.__path__ = path - files.__files__ = n - files.__directories__ = m - files.__remappings__ = r + local realpath = resolvers.resolve(path) -- no shortcut + local files, n, m, r = scan({ },realpath .. '/',"",0,0,0) + files.__path__ = path -- can be selfautoparent:texmf-whatever + files.__files__ = n + files.__directories__ = m + files.__remappings__ = r if trace_locating then report_resolvers("%s files found on %s directories with %s uppercase remappings",n,m,r) end diff --git a/tex/context/base/data-fil.lua b/tex/context/base/data-fil.lua index 05087c9bb..ecbeb52e6 100644 --- a/tex/context/base/data-fil.lua +++ b/tex/context/base/data-fil.lua @@ -19,9 +19,10 @@ local checkgarbage = utilities.garbagecollector and utilities.garbagecollector.c function locators.file(specification) local name = specification.filename - if name and name ~= '' and lfs.isdir(name) then + local realname = resolvers.resolve(name) -- no shortcut + if realname and realname ~= '' and lfs.isdir(realname) then if trace_locating then - report_resolvers("file locator '%s' found",name) + report_resolvers("file locator '%s' found as '%s'",name,realname) end resolvers.appendhash('file',name,true) -- cache elseif trace_locating then @@ -36,9 +37,9 @@ function hashers.file(specification) end function generators.file(specification) - local name = specification.filename - local content = resolvers.scanfiles(name) - resolvers.registerfilehash(name,content,true) + local path = specification.filename + local content = resolvers.scanfiles(path) + resolvers.registerfilehash(path,content,true) end concatinators.file = file.join diff --git a/tex/context/base/data-ini.lua b/tex/context/base/data-ini.lua index ed36b6992..ff115977c 100644 --- a/tex/context/base/data-ini.lua +++ b/tex/context/base/data-ini.lua @@ -219,3 +219,10 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- if profiler and osgetenv("MTX_PROFILE_RUN") == "YES" then -- profiler.start("luatex-profile.log") -- end + +-- a forward definition + +if not resolvers.resolve then + function resolvers.resolve (s) return s end + function resolvers.unresolve(s) return s end +end diff --git a/tex/context/base/data-pre.lua b/tex/context/base/data-pre.lua index fdf304b73..9cf1f0a8c 100644 --- a/tex/context/base/data-pre.lua +++ b/tex/context/base/data-pre.lua @@ -6,6 +6,13 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } +-- It could be interesting to hook the resolver in the file +-- opener so that unresolved prefixes travel around and we +-- get more abstraction. + +-- As we use this beforehand we will move this up in the chain +-- of loading. + --~ print(resolvers.resolve("abc env:tmp file:cont-en.tex path:cont-en.tex full:cont-en.tex rel:zapf/one/p-chars.tex")) local upper, lower, gsub = string.upper, string.lower, string.gsub @@ -14,10 +21,10 @@ local resolvers = resolvers local prefixes = { } -local getenv = resolvers.getenv +local getenv, cleanpath, findgivenfile = resolvers.getenv, resolvers.cleanpath, resolvers.findgivenfile prefixes.environment = function(str) -- getenv is case insensitive anyway - return resolvers.cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") + return cleanpath(getenv(str) or getenv(upper(str)) or getenv(lower(str)) or "") end prefixes.relative = function(str,n) @@ -36,7 +43,7 @@ prefixes.relative = function(str,n) end end end - return resolvers.cleanpath(str) + return cleanpath(str) end prefixes.auto = function(str) @@ -48,20 +55,38 @@ prefixes.auto = function(str) end prefixes.locate = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath((fullname ~= "" and fullname) or str) + local fullname = findgivenfile(str) or "" + return cleanpath((fullname ~= "" and fullname) or str) end prefixes.filename = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.basename((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.basename((fullname ~= "" and fullname) or str)) end prefixes.pathname = function(str) - local fullname = resolvers.findgivenfile(str) or "" - return resolvers.cleanpath(file.dirname((fullname ~= "" and fullname) or str)) + local fullname = findgivenfile(str) or "" + return cleanpath(file.dirname((fullname ~= "" and fullname) or str)) +end + +prefixes.selfautoloc = function(str) + return cleanpath(file.join(getenv('SELFAUTOLOC'),str)) +end + +prefixes.selfautoparent = function(str) + return cleanpath(file.join(getenv('SELFAUTOPARENT'),str)) +end + +prefixes.selfautodir = function(str) + return cleanpath(file.join(getenv('SELFAUTODIR'),str)) +end + +prefixes.home = function(str) + return cleanpath(file.join(getenv('HOME'),str)) end +prefixes["~"] = prefixes.home + prefixes.env = prefixes.environment prefixes.rel = prefixes.relative prefixes.loc = prefixes.locate @@ -88,19 +113,37 @@ local function _resolve_(method,target) end end -local function resolve(str) - if type(str) == "table" then - for k=1,#str do - local v = str[k] - str[k] = resolve(v) or v - end - elseif str and str ~= "" then - str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_) +--~ local function resolve(str) -- use schemes +--~ if type(str) == "table" then +--~ for k=1,#str do +--~ local v = str[k] +--~ str[k] = resolve(v) or v +--~ end +--~ elseif str and str ~= "" then +--~ str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_) +--~ end +--~ return str +--~ end + +local resolved = { } +local abstract = { } + +local function resolve(str) -- use schemes, this one is then for the commandline only + local res = resolved[str] + if not res then + res = gsub(str,"([a-z][a-z]+):([^ \"\']*)",_resolve_) + resolved[str] = res + abstract[res] = str end - return str + return res +end + +local function unresolve(str) + return abstract[str] or str end -resolvers.resolve = resolve +resolvers.resolve = resolve +resolvers.unresolve = unresolve if os.uname then diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index 897adb5c4..fe5ca1db0 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -43,15 +43,25 @@ 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' -resolvers.configbanner = '' -resolvers.homedir = environment.homedir -resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } -resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- rubish path -resolvers.luacnfname = 'texmfcnf.lua' -resolvers.luacnfstate = "unknown" +resolvers.cacheversion = '1.0.1' +resolvers.configbanner = '' +resolvers.homedir = environment.homedir +resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } +resolvers.luacnfname = 'texmfcnf.lua' +resolvers.luacnfstate = "unknown" + +-- resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' -- what a rubish path +-- resolvers.luacnfspec = 'selfautoparent:{/texmf{-local,}{,/web2c},}}' + +resolvers.luacnfspec = { + "selfautoparent:/texmf-local", + "selfautoparent:/texmf-local/web2c", + "selfautoparent:/texmf", + "selfautoparent:/texmf/web2c", + "selfautoparent:", +} -local unset_variable = "unset" +local unset_variable = "unset" local formats = resolvers.formats local suffixes = resolvers.suffixes @@ -136,10 +146,11 @@ end resolvers.getenv = getenv resolvers.env = getenv -local function resolve(key) - local value = instance.variables[key] or "" - return (value ~= "" and value) or getenv(key) or "" -end +--~ local function resolve(key) +--~ local value = instance.variables[key] or "" +--~ return (value ~= "" and value) or getenv(key) or "" +--~ end +--~ local dollarstripper = lpeg.stripper("$") local inhibitstripper = P("!")^0 * Cs(P(1)^0) @@ -151,27 +162,12 @@ local somethingelse = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "") + P(";") * (P(";") / "") + P(1) -local pattern = Cs( (somevariable * (somekey/resolve) + somethingelse)^1 ) - -local function expandvars(lst) -- simple vars - for k=1,#lst do - local lk = lst[k] - lst[k] = lpegmatch(pattern,lk) or lk - end -end - +--~ local pattern = Cs( (somevariable * (somekey/resolve) + somethingelse)^1 ) +--~ --~ local function expandvars(lst) -- simple vars ---~ local variables, getenv = instance.variables, resolvers.getenv ---~ local function resolve(a) ---~ local va = variables[a] or "" ---~ return (va ~= "" and va) or getenv(a) or "" ---~ end --~ for k=1,#lst do ---~ local var = lst[k] ---~ var = gsub(var,"%$([%a%d%_%-]+)",resolve) ---~ var = gsub(var,";+",";") ---~ var = gsub(var,";[!{}/\\]+;",";") ---~ lst[k] = var +--~ local lk = lst[k] +--~ lst[k] = lpegmatch(pattern,lk) or lk --~ end --~ end @@ -184,34 +180,24 @@ local pattern = Cs ( + slash^2 / "/.-/" + (1-slash) * P(-1) * Cc("/") + P(1) - )^1 * Cc("$") + )^1 * Cc("$") -- yes or no $ ) +local cache = { } + local function makepathexpression(str) if str == "." then return "^%./$" else - return lpegmatch(pattern,str) + local c = cache[str] + if not c then + c = lpegmatch(pattern,str) + cache[str] = c + end + return c end end ---~ local function makepathexpression(str) ---~ if str == "." then ---~ return "^%./$" ---~ else ---~ local expression ---~ if not find(str,"/$") then ---~ expression = str .. "/" ---~ else ---~ expression = str ---~ end ---~ expression = gsub(expression,"([%-%.])","%%%1") -- this also influences ---~ expression = gsub(expression,"//+$", '/.*') -- later usage of pathname ---~ expression = gsub(expression,"//", '/.-/') -- not ok for /// but harmless ---~ return "^" .. expression .. "$" ---~ end ---~ end - local function resolve(key) local value = instance.variables[key] if value and value ~= "" then @@ -231,13 +217,6 @@ local function expandedvariable(var) -- simple vars return lpegmatch(pattern,var) or var end ---~ local function expandedvariable(var) -- simple vars ---~ var = gsub(var,"%$([%a%d%_%-]+)",resolve) ---~ var = gsub(var,";+",";") ---~ var = gsub(var,";[!{}/\\]+;",";") ---~ return var ---~ end - local function entry(entries,name) if name and name ~= "" then name = lpegmatch(dollarstripper,name) @@ -289,14 +268,26 @@ local function identify_configuration_files() reportcriticalvariables() resolvers.expandvariables() local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) - expandvars(cnfpaths) --- hm + -- expandvars(cnfpaths) --- hm local luacnfname = resolvers.luacnfname for i=1,#cnfpaths do local filename = collapsepath(filejoin(cnfpaths[i],luacnfname)) - if lfs.isfile(filename) then - specification[#specification+1] = filename + local realname = resolvers.resolve(filename) -- no shortcut + -- if trace_locating then + -- report_resolvers("checking configuration file '%s'",filename) + -- end + if lfs.isfile(realname) then + specification[#specification+1] = filename -- or realname? + if trace_locating then + report_resolvers("found configuration file '%s'",realname) + end + elseif trace_locating then + report_resolvers("unknown configuration file '%s'",realname) end end + if trace_locating then + report_resolvers() + end end end @@ -308,7 +299,8 @@ local function load_configuration_files() local filename = specification[i] local pathname = filedirname(filename) local filename = filejoin(pathname,luacnfname) - local blob = loadfile(filename) + local realname = resolvers.resolve(filename) -- no shortcut + local blob = loadfile(realname) if blob then local setups = instance.setups local data = blob() @@ -410,6 +402,8 @@ local function collapse_configuration_data() -- potential optimization: pass sta end end +-- scheme magic + -- database loading local function load_file_databases() @@ -429,34 +423,24 @@ local function locate_file_databases() local texmfpaths = resolvers.expandedpathlist('TEXMF') for i=1,#texmfpaths do local path = collapsepath(texmfpaths[i]) - local stripped = lpegmatch(inhibitstripper,path) + local stripped = lpegmatch(inhibitstripper,path) -- the !! thing if stripped ~= "" then local runtime = stripped == path path = resolvers.cleanpath(path) - if lfs.isdir(path) then - local spec = resolvers.splitmethod(stripped) - if spec.scheme == "cache" or spec.scheme == "file" then - stripped = spec.path - elseif runtime and (spec.noscheme or spec.scheme == "file") then - stripped = "tree:///" .. stripped - end - if trace_locating then - if runtime then - report_resolvers("locating list of '%s' (runtime)",path) - else - report_resolvers("locating list of '%s' (cached)",path) - end - end - methodhandler('locators',stripped) -- nothing done with result - else - if trace_locating then - if runtime then - report_resolvers("skipping list of '%s' (runtime)",path) - else - report_resolvers("skipping list of '%s' (cached)",path) - end + local spec = resolvers.splitmethod(stripped) + if spec.scheme == "cache" or spec.scheme == "file" then + stripped = spec.path + elseif runtime and (spec.noscheme or spec.scheme == "file") then + stripped = "tree:///" .. stripped + end + if trace_locating then + if runtime then + report_resolvers("locating list of '%s' (runtime)",path) + else + report_resolvers("locating list of '%s' (cached)",path) end end + methodhandler('locators',stripped) end end if trace_locating then @@ -584,16 +568,16 @@ function resolvers.expandvariables() local engine, progname = instance.engine, instance.progname if type(engine) ~= "string" then instance.engine, engine = "", "" end if type(progname) ~= "string" then instance.progname, progname = "", "" end - if engine ~= "" then environment['engine'] = engine end - if progname ~= "" then environment['progname'] = progname end + if engine ~= "" then environment.engine = engine end + if progname ~= "" then environment.progname = progname end for k,v in next, environment do expansions[k] = v end - for k,v in next, environment do -- move environment to expansions (variables are already in there) - if not expansions[k] then expansions[k] = v end - end + -- for k,v in next, environment do -- move environment to expansions (variables are already in there) + -- if expansions[k] == nil then expansions[k] = v end + -- end for k,v in next, variables do -- move variables to expansions - if not expansions[k] then expansions[k] = v end + if expansions[k] == nil then expansions[k] = v end end repeat local busy = false @@ -847,7 +831,8 @@ local function collect_files(names) if type(blobfile) == 'string' then if not dname or find(blobfile,dname) then local kind = hash.type - local search = filejoin(blobpath,blobfile,bname) +--~ local search = filejoin(blobpath,blobfile,bname) +local search = filejoin(blobroot,blobfile,bname) local result = methodhandler('concatinators',hash.type,blobroot,blobfile,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -860,7 +845,8 @@ local function collect_files(names) local vv = blobfile[kk] if not dname or find(vv,dname) then local kind = hash.type - local search = filejoin(blobpath,vv,bname) +--~ local search = filejoin(blobpath,vv,bname) +local search = filejoin(blobroot,vv,bname) local result = methodhandler('concatinators',hash.type,blobroot,vv,bname) if trace_detail then report_resolvers("match: kind '%s', search '%s', result '%s'",kind,search,result) @@ -1105,8 +1091,8 @@ local function collect_instance_files(filename,askedformat,allresults) -- todo : local f = fl[2] local d = dirlist[k] if find(d,expression) then - --- todo, test for readable - result[#result+1] = fl[3] + -- todo, test for readable + result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut done = true if allresults then if trace_detail then diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua index 5ed6e4e1c..5304c0a24 100644 --- a/tex/context/base/data-tmp.lua +++ b/tex/context/base/data-tmp.lua @@ -48,16 +48,17 @@ end -- end of intermezzo -caches = caches or { } -local caches = caches - -caches.base = caches.base or "luatex-cache" -caches.more = caches.more or "context" -caches.direct = false -- true is faster but may need huge amounts of memory -caches.tree = false -caches.force = true -caches.ask = false -caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } +caches = caches or { } +local caches = caches + +caches.base = caches.base or "luatex-cache" +caches.more = caches.more or "context" +caches.direct = false -- true is faster but may need huge amounts of memory +caches.tree = false +caches.force = true +caches.ask = false +caches.relocate = false +caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } local writable, readables, usedreadables = nil, { }, { } @@ -177,7 +178,14 @@ function caches.configfiles() end function caches.hashed(tree) - return md5.hex(gsub(lower(tree),"[\\\/]+","/")) + tree = gsub(tree,"\\$","/") + tree = gsub(tree,"/+$","") + tree = lower(tree) + local hash = md5.hex(tree) + if trace_cache or trace_locating then + report_cache("hashing tree %s, hash %s",tree,hash) + end + return hash end function caches.treehash() diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua index ff2078e73..635780ac9 100644 --- a/tex/context/base/font-afm.lua +++ b/tex/context/base/font-afm.lua @@ -179,7 +179,7 @@ local function get_variables(data,fontmetrics) end local function get_indexes(data,pfbname) - data.luatex.filename = pfbname + data.luatex.filename = resolvers.unresolve(pfbname) -- no shortcut local pfbblob = fontloader.open(pfbname) if pfbblob then local characters = data.characters @@ -330,15 +330,19 @@ function afm.load(filename) end end +local uparser = fonts.map.makenameparser() + unify = function(data, filename) - local unicodevector = fonts.enc.load('unicode').hash + -- local unicodevector = fonts.enc.load('unicode').hash + local unicodevector = fonts.enc.agl.unicodes local glyphs, indices, unicodes, names = { }, { }, { }, { } local verbose, private = fonts.verbose, fonts.privateoffset for name, blob in next, data.characters do local code = unicodevector[name] -- or characters.name_to_unicode[name] if not code then - local u = match(name,"^uni(%x+)$") - code = u and tonumber(u,16) + -- local u = match(name,"^uni(%x+)$") + -- code = u and tonumber(u,16) + code = lpegmatch(uparser,name) if not code then code = private private = private + 1 @@ -367,7 +371,8 @@ unify = function(data, filename) data.glyphs = glyphs data.characters = nil local luatex = data.luatex - luatex.filename = luatex.filename or file.removesuffix(file.basename(filename)) + local filename = luatex.filename or file.removesuffix(file.basename(filename)) + luatex.filename = resolvers.unresolve(filename) -- no shortcut luatex.unicodes = unicodes -- name to unicode luatex.indices = indices -- unicode to index luatex.marks = { } -- todo diff --git a/tex/context/base/font-agl.lua b/tex/context/base/font-agl.lua index 820600acc..325b0225c 100644 --- a/tex/context/base/font-agl.lua +++ b/tex/context/base/font-agl.lua @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['font-map'] = { local allocate = utilities.storage.allocate +fonts = fonts or { } fonts.enc = fonts.enc or { } local enc = fonts.enc local agl = { } @@ -156,7 +157,7 @@ agl.names = allocate { -- to name [0x00AC] = "logicalnot", [0x00AD] = "softhyphen", [0x00AE] = "registered", - [0x00AF] = "overscore", + [0x00AF] = "macron", [0x00B0] = "degree", [0x00B1] = "plusminus", [0x00B2] = "twosuperior", @@ -3694,6 +3695,264 @@ agl.names = allocate { -- to name [0xFFE3] = "macronmonospace", [0xFFE5] = "yenmonospace", [0xFFE6] = "wonmonospace", + + -- extra entries taken from char-def: + + [0x0020] = "space", + [0x007C] = "bar", + [0x00B5] = "mu", + [0x0110] = "Dcroat", + [0x0111] = "dcroat", + [0x013F] = "Ldot", + [0x0140] = "ldot", + [0x0149] = "napostrophe", + [0x017F] = "longs", + [0x01FE] = "Oslashacute", + [0x01FF] = "oslashacute", + [0x02BC] = "afii57929", + [0x02BD] = "afii64937", + [0x0309] = "hookabovecomb", + [0x03C2] = "sigma1", + [0x03D1] = "theta1", + [0x03D2] = "Upsilon1", + [0x03D5] = "phi1", + [0x03D6] = "omega1", + [0x0431] = "afii10066", + [0x0432] = "afii10067", + [0x0433] = "afii10068", + [0x0434] = "afii10069", + [0x0435] = "afii10070", + [0x0436] = "afii10072", + [0x0437] = "afii10073", + [0x0438] = "afii10074", + [0x0439] = "afii10075", + [0x043A] = "afii10076", + [0x043B] = "afii10077", + [0x043C] = "afii10078", + [0x043D] = "afii10079", + [0x043E] = "afii10080", + [0x043F] = "afii10081", + [0x0440] = "afii10082", + [0x0441] = "afii10083", + [0x0442] = "afii10084", + [0x0443] = "afii10085", + [0x0444] = "afii10086", + [0x0445] = "afii10087", + [0x0446] = "afii10088", + [0x0447] = "afii10089", + [0x0448] = "afii10090", + [0x0449] = "afii10091", + [0x044A] = "afii10092", + [0x044B] = "afii10093", + [0x044C] = "afii10094", + [0x044D] = "afii10095", + [0x044E] = "afii10096", + [0x044F] = "afii10097", + [0x0451] = "afii10071", + [0x0452] = "afii10099", + [0x0453] = "afii10100", + [0x0454] = "afii10101", + [0x0455] = "afii10102", + [0x0456] = "afii10103", + [0x0457] = "afii10104", + [0x0458] = "afii10105", + [0x0459] = "afii10106", + [0x045A] = "afii10107", + [0x045B] = "afii10108", + [0x045C] = "afii10109", + [0x045E] = "afii10110", + [0x045F] = "afii10193", + [0x0463] = "afii10194", + [0x0473] = "afii10195", + [0x0475] = "afii10196", + [0x0491] = "afii10098", + [0x04D9] = "afii10846", + [0x05B0] = "afii57799", + [0x05B1] = "afii57801", + [0x05B2] = "afii57800", + [0x05B3] = "afii57802", + [0x05B4] = "afii57793", + [0x05B5] = "afii57794", + [0x05B6] = "afii57795", + [0x05B7] = "afii57798", + [0x05B8] = "afii57797", + [0x05B9] = "afii57806", + [0x05BB] = "afii57796", + [0x05BC] = "afii57807", + [0x05BD] = "afii57839", + [0x05BE] = "afii57645", + [0x05BF] = "afii57841", + [0x05C0] = "afii57842", + [0x05C1] = "afii57804", + [0x05C2] = "afii57803", + [0x05C3] = "afii57658", + [0x05D0] = "afii57664", + [0x05D1] = "afii57665", + [0x05D2] = "afii57666", + [0x05D3] = "afii57667", + [0x05D4] = "afii57668", + [0x05D5] = "afii57669", + [0x05D6] = "afii57670", + [0x05D7] = "afii57671", + [0x05D8] = "afii57672", + [0x05D9] = "afii57673", + [0x05DA] = "afii57674", + [0x05DB] = "afii57675", + [0x05DC] = "afii57676", + [0x05DD] = "afii57677", + [0x05DE] = "afii57678", + [0x05DF] = "afii57679", + [0x05E0] = "afii57680", + [0x05E1] = "afii57681", + [0x05E2] = "afii57682", + [0x05E3] = "afii57683", + [0x05E4] = "afii57684", + [0x05E5] = "afii57685", + [0x05E6] = "afii57686", + [0x05E7] = "afii57687", + [0x05E8] = "afii57688", + [0x05E9] = "afii57689", + [0x05EA] = "afii57690", + [0x05F0] = "afii57716", + [0x05F1] = "afii57717", + [0x05F2] = "afii57718", + [0x060C] = "afii57388", + [0x061B] = "afii57403", + [0x061F] = "afii57407", + [0x0621] = "afii57409", + [0x0622] = "afii57410", + [0x0623] = "afii57411", + [0x0624] = "afii57412", + [0x0625] = "afii57413", + [0x0626] = "afii57414", + [0x0627] = "afii57415", + [0x0628] = "afii57416", + [0x0629] = "afii57417", + [0x062A] = "afii57418", + [0x062B] = "afii57419", + [0x062C] = "afii57420", + [0x062D] = "afii57421", + [0x062E] = "afii57422", + [0x062F] = "afii57423", + [0x0630] = "afii57424", + [0x0631] = "afii57425", + [0x0632] = "afii57426", + [0x0633] = "afii57427", + [0x0634] = "afii57428", + [0x0635] = "afii57429", + [0x0636] = "afii57430", + [0x0637] = "afii57431", + [0x0638] = "afii57432", + [0x0639] = "afii57433", + [0x063A] = "afii57434", + [0x0640] = "afii57440", + [0x0641] = "afii57441", + [0x0642] = "afii57442", + [0x0643] = "afii57443", + [0x0644] = "afii57444", + [0x0645] = "afii57445", + [0x0646] = "afii57446", + [0x0647] = "afii57470", + [0x0648] = "afii57448", + [0x0649] = "afii57449", + [0x064A] = "afii57450", + [0x064B] = "afii57451", + [0x064C] = "afii57452", + [0x064D] = "afii57453", + [0x064E] = "afii57454", + [0x064F] = "afii57455", + [0x0650] = "afii57456", + [0x0651] = "afii57457", + [0x0652] = "afii57458", + [0x0660] = "afii57392", + [0x0661] = "afii57393", + [0x0662] = "afii57394", + [0x0663] = "afii57395", + [0x0664] = "afii57396", + [0x0665] = "afii57397", + [0x0666] = "afii57398", + [0x0667] = "afii57399", + [0x0668] = "afii57400", + [0x0669] = "afii57401", + [0x066A] = "afii57381", + [0x066D] = "afii63167", + [0x0679] = "afii57511", + [0x067E] = "afii57506", + [0x0686] = "afii57507", + [0x0688] = "afii57512", + [0x0691] = "afii57513", + [0x0698] = "afii57508", + [0x06A4] = "afii57505", + [0x06AF] = "afii57509", + [0x06BA] = "afii57514", + [0x06D2] = "afii57519", + [0x200C] = "afii61664", + [0x2015] = "afii208", + [0x2025] = "twodotenleader", + [0x20A1] = "colonmonetary", + [0x20AA] = "afii57636", + [0x20AC] = "Euro", + [0x2105] = "afii61248", + [0x2113] = "afii61289", + [0x2116] = "afii61352", + [0x21A8] = "arrowupdnbse", + [0x21D0] = "arrowdblleft", + [0x21D2] = "arrowdblright", + [0x21D4] = "arrowdblboth", + [0x2203] = "existential", + [0x2206] = "Delta", + [0x2207] = "gradient", + [0x2209] = "notelement", + [0x221F] = "orthogonal", + [0x223C] = "similar", + [0x2282] = "propersubset", + [0x2283] = "propersuperset", + [0x2286] = "reflexsubset", + [0x2287] = "reflexsuperset", + [0x2295] = "circleplus", + [0x2297] = "circlemultiply", + [0x250C] = "SF10000", + [0x2510] = "SF30000", + [0x2514] = "SF20000", + [0x2518] = "SF40000", + [0x251C] = "SF80000", + [0x2524] = "SF90000", + [0x252C] = "SF60000", + [0x2534] = "SF70000", + [0x253C] = "SF50000", + [0x2591] = "ltshade", + [0x2592] = "shade", + [0x2593] = "dkshade", + [0x25A1] = "H22073", + [0x25AA] = "H18543", + [0x25AB] = "H18551", + [0x25CB] = "circle", + [0x25CF] = "H18533", + [0x25D9] = "invcircle", + [0x25E6] = "openbullet", + [0x263A] = "smileface", + [0x2640] = "female", + [0x2642] = "male", + [0x2660] = "spade", + [0x2663] = "club", + [0x2665] = "heart", + } -agl.unicodes = allocate(table.swapped(agl.names)) -- to unicode +local unicodes = allocate(table.swapped(agl.names)) -- to unicode + +agl.unicodes = unicodes + +-- dofile("char-def.lua") +-- +-- for k,v in table.sortedpairs(characters.data) do +-- if v.adobename then +-- if unicodes[v.adobename] ~= k then +-- if not unicodes[k] then +-- print(string.format('[0x%04X] = "%s",',k,v.adobename)) +-- else +-- -- print(string.format('unicodes[%s] = %s,',v.adobename,k)) +-- end +-- end +-- end +-- end diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua index 7b4f4a4f8..a70d30c10 100644 --- a/tex/context/base/font-enc.lua +++ b/tex/context/base/font-enc.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-enc'] = { license = "see context related readme files" } +-- this module is obsolete + local match, gmatch, gsub = string.match, string.gmatch, string.gsub --[[ldx-- diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv index 5435de545..6a8c9594f 100644 --- a/tex/context/base/font-ini.mkiv +++ b/tex/context/base/font-ini.mkiv @@ -4299,7 +4299,7 @@ % \doifelsecurrentfonthasfeature{kern}{YES}{NO} \def\doifelsecurrentfonthasfeature#1% - {\ctxlua{commands.doifelsecurrentfonthasfeature("#1")}} + {\ctxcommand{doifelsecurrentfonthasfeature("#1")}} \protect \endinput diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index bfd3262ba..ee7964b60 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -543,7 +543,7 @@ end actions["prepare tables"] = function(data,filename,raw) local luatex = { - filename = filename, + filename = resolvers.unresolve(filename), -- no shortcut version = otf.version, creator = "context mkiv", } diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index c6f7b0393..4420c6092 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -407,7 +407,7 @@ local function check_name(data,result,filename,suffix,subfont) fullname = fullname or fontname familyname = familyname or fontname specifications[#specifications + 1] = { - filename = filename, + filename = filename, -- unresolved format = lower(suffix), subfont = subfont, rawname = rawname, @@ -739,12 +739,15 @@ local function analyzefiles() resolvers.dowithfilesintree(".*%." .. suffix .. "$", function(method,root,path,name) if method == "file" or method == "tree" then local completename = root .."/" .. path .. "/" .. name + completename = resolvers.resolve(completename) -- no shortcut identify(completename,name,suffix,name) return true end end, function(blobtype,blobpath,pattern) + blobpath = resolvers.resolve(blobpath) -- no shortcut report_names( "scanning %s for %s files",blobpath,suffix) end, function(blobtype,blobpath,pattern,total,checked,done) + blobpath = resolvers.resolve(blobpath) -- no shortcut report_names( "%s entries found, %s %s files checked, %s okay",total,checked,suffix,done) end) end) diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua index 68a92532b..baa6ffb69 100644 --- a/tex/context/base/font-tfm.lua +++ b/tex/context/base/font-tfm.lua @@ -744,6 +744,7 @@ function tfm.checkedfilename(metadata,whatever) if not foundfilename then local askedfilename = metadata.filename or "" if askedfilename ~= "" then + askedfilename = resolvers.resolve(askedfilename) -- no shortcut foundfilename = resolvers.findbinfile(askedfilename,"") or "" if foundfilename == "" then report_define("source file '%s' is not found",askedfilename) diff --git a/tex/context/base/font-tra.mkiv b/tex/context/base/font-tra.mkiv index 527941162..37ea4541a 100644 --- a/tex/context/base/font-tra.mkiv +++ b/tex/context/base/font-tra.mkiv @@ -21,7 +21,7 @@ %D \doiffontpresentelse{adam-lindsay-modern-serif}{YES}{NO} %D \stoptyping -\def\doiffontpresentelse#1{\ctxlua{commands.doifelse(fonts.names.exists("#1"))}} +\def\doiffontpresentelse#1{\ctxcommand{doifelse(fonts.names.exists("#1"))}} % experimental, maybe this becomes a module diff --git a/tex/context/base/font-uni.mkiv b/tex/context/base/font-uni.mkiv index dddc8420b..8fb5d0996 100644 --- a/tex/context/base/font-uni.mkiv +++ b/tex/context/base/font-uni.mkiv @@ -19,7 +19,7 @@ \unprotect -%def\uchar#1#2{\ctxlua{commands.uchar(,)}} +%def\uchar#1#2{\ctxcommand{uchar(,)}} \def\uchar#1#2{\cldcontext{utf.char(\number\numexpr#1*256+#2\relax)}} \let\uc\uchar diff --git a/tex/context/base/grph-fig.mkiv b/tex/context/base/grph-fig.mkiv index b789c51e2..a89c0afc5 100644 --- a/tex/context/base/grph-fig.mkiv +++ b/tex/context/base/grph-fig.mkiv @@ -517,7 +517,7 @@ {\bgroup \global\advance\noftypesetbuffers\plusone \edef\bufferfilename{\jobname-buffer-\the\noftypesetbuffers}% - \ctxlua{commands.runbuffer("\bufferfilename.tmp","#1",true)}% + \ctxcommand{runbuffer("\bufferfilename.tmp","#1",true)}% \externalfigure[\bufferfilename.pdf][#2]% \egroup} @@ -541,10 +541,7 @@ \definesystemvariable{tz} \unexpanded\def\definetypesetting{\dotripleempty\dodefinetypesetting} -\def\typesetfile {\dotripleempty\dotypesetfile} - -\unexpanded\def\definetypesetting{\dotripleempty\dodefinetypesetting} -\def\typesetfile {\dotripleempty\dotypesetfile} +\unexpanded\def\typesetfile {\dotripleempty\dotypesetfile} \def\dodefinetypesetting[#1][#2][#3]% <name> options settings-a {\doifsomething{#1}{\setvalue{\??tz#1}{\dodotypesetfile{#2}{#3}}}} diff --git a/tex/context/base/hand-ini.mkiv b/tex/context/base/hand-ini.mkiv index 0285b10cb..7b9732059 100644 --- a/tex/context/base/hand-ini.mkiv +++ b/tex/context/base/hand-ini.mkiv @@ -42,8 +42,8 @@ \unexpanded\def\setupfontexpansion {\dodoubleargument\dosetupfontexpansion } \unexpanded\def\setupfontprotrusion{\dodoubleargument\dosetupfontprotrusion} -\def\dosetupfontexpansion [#1][#2]{\ctxlua{commands.setupfontexpansion ("#1","#2")}} -\def\dosetupfontprotrusion[#1][#2]{\ctxlua{commands.setupfontprotrusion("#1","#2")}} +\def\dosetupfontexpansion [#1][#2]{\ctxcommand{setupfontexpansion ("#1","#2")}} +\def\dosetupfontprotrusion[#1][#2]{\ctxcommand{setupfontprotrusion("#1","#2")}} % \setupfontprotrusion[quality-upright][vector=quality] % \setupfontprotrusion[quality-slanted][vector=quality,right=1.5] diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua index ecab94920..a53c06adf 100644 --- a/tex/context/base/java-ini.lua +++ b/tex/context/base/java-ini.lua @@ -15,6 +15,10 @@ local variables = interfaces.variables -- todo: don't flush scripts if no JS key +local trace_javascript = false trackers.register("backends.javascript", function(v) trace_javascript = v end) + +local report_javascript = logs.new("javascript") + interactions.javascripts = interactions.javascripts or { } local javascripts = interactions.javascripts @@ -59,17 +63,25 @@ end function javascripts.storepreamble(str) -- now later local name, used, script = lpegmatch(parsepreamble,str) - if name and name ~= "" then - preambles[#preambles+1] = { name, used, script } - preambled[name] = #preambles + if name and name ~= "" and not preambled[name] then + local n = #preambles + 1 + preambles[n] = { name, used, script } + preambled[name] = n + if trace_javascript then + report_javascript("storing preamble '%s', state '%s', order '%s'",name,used,n) + end lpegmatch(parsefunctions,script) end end function javascripts.setpreamble(name,script) -- now later - if name and name ~= "" then - preambles[#preambles+1] = { name, "now", script } - preambled[name] = #preambles + if name and name ~= "" and not preambled[name] then + local n = #preambles + 1 + preambles[n] = { name, "now", script } + preambled[name] = n + if trace_javascript then + report_javascript("setting preamble '%s', state 'now', order '%s'",name,n) + end lpegmatch(parsefunctions,script) end end @@ -79,9 +91,16 @@ function javascripts.addtopreamble(name,script) -- now later local p = preambled[name] if p then preambles[p] = { "now", preambles[p] .. " ;\n" .. script } + if trace_javascript then + report_javascript("extending preamble '%s', state 'now'",name) + end else - preambles[#preambles+1] = { name, "now", script } - preambled[name] = #preambles + local n = #preambles + 1 + preambles[n] = { name, "now", script } + preambled[name] = n + if trace_javascript then + report_javascript("storing preamble '%s', state 'now', order '%s'",name,n) + end lpegmatch(parsefunctions,script) end end @@ -94,6 +113,9 @@ function javascripts.usepreamblenow(name) -- now later local somename = names[i] if not preambled[somename] then preambles[preambled[somename]][2] = "now" + if trace_javascript then + report_javascript("using preamble '%s', state 'now'",somename) + end end end end @@ -101,7 +123,7 @@ end local splitter = lpeg.Ct(lpeg.splitat(lpeg.patterns.commaspacer)) -local used = false +local used, reported = false, { } -- we can cache more function javascripts.code(name,arguments) local c = codes[name] @@ -110,8 +132,18 @@ function javascripts.code(name,arguments) if u ~= "" then local p = preambled[u] if p then - preambles[p][1] = "now" + preambles[p][2] = "now" + if trace_javascript and not reported[name] then + reported[name] = true + report_javascript("using code '%s', preamble '%s'",name,u) + end + elseif trace_javascript and not reported[name] then + reported[name] = true + report_javascript("using code '%s'",name) end + elseif trace_javascript and not reported[name] then + reported[name] = true + report_javascript("using code '%s'",name) end used = true return code @@ -119,6 +151,10 @@ function javascripts.code(name,arguments) local f = functions[name] if f then used = true + if trace_javascript and not reported[name] then + reported[name] = true + report_javascript("using function '%s'",name) + end if arguments then local args = lpegmatch(splitter,arguments) for i=1,#args do -- can be a helper @@ -137,6 +173,9 @@ function javascripts.flushpreambles() for i=1,#preambles do local preamble = preambles[i] if preamble[2] == "now" then + if trace_javascript then + report_javascript("flushing preamble '%s'",preamble[1]) + end t[#t+1] = { preamble[1], preamble[3] } end end @@ -149,10 +188,12 @@ local patterns = { "java-imp-%s.mkiv", "java-imp-%s.tex", "java-%s.mkiv", "java- function javascripts.usescripts(name) if name ~= variables.reset then commands.uselibrary(name,patterns,function(name,foundname) + context.startnointerference() context.startreadingfile() context.input(foundname) context.showcolormessage("javascript",1,name) context.stopreadingfile() + context.stopnointerference() end) end end diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua index 0d77d13d3..1c557bc49 100644 --- a/tex/context/base/l-dimen.lua +++ b/tex/context/base/l-dimen.lua @@ -169,7 +169,7 @@ local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") + local validdimen = amount * unit -lpeg.patterns.validdimen = pattern +lpeg.patterns.validdimen = validdimen --[[ldx-- <p>This converter accepts calls like:</p> @@ -329,9 +329,11 @@ function dimensions.texify() -- todo: % if fti and fc then dimenfactors["ex"] = function() return fti[fc()].ex_height end dimenfactors["em"] = function() return fti[fc()].quad end + -- dimenfactors["%"] = function() return tex.dimen.hsize/100 end else - dimenfactors["ex"] = 1/65536* 4 -- 4pt - dimenfactors["em"] = 1/65536*10 -- 10pt + dimenfactors["ex"] = 1/65536* 4 -- 4pt + dimenfactors["em"] = 1/65536*10 -- 10pt + -- dimenfactors["%"] = 1/65536* 4 -- 400pt/100 end end @@ -392,7 +394,7 @@ function dimen(a) end end -function string.todimen(str) +function string.todimen(str) -- maybe use tex.sp when available if type(str) == "number" then return str else @@ -400,7 +402,7 @@ function string.todimen(str) if not k then local value, unit = lpegmatch(dimenpair,str) if value and unit then - k = value/unit + k = value/unit -- to be considered: round else k = 0 end @@ -411,6 +413,17 @@ function string.todimen(str) end end +--~ local known = { } + +--~ function string.todimen(str) -- maybe use tex.sp +--~ local k = known[str] +--~ if not k then +--~ k = tex.sp(str) +--~ known[str] = k +--~ end +--~ return k +--~ end + stringtodimen = string.todimen -- local variable defined earlier function number.toscaled(d) diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 9193bac9a..868a6d52e 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -284,6 +284,14 @@ function lpeg.keeper(str) end end +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end + +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + -- Just for fun I looked at the used bytecode and -- p = (p and p + pp) or pp gets one more (testset). diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua index 47d8127de..d75135a2a 100644 --- a/tex/context/base/l-url.lua +++ b/tex/context/base/l-url.lua @@ -52,8 +52,10 @@ local path = slash * Cs((escaped+(1- qmark-hash))^0) local query = qmark * Cs((escaped+(1- hash))^0) + nothing local fragment = hash * Cs((escaped+(1- endofstring))^0) + nothing -local parser = Ct(scheme * authority * path * query * fragment) +local validurl = scheme * authority * path * query * fragment +local parser = Ct(validurl) +lpegpatterns.url = validurl lpegpatterns.urlsplitter = parser local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end diff --git a/tex/context/base/lang-def.mkiv b/tex/context/base/lang-def.mkiv index 88f4f1cdf..f766082fc 100644 --- a/tex/context/base/lang-def.mkiv +++ b/tex/context/base/lang-def.mkiv @@ -328,8 +328,8 @@ \defineconversion [sl] [AK] [\smallcapped\sloveniancharacters] \defineconversion [sl] [KA] [\smallcapped\sloveniancharacters] -\def\sloveniancharacters#1{\ctxlua{converters.alphabetic(\number#1,"sl")}} -\def\slovenianCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"sl")}} +\def\sloveniancharacters#1{\ctxcommand{alphabetic(\number#1,"sl")}} +\def\slovenianCharacters#1{\ctxcommand{Alphabetic(\number#1,"sl")}} % Cyrillic Languages diff --git a/tex/context/base/lang-url.mkiv b/tex/context/base/lang-url.mkiv index c21acc033..a3cf466de 100644 --- a/tex/context/base/lang-url.mkiv +++ b/tex/context/base/lang-url.mkiv @@ -62,9 +62,9 @@ \def\dohyphenatedurlnormal#1{\char#1\relax}% \def\dohyphenatedurldisc #1{\discretionary{}{}{}} -\def\sethyphenatedurlnormal #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,0)}} -\def\sethyphenatedurlbefore #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,1)}} -\def\sethyphenatedurlafter #1{\ctxlua{commands.hyphenatedurl.setcharacters(\!!bs#1\!!es,2)}} +\def\sethyphenatedurlnormal #1{\ctxcommand{hyphenatedurl.setcharacters(\!!bs#1\!!es,0)}} +\def\sethyphenatedurlbefore #1{\ctxcommand{hyphenatedurl.setcharacters(\!!bs#1\!!es,1)}} +\def\sethyphenatedurlafter #1{\ctxcommand{hyphenatedurl.setcharacters(\!!bs#1\!!es,2)}} \def\hyphenatedurldiscretionary{} @@ -81,7 +81,7 @@ \let\b\dohyphenatedurlbefore \let\a\dohyphenatedurlafter \let\d\dohyphenatedurldisc - \normalexpanded{\noexpand\ctxlua{commands.hyphenatedurl.action( + \normalexpanded{\noexpand\ctxcommand{hyphenatedurl.action( \!!bs\noexpand\detokenize{#1}\!!es, \number\hyphenatedurllefthyphenmin, \number\hyphenatedurlrighthyphenmin, diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua index 79b184e9a..88ea617ed 100644 --- a/tex/context/base/lpdf-fld.lua +++ b/tex/context/base/lpdf-fld.lua @@ -20,34 +20,37 @@ local report_fields = logs.new("fields") local backends, lpdf = backends, lpdf -local variables = interfaces.variables -local context = context - -local references = structures.references -local settings_to_array = utilities.parsers.settings_to_array - -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 -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfstring = lpdf.string -local pdfconstant = lpdf.constant -local pdftoeight = lpdf.toeight -local pdfflushobject = lpdf.flushobject -local pdfshareobjectref = lpdf.shareobjectreference -local pdfreserveobject = lpdf.reserveobject -local pdfreserveannotation = lpdf.reserveannotation - -local nodepool = nodes.pool - -local pdfannotation_node = nodepool.pdfannotation +local variables = interfaces.variables +local context = context + +local references = structures.references +local settings_to_array = utilities.parsers.settings_to_array + +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 +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfconstant = lpdf.constant +local pdftoeight = lpdf.toeight +local pdfflushobject = lpdf.flushobject +local pdfimmediateobject = lpdf.immediateobject +local pdfshareobjectreference = lpdf.shareobjectreference +local pdfshareobject = lpdf.shareobject +local pdfreserveobject = lpdf.reserveobject +local pdfreserveannotation = lpdf.reserveannotation +local pdfaction = lpdf.action + +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 @@ -125,24 +128,45 @@ local function fieldplus(specification) return n end +-- local function checked(what) +-- local set, bug = references.identify("",what) +-- return not bug and #set > 0 and lpdf.action(set) +-- end + local function checked(what) - if what and what ~= "" then - local set, bug = references.identify("",what) - return not bug and #set > 0 and lpdf.action(set) + local set, bug = references.identify("",what) + if not bug and #set > 0 then + local r, n = pdfaction(set) + return pdfshareobjectreference(r) end end +-- a dedicated hash is faster, but maybe overkill + +--~ local cache = { } +--~ +--~ local function checked(what) +--~ local set, bug = references.identify("",what) +--~ if not bug and #set > 0 then +--~ local r = cache[set] +--~ if not r then +--~ r = pdfreference(pdfimmediateobject(pdfaction(set))) +--~ cache[set] = r +--~ end +--~ return r +--~ end +--~ end + local function fieldactions(specification) -- share actions ---~ print(table.serialize(specification)) local d, a = { }, nil a = specification.mousedown if a and a ~= "" then d.D = checked(a) end a = specification.mouseup if a and a ~= "" then d.U = checked(a) end a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit - a = specification.afterkeystroke if a and a ~= "" then d.K = checked(a) end - a = specification.formatresult if a and a ~= "" then d.F = checked(a) end - a = specification.validateresult if a and a ~= "" then d.V = checked(a) end - a = specification.calculatewhatever if a and a ~= "" then d.C = checked(a) end + a = specification.afterkey if a and a ~= "" then d.K = checked(a) end + a = specification.format if a and a ~= "" then d.F = checked(a) end + a = specification.validate if a and a ~= "" then d.V = checked(a) end + a = specification.calculate if a and a ~= "" then d.C = checked(a) end a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end -- a = specification.openpage if a and a ~= "" then d.PO = checked(a) end @@ -261,7 +285,7 @@ local function fieldappearances(specification) local appearance = pdfdictionary { -- cache this one N = registeredsymbol(n), R = registeredsymbol(r), D = registeredsymbol(d), } - return pdfshareobjectref(appearance) + return pdfshareobjectreference(appearance) end local function fieldstates(specification,forceyes,values,default) @@ -323,7 +347,7 @@ local function fieldstates(specification,forceyes,values,default) R = pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }, D = pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) } } - local appearanceref = pdfshareobjectref(appearance) + local appearanceref = pdfshareobjectreference(appearance) return appearanceref, default end diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua index 0d96d8086..1ca41ed7c 100644 --- a/tex/context/base/lpdf-wid.lua +++ b/tex/context/base/lpdf-wid.lua @@ -122,7 +122,8 @@ end function codeinjections.registercomment(specification) nofcomments = nofcomments + 1 local text = buffers.collectcontent(specification.buffer) - if stripleading then + text = string.strip(text) + if stripleading then -- maybe just strip all leading and trailing spacing text = gsub(text,"[\n\r] *","\n") end local name, appearance = analyzesymbol(specification.symbol) diff --git a/tex/context/base/luat-cod.mkiv b/tex/context/base/luat-cod.mkiv index 6c9da7e51..7c0298f4c 100644 --- a/tex/context/base/luat-cod.mkiv +++ b/tex/context/base/luat-cod.mkiv @@ -15,9 +15,8 @@ \unprotect -\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded - \long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded} +%long\def\expanded#1{\normalexpanded{\noexpand#1}} % compatible ## mess \newif\ifproductionrun @@ -48,6 +47,7 @@ \def\ctxlatelua {\latelua \zerocount} \def\ctxsprint #1{\directlua\zerocount{tex.sprint(tex.ctxcatcodes,#1)}} % saves tokens \def\ctxwrite #1{\directlua\zerocount{tex.write(#1)}} % saves tokens +\def\ctxcommand#1{\directlua\zerocount{commands.#1}} % saves tokens %D Take your choice \unknown diff --git a/tex/context/base/luat-dum.lua b/tex/context/base/luat-dum.lua index d8d236df2..a7f602eb0 100644 --- a/tex/context/base/luat-dum.lua +++ b/tex/context/base/luat-dum.lua @@ -80,6 +80,14 @@ function resolvers.findbinfile(name,kind) return resolvers.findfile(name,(kind and remapper[kind]) or kind) end +function resolvers.resolve(s) + return s +end + +function resolvers.unresolve(s) + return s +end + -- Caches ... I will make a real stupid version some day when I'm in the -- mood. After all, the generic code does not need the more advanced -- ConTeXt features. Cached data is not shared between ConTeXt and other diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv index 7403c9f88..a1d6b50a8 100644 --- a/tex/context/base/lxml-ini.mkiv +++ b/tex/context/base/lxml-ini.mkiv @@ -28,89 +28,91 @@ \def\c!entities{entities} % to be internationalized -\def\xmlmain #1{\ctxlua{lxml.main("#1")}} -\def\xmlmatch #1{\ctxlua{lxml.match("#1")}} -\def\xmlall #1#2{\ctxlua{lxml.all("#1","#2")}} -\def\xmlatt #1#2{\ctxlua{lxml.att("#1","#2")}} -\def\xmlattdef #1#2#3{\ctxlua{lxml.att("#1","#2","#3")}} -\def\xmlchainatt #1#2{\ctxlua{lxml.chainattribute("#1","/","#2")}} -\def\xmlchainattdef #1#2#3{\ctxlua{lxml.chainattribute("#1","/","#2","#3")}} -\def\xmlattribute #1#2#3{\ctxlua{lxml.attribute("#1","#2","#3")}} -\def\xmlattributedef #1#2#3#4{\ctxlua{lxml.attribute("#1","#2","#3","#4")}} -\def\xmlcommand #1#2#3{\ctxlua{lxml.command("#1","#2","#3")}} -\def\xmlconcat #1#2#3{\ctxlua{lxml.concat("#1","#2",[[\detokenize{#3}]])}} -\def\xmlconcatrange#1#2#3#4#5{\ctxlua{lxml.concatrange("#1","#2","#3","#4",[[\detokenize{#5}]])}} -\def\xmlcount #1#2{\ctxlua{lxml.count("#1","#2")}} -\def\xmldelete #1#2{\ctxlua{lxml.delete("#1","#2")}} -\def\xmldirectives #1{\ctxlua{lxml.directives.setup("#1")}} -\def\xmldirectivesbefore #1{\ctxlua{lxml.directives.before("#1")}} -\def\xmldirectivesafter #1{\ctxlua{lxml.directives.after("#1")}} -\def\xmlfilter #1#2{\ctxlua{lxml.filter("#1",\!!bs#2\!!es)}} -\def\xmlfilterlist #1#2{\ctxlua{lxml.filterlist("#1",\!!bs#2\!!es)}} -\def\xmlfunction #1#2{\ctxlua{lxml["function"]("#1",\!!bs#2\!!es)}} -\def\xmlfirst #1#2{\ctxlua{lxml.first("#1","#2")}} -\def\xmlflush #1{\ctxlua{lxml.flush("#1")}} -%def\xmlcontent #1{\ctxlua{lxml.content("#1")}} -%def\xmlflushstripped #1{\ctxlua{lxml.strip("#1",true)}} -\def\xmldirect #1{\ctxlua{lxml.direct("#1")}} % in loops, not dt but root -\def\xmlidx #1#2#3{\ctxlua{lxml.idx("#1","#2",\number#3)}} -\def\xmlinclude #1#2#3{\ctxlua{lxml.include("#1","#2","#3",true)}} -\def\xmlindex #1#2#3{\ctxlua{lxml.index("#1","#2",\number#3)}} -\def\xmlinfo #1{\hbox{\ttxx[\ctxlua{lxml.info("#1")}]}} +\def\ctxlxml #1{\directlua\zerocount{lxml.#1}} + +\def\xmlmain #1{\ctxlxml{main("#1")}} +\def\xmlmatch #1{\ctxlxml{match("#1")}} +\def\xmlall #1#2{\ctxlxml{all("#1","#2")}} +\def\xmlatt #1#2{\ctxlxml{att("#1","#2")}} +\def\xmlattdef #1#2#3{\ctxlxml{att("#1","#2","#3")}} +\def\xmlchainatt #1#2{\ctxlxml{chainattribute("#1","/","#2")}} +\def\xmlchainattdef #1#2#3{\ctxlxml{chainattribute("#1","/","#2","#3")}} +\def\xmlattribute #1#2#3{\ctxlxml{attribute("#1","#2","#3")}} +\def\xmlattributedef #1#2#3#4{\ctxlxml{attribute("#1","#2","#3","#4")}} +\def\xmlcommand #1#2#3{\ctxlxml{command("#1","#2","#3")}} +\def\xmlconcat #1#2#3{\ctxlxml{concat("#1","#2",[[\detokenize{#3}]])}} +\def\xmlconcatrange#1#2#3#4#5{\ctxlxml{concatrange("#1","#2","#3","#4",[[\detokenize{#5}]])}} +\def\xmlcount #1#2{\ctxlxml{count("#1","#2")}} +\def\xmldelete #1#2{\ctxlxml{delete("#1","#2")}} +\def\xmldirectives #1{\ctxlxml{directives.setup("#1")}} +\def\xmldirectivesbefore #1{\ctxlxml{directives.before("#1")}} +\def\xmldirectivesafter #1{\ctxlxml{directives.after("#1")}} +\def\xmlfilter #1#2{\ctxlxml{filter("#1",\!!bs#2\!!es)}} +\def\xmlfilterlist #1#2{\ctxlxml{filterlist("#1",\!!bs#2\!!es)}} +\def\xmlfunction #1#2{\ctxlxml{applyfunction("#1",\!!bs#2\!!es)}} +\def\xmlfirst #1#2{\ctxlxml{first("#1","#2")}} +\def\xmlflush #1{\ctxlxml{flush("#1")}} +%def\xmlcontent #1{\ctxlxml{content("#1")}} +%def\xmlflushstripped #1{\ctxlxml{strip("#1",true)}} +\def\xmldirect #1{\ctxlxml{direct("#1")}} % in loops, not dt but root +\def\xmlidx #1#2#3{\ctxlxml{idx("#1","#2",\number#3)}} +\def\xmlinclude #1#2#3{\ctxlxml{include("#1","#2","#3",true)}} +\def\xmlindex #1#2#3{\ctxlxml{index("#1","#2",\number#3)}} +\def\xmlinfo #1{\hbox{\ttxx[\ctxlxml{info("#1")}]}} \def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} -\def\xmllast #1#2{\ctxlua{lxml.last("#1","#2")}} -\def\xmlname #1{\ctxlua{lxml.name("#1")}} -\def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}} -\def\xmlnonspace #1#2{\ctxlua{lxml.nonspace("#1","#2")}} -\def\xmlraw #1#2{\ctxlua{lxml.raw("#1","#2")}} -\def\xmlcontext #1#2{\ctxlua{lxml.context("#1","#2")}} -\def\xmlflushcontext #1{\ctxlua{lxml.context("#1")}} -\def\xmlsnippet #1#2{\ctxlua{lxml.snippet("#1",#2)}} -\def\xmlelement #1#2{\ctxlua{lxml.element("#1",#2)}} +\def\xmllast #1#2{\ctxlxml{last("#1","#2")}} +\def\xmlname #1{\ctxlxml{name("#1")}} +\def\xmlnamespace #1{\ctxlxml{namespace("#1")}} +\def\xmlnonspace #1#2{\ctxlxml{nonspace("#1","#2")}} +\def\xmlraw #1#2{\ctxlxml{raw("#1","#2")}} +\def\xmlcontext #1#2{\ctxlxml{context("#1","#2")}} +\def\xmlflushcontext #1{\ctxlxml{context("#1")}} +\def\xmlsnippet #1#2{\ctxlxml{snippet("#1",#2)}} +\def\xmlelement #1#2{\ctxlxml{element("#1",#2)}} \def\xmlregisterns #1#2{\ctxlua{xml.registerns("#1","#2")}} % document \def\xmlremapname #1#2#3#4{\ctxlua{xml.remapname(lxml.id("#1"),"#2","#3","#4")}} % element \def\xmlremapnamespace #1#2#3{\ctxlua{xml.renamespace(lxml.id("#1"),"#2","#3")}} % document \def\xmlchecknamespace #1#2#3{\ctxlua{xml.checknamespace(lxml.id("#1"),"#2","#3")}} % element -\def\xmlsetfunction #1#2#3{\ctxlua{lxml.setaction("#1","#2",#3)}} -\def\xmlsetsetup #1#2#3{\ctxlua{lxml.setsetup("#1","#2","#3")}} -\def\xmlstrip #1#2{\ctxlua{lxml.strip("#1","#2")}} -\def\xmlstripnolines #1#2{\ctxlua{lxml.strip("#1","#2",true)}} -\def\xmlstripanywhere #1#2{\ctxlua{lxml.strip("#1","#2",true,true)}} -\def\xmlstripped #1#2{\ctxlua{lxml.stripped("#1","#2")}} -\def\xmlstrippednolines #1#2{\ctxlua{lxml.stripped("#1","#2",true)}} -\def\xmltag #1{\ctxlua{lxml.tag("#1")}} -\def\xmltext #1#2{\ctxlua{lxml.text("#1","#2")}} -\def\xmlverbatim #1{\ctxlua{lxml.verbatim("#1")}} -\def\xmldisplayverbatim #1{\ctxlua{lxml.displayverbatim("#1")}} -\def\xmlinlineverbatim #1{\ctxlua{lxml.inlineverbatim("#1")}} - -\def\xmlload #1#2{\ctxlua{lxml.load("#1","#2","\@@xmentities","\@@xmcompress")}} -\def\xmlloadbuffer #1#2{\ctxlua{lxml.loadbuffer("#1","#2","\@@xmentities","\@@xmcompress")}} -\def\xmlloaddata #1#2{\ctxlua{lxml.loaddata("#1",\!!bs#2\!!es,"\@@xmentities","\@@xmcompress")}} -\def\xmlloadregistered #1#2{\ctxlua{lxml.loadregistered("#1","\@@xmentities","\@@xmcompress")}} -\def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("any:///#1")}} -\def\xmlpos #1{\ctxlua{lxml.pos("#1")}} - -\def\xmltoparameters #1{\ctxlua{lxml.toparameters("#1")}} - -\def\xmltofile #1#2#3{\ctxlua{lxml.tofile("#1","#2","#3")}} % id pattern filename +\def\xmlsetfunction #1#2#3{\ctxlxml{setaction("#1","#2",#3)}} +\def\xmlsetsetup #1#2#3{\ctxlxml{setsetup("#1","#2","#3")}} +\def\xmlstrip #1#2{\ctxlxml{strip("#1","#2")}} +\def\xmlstripnolines #1#2{\ctxlxml{strip("#1","#2",true)}} +\def\xmlstripanywhere #1#2{\ctxlxml{strip("#1","#2",true,true)}} +\def\xmlstripped #1#2{\ctxlxml{stripped("#1","#2")}} +\def\xmlstrippednolines #1#2{\ctxlxml{stripped("#1","#2",true)}} +\def\xmltag #1{\ctxlxml{tag("#1")}} +\def\xmltext #1#2{\ctxlxml{text("#1","#2")}} +\def\xmlverbatim #1{\ctxlxml{verbatim("#1")}} +\def\xmldisplayverbatim #1{\ctxlxml{displayverbatim("#1")}} +\def\xmlinlineverbatim #1{\ctxlxml{inlineverbatim("#1")}} + +\def\xmlload #1#2{\ctxlxml{load("#1","#2","\@@xmentities","\@@xmcompress")}} +\def\xmlloadbuffer #1#2{\ctxlxml{loadbuffer("#1","#2","\@@xmentities","\@@xmcompress")}} +\def\xmlloaddata #1#2{\ctxlxml{loaddata("#1",\!!bs#2\!!es,"\@@xmentities","\@@xmcompress")}} +\def\xmlloadregistered #1#2{\ctxlxml{loadregistered("#1","\@@xmentities","\@@xmcompress")}} +\def\xmlloaddirectives #1{\ctxlxml{directives.load("any:///#1")}} +\def\xmlpos #1{\ctxlxml{pos("#1")}} + +\def\xmltoparameters #1{\ctxlxml{toparameters("#1")}} + +\def\xmltofile #1#2#3{\ctxlxml{tofile("#1","#2","#3")}} % id pattern filename % kind of special: -\def\xmlstartraw{\ctxlua{lxml.startraw()}} -\def\xmlstopraw {\ctxlua{lxml.stopraw()}} +\def\xmlstartraw{\ctxlxml{startraw()}} +\def\xmlstopraw {\ctxlxml{stopraw()}} % todo: \xmldoifelseattribute -\def\xmldoif #1#2{\ctxlua{lxml.doif (\!!bs#1\!!es,\!!bs#2\!!es)}} -\def\xmldoifnot #1#2{\ctxlua{lxml.doifnot (\!!bs#1\!!es,\!!bs#2\!!es)}} -\def\xmldoifelse #1#2{\ctxlua{lxml.doifelse (\!!bs#1\!!es,\!!bs#2\!!es)}} -\def\xmldoiftext #1#2{\ctxlua{lxml.doiftext (\!!bs#1\!!es,\!!bs#2\!!es)}} -\def\xmldoifnottext #1#2{\ctxlua{lxml.doifnottext (\!!bs#1\!!es,\!!bs#2\!!es)}} -\def\xmldoifelsetext #1#2{\ctxlua{lxml.doifelsetext(\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoif #1#2{\ctxlxml{doif (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifnot #1#2{\ctxlxml{doifnot (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifelse #1#2{\ctxlxml{doifelse (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoiftext #1#2{\ctxlxml{doiftext (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifnottext #1#2{\ctxlxml{doifnottext (\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\xmldoifelsetext #1#2{\ctxlxml{doifelsetext(\!!bs#1\!!es,\!!bs#2\!!es)}} -%def\xmldoifelseempty #1#2{\ctxlua{lxml.doifelseempty("#1","#2")}} % #2, "*" or "" == self not yet implemented -%def\xmldoifelseselfempty #1{\ctxlua{lxml.doifelseempty("#1")}} +%def\xmldoifelseempty #1#2{\ctxlxml{doifelseempty("#1","#2")}} % #2, "*" or "" == self not yet implemented +%def\xmldoifelseselfempty #1{\ctxlxml{doifelseempty("#1")}} % \startxmlsetups xml:include % \xmlinclude{main}{include}{filename|href} @@ -130,21 +132,21 @@ % todo: 1:xml:whatever always before 3:xml:something -\def\xmlprependsetup #1{\ctxlua{lxml.installsetup(1,"*","#1")}} -\def\xmlappendsetup #1{\ctxlua{lxml.installsetup(2,"*","#1")}} -\def\xmlbeforesetup #1#2{\ctxlua{lxml.installsetup(3,"*","#1","#2"))}} -\def\xmlaftersetup #1#2{\ctxlua{lxml.installsetup(4,"*","#1","#2"))}} +\def\xmlprependsetup #1{\ctxlxml{installsetup(1,"*","#1")}} +\def\xmlappendsetup #1{\ctxlxml{installsetup(2,"*","#1")}} +\def\xmlbeforesetup #1#2{\ctxlxml{installsetup(3,"*","#1","#2"))}} +\def\xmlaftersetup #1#2{\ctxlxml{installsetup(4,"*","#1","#2"))}} -\def\xmlprependdocumentsetup #1#2{\ctxlua{lxml.installsetup(1,"#1","#2")}} -\def\xmlappenddocumentsetup #1#2{\ctxlua{lxml.installsetup(2,"#1","#2")}} -\def\xmlbeforedocumentsetup#1#2#3{\ctxlua{lxml.installsetup(3,"#1","#2","#3"))}} -\def\xmlafterdocumentsetup #1#2#3{\ctxlua{lxml.installsetup(4,"#1","#2","#3"))}} +\def\xmlprependdocumentsetup #1#2{\ctxlxml{installsetup(1,"#1","#2")}} +\def\xmlappenddocumentsetup #1#2{\ctxlxml{installsetup(2,"#1","#2")}} +\def\xmlbeforedocumentsetup#1#2#3{\ctxlxml{installsetup(3,"#1","#2","#3"))}} +\def\xmlafterdocumentsetup #1#2#3{\ctxlxml{installsetup(4,"#1","#2","#3"))}} -\def\xmlremovesetup #1{\ctxlua{lxml.removesetup("*","#1")}} -\def\xmlremovedocumentsetup #1#2{\ctxlua{lxml.removesetup("#1","#2")}} +\def\xmlremovesetup #1{\ctxlxml{removesetup("*","#1")}} +\def\xmlremovedocumentsetup #1#2{\ctxlxml{removesetup("#1","#2")}} -\def\xmlflushdocumentsetups #1#2{\ctxlua{lxml.flushsetups("#1","*","#2")}} % #1 == id where to apply * and #2 -\def\xmlresetdocumentsetups #1{\ctxlua{lxml.resetsetups("#1")}} +\def\xmlflushdocumentsetups #1#2{\ctxlxml{flushsetups("#1","*","#2")}} % #1 == id where to apply * and #2 +\def\xmlresetdocumentsetups #1{\ctxlxml{resetsetups("#1")}} \let\xmlregistersetup \xmlappendsetup \let\xmlregisterdocumentsetup\xmlappenddocumentsetup @@ -269,7 +271,7 @@ % \def\xmltraceentities % settextcleanup is not defined % {\ctxlua{xml.settextcleanup(lxml.trace_text_entities)}% -% \appendtoks\ctxlua{lxml.showtextentities()}\to\everygoodbye} +% \appendtoks\ctxlxml{showtextentities()}\to\everygoodbye} % processing instructions @@ -299,9 +301,9 @@ {\ifcase\xmlprocessingmode % unset \or - \ctxlua{lxml.setcommandtotext("#1")}% 1 + \ctxlxml{setcommandtotext("#1")}% 1 \or - \ctxlua{lxml.setcommandtonone("#1")}% 2 + \ctxlxml{setcommandtonone("#1")}% 2 \else % unset \fi} @@ -327,9 +329,9 @@ %D Experimental: -\def\xmlgetindex #1{\ctxlua{lxml.getindex("\xmldocument","#1")}} -\def\xmlrawindex #1{\ctxlua{lxml.rawindex("#1")}} -\def\xmlwithindex #1#2{\ctxlua{lxml.withindex("\xmldocument","#1","#2")}} +\def\xmlgetindex #1{\ctxlxml{getindex("\xmldocument","#1")}} +\def\xmlrawindex #1{\ctxlxml{rawindex("#1")}} +\def\xmlwithindex #1#2{\ctxlxml{withindex("\xmldocument","#1","#2")}} \def\xmlreference #1#2{\string\xmlwithindex{#1}{#2}} %D Entities: diff --git a/tex/context/base/lxml-sor.mkiv b/tex/context/base/lxml-sor.mkiv index 14425967b..a3fc83dd1 100644 --- a/tex/context/base/lxml-sor.mkiv +++ b/tex/context/base/lxml-sor.mkiv @@ -19,11 +19,11 @@ \unprotect -\def\xmlresetsorter #1{\ctxlua{lxml.sorters.reset("#1")}} -\def\xmladdsortentry#1#2#3{\ctxlua{lxml.sorters.add("#1","#2",\!!bs#3\!!es)}} -\def\xmlshowsorter #1{\ctxlua{lxml.sorters.show("#1")}} -\def\xmlflushsorter #1#2{\ctxlua{lxml.sorters.flush("#1","#2")}} -\def\xmlsortentries #1{\ctxlua{lxml.sorters.sort("#1")}} +\def\xmlresetsorter #1{\ctxlxml{sorters.reset("#1")}} +\def\xmladdsortentry#1#2#3{\ctxlxml{sorters.add("#1","#2",\!!bs#3\!!es)}} +\def\xmlshowsorter #1{\ctxlxml{sorters.show("#1")}} +\def\xmlflushsorter #1#2{\ctxlxml{sorters.flush("#1","#2")}} +\def\xmlsortentries #1{\ctxlxml{sorters.sort("#1")}} \protect \endinput diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index ffaf9cf18..213ed8a92 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -288,7 +288,7 @@ function lxml.filterlist(list,pattern) end end -lxml["function"] = function(id,name) +function lxml.applyfunction(id,name) local f = xml.functions[name] return f and f(getid(id)) end diff --git a/tex/context/base/m-chart.mkiv b/tex/context/base/m-chart.mkiv index eb20e0457..e55b8aae7 100644 --- a/tex/context/base/m-chart.mkiv +++ b/tex/context/base/m-chart.mkiv @@ -634,16 +634,16 @@ \global\let\FLOWshape\@@FLOSdefault \fi \doifnot\FLOWshape{none} % {\v!none} - {\ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWshapes} + {\doifinsetelse\FLOWshape\FLOWshapes {\edef\FLOWshapetag{shape_ \FLOWshape}% beter \expanded \@EA\setFLOWname\@EA\FLOWshapetag\@EA{\FLOWshapetag}} {\doifnumberelse\FLOWshape {\let\FLOWshapetag\FLOWshape} {\let\FLOWshapetag\empty}}% \ifx\FLOWshapetag\empty \else - \ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWlines} + \doifinsetelse\FLOWshape\FLOWlines {\chardef\FLOWstate0 } - {\ExpandBothAfter\doifcommonelse{\FLOWcell,\FLOWfocus}{\@@FLOWfocus} + {\doifcommonelse{\FLOWcell,\FLOWfocus}\@@FLOWfocus {\chardef\FLOWstate1 } {\chardef\FLOWstate2 }}% \startMPdrawing @@ -989,7 +989,7 @@ \def\doFLOWlocationF#1,#2\end% {\ifnum#1>\@@FLOWabsx\def\@@FLOWabsx{#1}\fi \ifnum#2>\@@FLOWabsy\def\@@FLOWabsy{#2}\fi - \ExpandBothAfter\doifinset{\FLOWcell}{\@@FLOWautofocus} + \doifinset\FLOWcell\@@FLOWautofocus {\dodoFLOWlocationF{#1}<-\@@FLOWminx \dodoFLOWlocationF{#1}>+\@@FLOWmaxx \dodoFLOWlocationF{#2}<-\@@FLOWminy @@ -1902,16 +1902,16 @@ \global\let\FLOWshape\@@FLOSdefault \fi \doifnot\FLOWshape{none} % {\v!none} - {\ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWshapes} + {\doifinsetelse\FLOWshape\FLOWshapes {\edef\FLOWshapetag{shape_\FLOWshape}% beter \expanded \@EA\setFLOWname\@EA\FLOWshapetag\@EA{\FLOWshapetag}} {\doifnumberelse\FLOWshape {\let\FLOWshapetag\FLOWshape} {\let\FLOWshapetag\empty}}% \ifx\FLOWshapetag\empty \else - \ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWlines} + \doifinsetelse\FLOWshape\FLOWlines {\chardef\FLOWstate0 } - {\ExpandBothAfter\doifcommonelse{\FLOWcell,\FLOWfocus}{\@@FLOWfocus} + {\doifcommonelse{\FLOWcell,\FLOWfocus}\@@FLOWfocus {\chardef\FLOWstate1 } {\chardef\FLOWstate2 }}% \startMPdrawing @@ -2257,7 +2257,7 @@ \def\doFLOWlocationF#1,#2\end% {\ifnum#1>\@@FLOWabsx\def\@@FLOWabsx{#1}\fi \ifnum#2>\@@FLOWabsy\def\@@FLOWabsy{#2}\fi - \ExpandBothAfter\doifinset{\FLOWcell}{\@@FLOWautofocus} + \doifinset\FLOWcell\@@FLOWautofocus {\dodoFLOWlocationF{#1}<-\@@FLOWminx \dodoFLOWlocationF{#1}>+\@@FLOWmaxx \dodoFLOWlocationF{#2}<-\@@FLOWminy diff --git a/tex/context/base/meta-fig.mkiv b/tex/context/base/meta-fig.mkiv index 8c8ed03a7..adaad4647 100644 --- a/tex/context/base/meta-fig.mkiv +++ b/tex/context/base/meta-fig.mkiv @@ -46,12 +46,20 @@ \unexpanded\def\setupMPpage {\dodoubleargument\getparameters[\??mg]} +% \def\startMPpage +% {\dodoubleempty\dostartMPpage} +% +% \long\def\dostartMPpage[#1][#2]#3\stopMPpage % second arg gobbles space +% {\dostartfittingpage[\??mg][#1]% +% \processMPgraphic{#3}% +% \dostopfittingpage} + \def\startMPpage - {\dodoubleempty\dostartMPpage} + {\dosingleempty\dostartMPpage} -\long\def\dostartMPpage[#1][#2]#3\stopMPpage % second arg gobbles space +\long\def\dostartMPpage[#1]#2\stopMPpage {\dostartfittingpage[\??mg][#1]% - \processMPgraphic{#3}% + \processMPgraphic{#2}% \dostopfittingpage} \let\stopMPpage \relax % so that we can use it in \expanded diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index 145251d87..60011ff36 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -648,15 +648,6 @@ % \stopnointerference \stopreadingfile} -%D \macros -%D {MPrunfile} -%D -%D This one is more abstract and does not assume knowledge -%D of buffer prefixes. - -\def\MPrunfile#1% - {\bufferprefix mprun.#1} - %D For the moment, the next one is a private macro: \def\processMPbuffer @@ -680,7 +671,7 @@ % we need this trick because tex.sprint does not interprets newlines and the scanner % stops at a newline; also, we do need to flush the buffer under a normal catcode % regime in order to expand embedded tex macros; #1 can be a list - \processMPgraphic{\ctxlua{commands.feedback("\currentMPgraphicname")}}% + \processMPgraphic{\ctxcommand{feedback("\currentMPgraphicname")}}% \endMPgraphicgroup}} \def\runMPbuffer diff --git a/tex/context/base/mtx-context-select.tex b/tex/context/base/mtx-context-select.tex new file mode 100644 index 000000000..8a02bdff7 --- /dev/null +++ b/tex/context/base/mtx-context-select.tex @@ -0,0 +1,109 @@ +% engine=luatex + +%D \module +%D [ file=mtx-context-select, +%D version=2008.11.10, % about that time i started playing with this +%D title=\CONTEXT\ Extra Trickry, +%D subtitle=Listing Files, +%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. + +%D This is a \TEXEXEC\ features that has been moved to \MKIV. + +% begin help +% +% usage: context --extra=select [options] list-of-files +% +% --sort : sort filenames first +% --topspace=dimension : distance above first line +% --backspace=dimension : distance before left margin +% --selection=list : n:m,p:q,... +% --paperformat=spec : paper*print or paperxprint or 'fit' +% --interaction : add hyperlinks +% +% end help + +\input mtx-context-common.tex + +\setuppapersize + [\getdocumentargumentdefault{paperformat_from}{A4}] + [\getdocumentargumentdefault{paperformat_to}{A4}] + +\setuppaper + [offset=\getdocumentargumentdefault{paperformat_to}{0pt}] + +\setuplayout + [width=middle, + height=middle, + topspace=\getdocumentargumentdefault{topspace}{0pt}, + backspace=\getdocumentargumentdefault{backspace}{0pt}, + location=middle, + header=0pt, + footer=0pt] + +\doif {\getdocumentargument{marking}} {yes} { + \setuplayout + [marking=on] +} + +\doif {\getdocumentargument{interaction}} {yes} { + \setupinteraction + [state=start] + \setupexternalfigures + [interaction=yes] +} + +\setupexternalfigures + [directory=] + +\doifelse {\getdocumentargument{paperformat_paper}} {fit} { + \doifdocumentfilename {1} { + \getfiguredimensions + [\getdocumentfilename{1}] + \definepapersize + [fit] + [width=\figurewidth, + height=\figureheight] + \setuppapersize + [fit] + [fit] + } +} + +\starttext + +\startluacode + + local papersize = document.arguments.paperformat_paper or "A4" + local printsize = document.arguments.paperformat_print or "A4" + local selection = document.arguments.selection or "" + local textwidth = document.arguments.textwidth or "0cm" -- needed ? + + if #document.files == 0 then + context("no files given") + elseif selection == "" then + context("no selection given") + else + if document.arguments.sort then + table.sort(document.files) + end + for _, filename in ipairs(document.files) do + if not string.find(filename,"^mtx%-context%-") then + context.filterpages ( + { filename }, + { selection }, + { width = textwidth } + ) + end + end + end + +\stopluacode + +\stoptext + diff --git a/tex/context/base/mult-aux.mkii b/tex/context/base/mult-aux.mkii new file mode 100644 index 000000000..f06833bff --- /dev/null +++ b/tex/context/base/mult-aux.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=mult-aux, +%D version=2010.08.2, +%D title=\CONTEXT\ Multilingual Macros, +%D subtitle=helpers, +%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. + +%D This is a subset of the \MKIV\ variant which has more comments). There +%D is no support for attributes (fonts and color). This code is mostly +%D meant for usage in modules that are backported from \MKIV. + +\writestatus{loading}{ConTeXt Multilingual Macros / Helpers} + +\unprotect + +%D \starttyping +%D \unprotect +%D \def\????aa{@@@@aa} +%D +%D \installparameterhandler \????aa {whatever} +%D \installsetuphandler \????aa {whatever} +%D \installdefinehandler \????aa {whatever} \????aa % #3 == defaultroot +%D +%D % \installcommandhandler \????aa {whatever} \????aa +%D \protect +%D +%D % \whateverparameter \c!test +%D % \whateverparameterhash \c!test +%D % \namedwhateverparameter \mycurrentwhatever \c!test +%D % \everydefinewhatever (sets \currentwhatever) +%D % \everypresetwhatever (can be used to reset parameters as we can redefine) +%D % \everysetupwhatever (sets \currentwhatever) +%D +%D \starttext +%D \definewhatever[first] \definewhatever[second][first] +%D test: \def\currentwhatever{first} \whateverparameter{method} \par +%D \setupwhatever [method=unset] test: \def\currentwhatever{first} \whateverparameter{method} \par +%D \setupwhatever[first] [method=first] test: \def\currentwhatever{first} \whateverparameter{method} \par +%D test: \def\currentwhatever{second} \whateverparameter{method} \par +%D \setupwhatever[second][method=second] test: \def\currentwhatever{second} \whateverparameter{method} \par +%D \stoptext +%D \stoptyping + +\unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7#8#9% + {\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#8{\dosetvalue{#1}}% ##1 {##2} (braces are mandate) + \def#9{\doletvalue{#1}}}% ##1 ##2 + +\unexpanded\def\installparameterhandler#1#2% + {%\message{\detokenize{#1}/\detokenize{#2}}% + \normalexpanded + {\doinstallparameterhandler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname #2parameter\endcsname + \expandafter\noexpand\csname do#2parameter\endcsname + \expandafter\noexpand\csname do#2parentparameter\endcsname + \expandafter\noexpand\csname named#2parameter\endcsname + \expandafter\noexpand\csname detokenized#2parameter\endcsname + \expandafter\noexpand\csname doset#2parameter\endcsname + \expandafter\noexpand\csname dolet#2parameter\endcsname}} + +\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}} + +\unexpanded\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\doinstalldefinehandler#1#2#3#4#5#6#7% + {\unexpanded\def#2{\dotripleempty#5}% + \newtoks#6% + \newtoks#7% + \def#5[##1][##2][##3]% [child][parent][settings] + {\edef#4{##1}% % [child] [settings] + \the#6% predefine % [child][parent] + \ifthirdargument % [child] + \getparameters[#1#4][\s!parent=#1##2,##3]% + \else\ifsecondargument + \doifassignmentelse{##2} + {\getparameters[#1#4][\s!parent=#3,##2]} + {\getparameters[#1#4][\s!parent=#1##2]}% + \else + \getparameters[#1#4][\s!parent=#3]% + \fi\fi + \the#7}} + +\unexpanded\def\installdefinehandler#1#2#3% + {\normalexpanded + {\doinstalldefinehandler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname define#2\endcsname + {\noexpand#3}% root + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname d@define#2\endcsname + \expandafter\noexpand\csname everypreset#2\endcsname + \expandafter\noexpand\csname everydefine#2\endcsname}} + +\unexpanded\def\doinstallsetuphandler#1#2#3#4#5% + {\unexpanded\def#2{\dodoubleempty#4}% + \newtoks#5% + \def#4[##1][##2]% maybe helper + {\ifsecondargument + \def\docommand####1% we will have a simple one as well + {\edef#3{####1}% + \getparameters[#1#3][##2]% + \the#5}% + \processcommalist[##1]\docommand + \else + \let#3\empty + \getparameters[#1][##1]% + \the#5% + \fi}} + +\unexpanded\def\installsetuphandler#1#2% + {\normalexpanded + {\doinstallsetuphandler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname setup#2\endcsname + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname d@setup#2\endcsname + \expandafter\noexpand\csname everysetup#2\endcsname}} + +\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}} + +\unexpanded\def\installnamespace#1% + {\setvalue{????#1}{@@@@#1}} + +\protect + diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua deleted file mode 100644 index 08446a7ca..000000000 --- a/tex/context/base/mult-cld.lua +++ /dev/null @@ -1,753 +0,0 @@ -if not modules then modules = { } end modules ['mult-cld'] = { - version = 1.001, - comment = "companion to mult-cld.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- This is an experiment: generating context code at the lua end. After all --- it is surprisingly simple to implement due to metatables. I was wondering --- if there was a more natural way to deal with commands at the lua end. --- Of course it's a bit slower but often more readable when mixed with lua --- code. It can also be handy when generating documents from databases or --- when constructing large tables or so. --- --- Todo: optional checking against interface --- Todo: coroutine trickery --- Todo: maybe use txtcatcodes - --- tflush needs checking ... sort of weird that it's not a table - --- __flushlines is an experiment and rather ugly so it will go away - -context = context or { } -local context = context - -local format, find, gmatch, splitlines = string.format, string.find, string.gmatch, string.splitlines -local next, type, tostring, setmetatable = next, type, tostring, setmetatable -local insert, remove, concat = table.insert, table.remove, table.concat -local lpegmatch = lpeg.match - -local tex = tex - -local texsprint = tex.sprint -local textprint = tex.tprint -local texprint = tex.print -local texiowrite = texio.write -local texcount = tex.count - -local isnode = node.is_node -- after 0.65 just node.type -local writenode = node.write -local copynodelist = node.copylist - -local ctxcatcodes = tex.ctxcatcodes -local prtcatcodes = tex.prtcatcodes -local texcatcodes = tex.texcatcodes -local txtcatcodes = tex.txtcatcodes -local vrbcatcodes = tex.vrbcatcodes -local xmlcatcodes = tex.xmlcatcodes - -local flush = texsprint - -local report_context = logs.new("context") -- here -local report_cld = logs.new("cld") - -local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end) - --- for tracing it's easier to have two stacks - -local _stack_f_, _n_f_ = { }, 0 -local _stack_n_, _n_n_ = { }, 0 - -local function _store_f_(ti) - _n_f_ = _n_f_ + 1 - _stack_f_[_n_f_] = ti - return _n_f_ -end - -local function _store_n_(ti) - _n_n_ = _n_n_ + 1 - _stack_n_[_n_n_] = ti - return _n_n_ -end - -local function _flush_f_(n) - local sn = _stack_f_[n] - if not sn then - report_cld("data with id %s cannot be found on stack",n) - else - local tn = type(sn) - if tn == "function" then - if not sn() and texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! - _stack_f_[n] = nil - else - -- keep, beware, that way the stack can grow - end - else - if texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! - writenode(sn) - _stack_f_[n] = nil - else - writenode(copynodelist(sn)) - -- keep, beware, that way the stack can grow - end - end - end -end - -local function _flush_n_(n) - local sn = _stack_n_[n] - if not sn then - report_cld("data with id %s cannot be found on stack",n) - elseif texcount["@@trialtypesetting"] == 0 then -- @@trialtypesetting is private! - writenode(sn) - _stack_n_[n] = nil - else - writenode(copynodelist(sn)) - -- keep, beware, that way the stack can grow - end -end - -function context.restart() - _stack_f_, _n_f_ = { }, 0 - _stack_n_, _n_n_ = { }, 0 -end - -context._stack_f_ = _stack_f_ -context._store_f_ = _store_f_ -context._flush_f_ = _flush_f_ cldff = _flush_f_ - -context._stack_n_ = _stack_n_ -context._store_n_ = _store_n_ -context._flush_n_ = _flush_n_ cldfn = _flush_n_ - --- Should we keep the catcodes with the function? - -local catcodestack = { } -local currentcatcodes = ctxcatcodes -local contentcatcodes = ctxcatcodes - -local catcodes = { - ctx = ctxcatcodes, ctxcatcodes = ctxcatcodes, context = ctxcatcodes, - prt = prtcatcodes, prtcatcodes = prtcatcodes, protect = prtcatcodes, - tex = texcatcodes, texcatcodes = texcatcodes, plain = texcatcodes, - txt = txtcatcodes, txtcatcodes = txtcatcodes, text = txtcatcodes, - vrb = vrbcatcodes, vrbcatcodes = vrbcatcodes, verbatim = vrbcatcodes, - xml = xmlcatcodes, xmlcatcodes = xmlcatcodes, -} - -function context.pushcatcodes(c) - insert(catcodestack,currentcatcodes) - currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes - contentcatcodes = currentcatcodes -end - -function context.popcatcodes() - currentcatcodes = remove(catcodestack) or currentcatcodes - contentcatcodes = currentcatcodes -end - -function tex.fprint(...) -- goodie - texsprint(currentcatcodes,format(...)) -end - --- -- -- todo: tracing - -local newline = lpeg.patterns.newline -local space = lpeg.patterns.spacer -local spacing = newline * space^0 -local content = lpeg.C((1-spacing)^1) -local emptyline = space^0 * newline^2 -local endofline = space^0 * newline * space^0 -local simpleline = endofline * lpeg.P(-1) - -local function n_content(s) - flush(contentcatcodes,s) -end - -local function n_endofline() - texsprint(" \r") -end - -local function n_emptyline() - texprint("\r") -end - -local function n_simpleline() - texprint("\r") -end - -function lpeg.texlinesplitter(f_content,f_endofline,f_emptyline,f_simpleline) - local splitlines = - simpleline / (f_simpleline or n_simpleline) - + ( - emptyline / (f_emptyline or n_emptyline) - + endofline / (f_endofline or n_emptyline) - + content / (f_content or n_content) - )^0 - return function(str) return lpegmatch(splitlines,str) end -end - -local flushlines = lpeg.texlinesplitter(n_content,n_endofline,n_emptyline,n_simpleline) - -context.__flushlines = flushlines -- maybe context.helpers.flushtexlines -context.__flush = flush - -local printlines_ctx = ( - (newline) / function() texprint("") end + - (1-newline)^1 / function(s) texprint(ctxcatcodes,s) end * newline^-1 -)^0 - -local printlines_raw = ( - (newline) / function() texprint("") end + - (1-newline)^1 / function(s) texprint(s) end * newline^-1 -)^0 - -function context.printlines(str,raw) - if raw then - lpegmatch(printlines_raw,str) - else - lpegmatch(printlines_ctx,str) - end -end - --- -- -- - -local methodhandler = resolvers.methodhandler - -function context.viafile(data) - -- this is the only way to deal with nested buffers - -- and other catcode sensitive data - local filename = resolvers.savers.byscheme("virtual","viafile",data) - context.input(filename) -end - --- -- -- - -local function writer(parent,command,first,...) - local t = { first, ... } - flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes - local direct = false - for i=1,#t do - local ti = t[i] - local typ = type(ti) - if direct then - if typ == "string" or typ == "number" then - flush(currentcatcodes,ti) - else -- node.write - report_context("error: invalid use of direct in '%s', only strings and numbers can be flushed directly, not '%s'",command,typ) - end - direct = false - elseif ti == nil then - -- nothing - elseif ti == "" then - flush(currentcatcodes,"{}") - elseif typ == "string" then - if processlines and find(ti,"[\n\r]") then -- we can check for ti == "\n" - flush(currentcatcodes,"{") - local flushlines = parent.__flushlines or flushlines - flushlines(ti) - flush(currentcatcodes,"}") - elseif currentcatcodes == contentcatcodes then - flush(currentcatcodes,"{",ti,"}") - else - flush(currentcatcodes,"{") - flush(contentcatcodes,ti) - flush(currentcatcodes,"}") - end - elseif typ == "number" then - -- numbers never have funny catcodes - flush(currentcatcodes,"{",ti,"}") - elseif typ == "table" then - local tn = #ti - if tn == 0 then - local done = false - for k, v in next, ti do - if done then - if v == "" then - flush(currentcatcodes,",",k,'=') - else - flush(currentcatcodes,",",k,'=',v) - end - else - if v == "" then - flush(currentcatcodes,"[",k,'=') - else - flush(currentcatcodes,"[",k,'=',v) - end - done = true - end - end - flush(currentcatcodes,"]") - elseif tn == 1 then -- some 20% faster than the next loop - local tj = ti[1] - if type(tj) == "function" then - flush(currentcatcodes,"[\\cldff{",_store_f_(tj),"}]") - else - flush(currentcatcodes,"[",tj,"]") - end - else -- is concat really faster than flushes here? probably needed anyway (print artifacts) - for j=1,tn do - local tj = ti[j] - if type(tj) == "function" then - ti[j] = "\\cldff{" .. _store_f_(tj) .. "}" - end - end - flush(currentcatcodes,"[",concat(ti,","),"]") - end - elseif typ == "function" then - flush(currentcatcodes,"{\\cldff{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if ti then - -- flush(currentcatcodes,"^^M") - texprint("") - else - direct = true - end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(ti) then -- slow - flush(currentcatcodes,"{\\cldfn{",_store_n_(ti),"}}") - else - report_context("error: '%s' gets a weird argument '%s'",command,tostring(ti)) - end - end -end - -local generics = { } context.generics = generics - -local function indexer(parent,k) - local c = "\\" .. tostring(generics[k] or k) - local f = function(first,...) - if first == nil then - flush(currentcatcodes,c) - else - return writer(parent,c,first,...) - end - end - parent[k] = f - return f -end - -local function caller(parent,f,a,...) - if not parent then - -- so we don't need to test in the calling (slower but often no issue) (will go) - elseif f ~= nil then - local typ = type(f) - if typ == "string" then - if a then - flush(contentcatcodes,format(f,a,...)) -- was currentcatcodes - elseif processlines and find(f,"[\n\r]") then - local flushlines = parent.__flushlines or flushlines - flushlines(f) - else - flush(contentcatcodes,f) - end - elseif typ == "number" then - if a then - flush(currentcatcodes,f,a,...) - else - flush(currentcatcodes,f) - end - elseif typ == "function" then - -- ignored: a ... - flush(currentcatcodes,"{\\cldff{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if f then - if a ~= nil then - local flushlines = parent.__flushlines or flushlines - flushlines(f) - -- ignore ... maybe some day - else - -- flush(currentcatcodes,"^^M") - texprint("") - end - else - if a ~= nil then - -- no command, same as context(a,...) - writer(parent,"",a,...) - else - -- ignored - end - end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(f) then -- slow - -- writenode(f) - flush(currentcatcodes,"\\cldfn{",_store_n_(f),"}") - else - report_context("error: 'context' gets a weird argument '%s'",tostring(f)) - end - end -end - -local defaultcaller = caller - -setmetatable(context, { __index = indexer, __call = caller } ) - --- now we tweak unprotect and protect - -function context.unprotect() - -- at the lua end - insert(catcodestack,currentcatcodes) - currentcatcodes = prtcatcodes - contentcatcodes = currentcatcodes - -- at the tex end - flush("\\unprotect") -end - -function context.protect() - -- at the tex end - flush("\\protect") - -- at the lua end - currentcatcodes = remove(catcodestack) or currentcatcodes - contentcatcodes = currentcatcodes -end - --- logging - -local trace_stack = { } - -local normalflush = flush -local normalwriter = writer -local currenttrace = nil -local nofwriters = 0 -local nofflushes = 0 - -statistics.register("traced context", function() - if nofwriters > 0 or nofflushes > 0 then - return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,_n_f_) - end -end) - -local tracedwriter = function(parent,...) - nofwriters = nofwriters + 1 - local t, f, n = { "w : " }, flush, 0 - flush = function(...) - n = n + 1 - t[n] = concat({...},"",2) - normalflush(...) - end - normalwriter(parent,...) - flush = f - currenttrace(concat(t)) -end - -local tracedflush = function(...) - nofflushes = nofflushes + 1 - normalflush(...) - local t = { ... } - t[1] = "f : " -- replaces the catcode - for i=2,#t do - local ti = t[i] - local tt = type(ti) - if tt == "string" then - -- ok - elseif tt == "number" then - -- ok - else - t[i] = format("<%s>",tostring(ti)) - end - -- currenttrace(format("%02i: %s",i-1,tostring(t[i]))) - end - currenttrace(concat(t)) -end - -local function pushlogger(trace) - insert(trace_stack,currenttrace) - currenttrace = trace - flush, writer = tracedflush, tracedwriter - context.__flush = flush -end - -local function poplogger() - currenttrace = remove(trace_stack) - if not currenttrace then - flush, writer = normalflush, normalwriter - context.__flush = flush - end -end - -local function settracing(v) - if v then - pushlogger(report_context) - else - poplogger() - end -end - --- todo: share flushers so that we can define in other files - -trackers.register("context.trace",settracing) - -context.pushlogger = pushlogger -context.poplogger = poplogger -context.settracing = settracing - -local trace_cld = false trackers.register("context.files", function(v) trace_cld = v end) - -function context.runfile(filename) - local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or "" - if foundname ~= "" then - local ok = dofile(foundname) - if type(ok) == "function" then - if trace_cld then - report_context("begin of file '%s' (function call)",foundname) - end - ok() - if trace_cld then - report_context("end of file '%s' (function call)",foundname) - end - elseif ok then - report_context("file '%s' is processed and returns true",foundname) - else - report_context("file '%s' is processed and returns nothing",foundname) - end - else - report_context("unknown file '%s'",filename) - end -end - --- some functions - -function context.direct(first,...) - if first ~= nil then - return writer(context,"",first,...) - end -end - --- context.delayed (todo: lines) - -local delayed = { } context.delayed = delayed -- maybe also store them - -local function indexer(parent,k) - local f = function(...) - local a = { ... } - return function() - return context[k](unpack(a)) - end - end - parent[k] = f - return f -end - -local function caller(parent,...) -- todo: nodes - local a = { ... } - return function() - return context(unpack(a)) - end -end - -setmetatable(delayed, { __index = indexer, __call = caller } ) - --- context.nested (todo: lines) - -local nested = { } context.nested = nested - -local function indexer(parent,k) - local f = function(...) - local t, savedflush, n = { }, flush, 0 - flush = function(c,f,s,...) -- catcodes are ignored - n = n + 1 - t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 - end - context[k](...) - flush = savedflush - return concat(t) - end - parent[k] = f - return f -end - -local function caller(parent,...) - local t, savedflush, n = { }, flush, 0 - flush = function(c,f,s,...) -- catcodes are ignored - n = n + 1 - t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 - end - context(...) - flush = savedflush - return concat(t) -end - -setmetatable(nested, { __index = indexer, __call = caller } ) - --- verbatim - -local verbatim = { } context.verbatim = verbatim - -local function indexer(parent,k) - local command = context[k] - local f = function(...) - local savedcatcodes = contentcatcodes - contentcatcodes = vrbcatcodes - command(...) - contentcatcodes = savedcatcodes - end - parent[k] = f - return f -end - -local function caller(parent,...) - local savedcatcodes = contentcatcodes - contentcatcodes = vrbcatcodes - defaultcaller(parent,...) - contentcatcodes = savedcatcodes -end - -setmetatable(verbatim, { __index = indexer, __call = caller } ) - --- metafun - -local metafun = { } context.metafun = metafun - -local mpdrawing = "\\MPdrawing" - -local function caller(parent,f,a,...) - if not parent then - -- skip - elseif f then - local typ = type(f) - if typ == "string" then - if a then - flush(currentcatcodes,mpdrawing,"{",format(f,a,...),"}") - else - flush(currentcatcodes,mpdrawing,"{",f,"}") - end - elseif typ == "number" then - if a then - flush(currentcatcodes,mpdrawing,"{",f,a,...,"}") - else - flush(currentcatcodes,mpdrawing,"{",f,"}") - end - elseif typ == "function" then - -- ignored: a ... - flush(currentcatcodes,mpdrawing,"{\\cldff{",store_(f),"}}") - elseif typ == "boolean" then - -- ignored: a ... - if f then - flush(currentcatcodes,mpdrawing,"{^^M}") - else - report_context("warning: 'metafun' gets argument 'false' which is currently unsupported") - end - else - report_context("error: 'metafun' gets a weird argument '%s'",tostring(f)) - end - end -end - -setmetatable(metafun, { __call = caller } ) - -function metafun.start() - context.resetMPdrawing() -end - -function metafun.stop() - context.MPdrawingdonetrue() - context.getMPdrawing() -end - -function metafun.color(name) - return format([[\MPcolor{%s}]],name) -end - --- metafun.delayed - -local delayed = { } metafun.delayed = delayed - -local function indexer(parent,k) - local f = function(...) - local a = { ... } - return function() - return metafun[k](unpack(a)) - end - end - parent[k] = f - return f -end - - -local function caller(parent,...) - local a = { ... } - return function() - return metafun(unpack(a)) - end -end - -setmetatable(delayed, { __index = indexer, __call = caller } ) - ---~ Not that useful yet. Maybe something like this when the main loop ---~ is a coroutine. It also does not help taking care of nested calls. ---~ Even worse, it interferes with other mechanisms using context calls. ---~ ---~ local create, yield, resume = coroutine.create, coroutine.yield, coroutine.resume ---~ local getflush, setflush = context.getflush, context.setflush ---~ local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes ---~ ---~ function context.getflush() ---~ return flush ---~ end ---~ ---~ function context.setflush(newflush) ---~ local oldflush = flush ---~ flush = newflush or flush ---~ return oldflush ---~ end ---~ ---~ function context.direct(f) ---~ local routine = create(f) ---~ local oldflush = getflush() ---~ function newflush(...) ---~ oldflush(...) ---~ yield(true) ---~ end ---~ setflush(newflush) ---~ ---~ -- local function resumecontext() ---~ -- local done = resume(routine) ---~ -- if not done then ---~ -- return ---~ -- end ---~ -- resumecontext() -- stack overflow ... no tail recursion ---~ -- end ---~ -- context.resume = resumecontext ---~ -- texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") ---~ ---~ local function resumecontext() ---~ local done = resume(routine) ---~ if not done then ---~ return ---~ end ---~ -- texsprint(ctxcatcodes,"\\exitloop") ---~ texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") -- can be simple macro call ---~ end ---~ context.resume = resumecontext ---~ -- texsprint(ctxcatcodes,"\\doloop{\\ctxlua{context.resume()}}") -- can be fast loop at the tex end ---~ texsprint(ctxcatcodes,"\\ctxlua{context.resume()}") ---~ ---~ end ---~ ---~ function something() ---~ context("\\setbox0") ---~ context("\\hbox{hans hagen xx}") ---~ context("\\the\\wd0/\\box0") ---~ end ---~ ---~ context.direct(something) - --- helpers: - -function context.concat(t,separator) - local done = false - for i=1,#t do - local ti = t[i] - if ti ~= "" then - if done then - context(separator) - end - context(ti) - done = true - end - end -end diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index c715fb1ad..14eeeb4c6 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -39,9 +39,9 @@ local complete = { } interfaces.complete = complete setmetatable(complete, { __index = function(t,k) report_interfaces("loading interface definitions from 'mult-def.lua'") - complete = dofile(resolvers.find_file("mult-def.lua")) + complete = dofile(resolvers.findfile("mult-def.lua")) report_interfaces("loading interface messages from 'mult-mes.lua'") - complete.messages = dofile(resolvers.find_file("mult-mes.lua")) + complete.messages = dofile(resolvers.findfile("mult-mes.lua")) interfaces.complete = complete return complete[k] end } ) diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua index 991e08d93..e90449366 100644 --- a/tex/context/base/node-rul.lua +++ b/tex/context/base/node-rul.lua @@ -43,7 +43,12 @@ function nodes.striprange(first,last) -- todo: dir if id == glyph_code or id == disc_code then -- or id == rule_code break else +local prev = last.prev -- luatex < 0.70 has italic correction kern not prev'd +if prev then last = last.prev +else + break +end end end if not last then diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index d3b71b2b2..22d11fc5b 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -517,8 +517,6 @@ end --~ return table.concat(table.reversed(t)," ") --~ end - - local function showsimplelist(h,depth,n) while h do write_nl(rep(" ",n) .. tostring(h)) diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv index 1338148ac..b3e73c488 100644 --- a/tex/context/base/pack-rul.mkiv +++ b/tex/context/base/pack-rul.mkiv @@ -1842,7 +1842,7 @@ \let\framedboxheight\!!zeropoint \let\framedboxdepth \!!zeropoint -\def\doreshapeframedbox{\ifvbox\framebox\ctxlua{commands.doreshapeframedbox(\number\framebox)}\fi} +\def\doreshapeframedbox{\ifvbox\framebox\ctxcommand{doreshapeframedbox(\number\framebox)}\fi} %D The two variables \type {\framednoflines} and \type %D {\framedlastlength} can be used in a second pass to diff --git a/tex/context/base/page-app.mkiv b/tex/context/base/page-app.mkiv index 9fade501b..afd0c7d5d 100644 --- a/tex/context/base/page-app.mkiv +++ b/tex/context/base/page-app.mkiv @@ -129,7 +129,7 @@ \unexpanded\def\startTEXstream {\dosingleempty\dostartTEXstream} -\def\dostartTEXstream[#1]% +\def\dostartTEXstream[#1]% old code, to be redone {\page \defineoutputstream[tex]% \enableoutputstream[tex]% @@ -139,61 +139,18 @@ \outputstreamunvbox[tex]% \stopTEXpage}} -%D Application pages (for an example, see \type {m-pstric}): +%D Application pages, a quick \MKIV\ hack: -\def\@@texapp{texapp} -\def\@@texdim{texdim} +\definetypesetting[TEXapplication] +\definebuffer[TEXapplication] -\def\saveTEXapplication#1#2% - {\immediate\openout\scratchwrite=\bufferprefix\@@texdim.tmp - \immediate\write\scratchwrite{\dimen#1=\the\ht\scratchbox}% - \immediate\write\scratchwrite{\dimen#2=\the\wd\scratchbox}% - \immediate\closeout\scratchwrite} +% we could use a counter and saves runs on numbering them. -\def\restoreTEXapplication - {\readlocfile{\bufferprefix\@@texdim.tmp}\donothing\donothing} +\def\TEXapplicationfilename{\jobname-texapplication.tex} -\def\startTEXapplication - {\dosingleempty\dostartTEXapplication} - -\long\def\dostartTEXapplication[#1]#2#3\stopTEXapplication - {\bgroup - \bgroup - \let\f!temporaryextension\c!tex - \setbuffer[\@@texapp]% - \starttext - #2% preamble - \startTEXpage[#1]% - \topskip\zeropoint - \setbox\scratchbox\hbox{#3}% - \saveTEXapplication02% dimensions - \box\scratchbox - \stopTEXpage - \stoptext - \endbuffer - \egroup - \doifelse\jobsuffix{dvi}\donetrue\donefalse - \executesystemcommand{texexec \bufferprefix\@@texapp.tex --once --batch}% - \ifdone % eps - \executesystemcommand{dvips -E* -o \@@texapp.eps \@@texapp}% - \else % pdf - \executesystemcommand{dvips \bufferprefix\@@texapp}% - \executesystemcommand{ps2pdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% -% \executesystemcommand{texmfstart pstopdf \bufferprefix\@@texapp.ps \bufferprefix\@@texapp.pdf}% - \fi - \restoreTEXapplication % dimensions - \doifelse\jobsuffix{dvi}\donetrue\donefalse - \setbox\scratchbox\hbox - {\expanded{\externalfigure - [\bufferprefix\@@texapp.\ifdone eps\else pdf\fi] - [\c!object=\v!no]}}% - \setbox\scratchbox\hbox - {\lower\ht\scratchbox\hbox{\raise\dimen2\box\scratchbox}}% - \wd\scratchbox\dimen0 - \ht\scratchbox\dimen2 - \dp\scratchbox\zeropoint - \box\scratchbox - \egroup} +\def\stopTEXapplication + {\savebuffer[\thedefinedbuffer{TEXapplication}][\TEXapplicationfilename]% + \typesetfile[TEXapplication][\TEXapplicationfilename]\relax} %D \macros %D {startpagefigure} diff --git a/tex/context/base/page-flt.mkiv b/tex/context/base/page-flt.mkiv index 450e7ae0e..6d2389176 100644 --- a/tex/context/base/page-flt.mkiv +++ b/tex/context/base/page-flt.mkiv @@ -99,7 +99,7 @@ {\ctxlua{floats.consult("#1")}} \def\doifsavedfloatelse#1% - {\ctxlua{commands.doifsavedfloatelse("#1")}} + {\ctxcommand{doifsavedfloatelse("#1")}} \def\dofloatscollect#1#2#3% {\ctxlua{floats.collect("#1",\number\dimexpr#2,\number\dimexpr#3)}} diff --git a/tex/context/base/page-mak.mkiv b/tex/context/base/page-mak.mkiv index 4544f04e0..ea285bcb8 100644 --- a/tex/context/base/page-mak.mkiv +++ b/tex/context/base/page-mak.mkiv @@ -116,7 +116,7 @@ \def\dodostartmakeup {\doifvaluesomething{\??do\currentmakeup\c!page} - {\ExpandFirstAfter\page[\makeupparameter\c!page]}% + {\page[\makeupparameter\c!page]}% \pagetype[\currentmakeup]% \setsystemmode\v!makeup \setupmakeuplayout diff --git a/tex/context/base/page-run.mkiv b/tex/context/base/page-run.mkiv index cde0a2231..4e92efa27 100644 --- a/tex/context/base/page-run.mkiv +++ b/tex/context/base/page-run.mkiv @@ -195,7 +195,7 @@ end {\dodoubleempty\doshowframe} \gdef\showsetups - {\ctxlua{commands.showlayoutvariables()}} + {\ctxcommand{showlayoutvariables()}} \gdef\showlayout % interfereert lelijk met een \typefile er na {\bgroup diff --git a/tex/context/base/scrn-int.mkiv b/tex/context/base/scrn-int.mkiv index f819789e9..cc25f48b2 100644 --- a/tex/context/base/scrn-int.mkiv +++ b/tex/context/base/scrn-int.mkiv @@ -269,9 +269,9 @@ {\startoverlay{\box\commentcollection}{\box\scratchbox}\stopoverlay}}% \endgroup} -\setvalue{\e!start\v!comment}{\dotripleempty\dostartcomment}% the dummy triple gobbles trailing spaces +\setvalue{\e!start\v!comment}{\dodoubleempty\dostartcomment} -\def\dostartcomment[#1][#2][#3]% +\def\dostartcomment[#1][#2]% {\bgroup \doifassignmentelse{#1}{\getparameters[\??cc][#1]}{\getparameters[\??cc][\c!title=#1,#2]}% \dostartbuffer[\v!comment\v!buffer][\v!comment\v!buffer][\e!start\v!comment][\e!stop\v!comment]} @@ -489,7 +489,7 @@ \def\checksoundtrack#1% yet untested in mkiv (also move management to lua) {\iflocation - \ctxlua{nodeinjections.insertsound{ + \ctxlua{backends.nodeinjections.insertsound{ label = "#1", repeat = "\@@sdoption", % not entirely ok but works }}% diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv index 70d949e76..ce9c80d17 100644 --- a/tex/context/base/spac-hor.mkiv +++ b/tex/context/base/spac-hor.mkiv @@ -917,7 +917,7 @@ {\futurelet\nexttoken\doautoinsertnextspace} \def\doautoinsertnextspace - {\ctxlua{commands.autonextspace("\meaning\nexttoken")}} % todo, just consult nexttoken at the lua end + {\ctxcommand{autonextspace("\meaning\nexttoken")}} % todo, just consult nexttoken at the lua end %D Moved from bib module: diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 56bc18218..852dac1b2 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index 1b8dfeb6f..7e95fb563 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -501,10 +501,10 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio if ownnumber ~= "" then result[#result+1] = ownnumber elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups) .. inherited! - result[#result+1] = converters.convert(conversion,number,true) + result[#result+1] = converters.convert(conversion,number) else local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers") - result[#result+1] = converters.convert(theconversion,number,true) + result[#result+1] = converters.convert(theconversion,number) end else if ownnumber ~= "" then diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv index 7e20d25ec..eb876452c 100644 --- a/tex/context/base/strc-lst.mkiv +++ b/tex/context/base/strc-lst.mkiv @@ -177,7 +177,7 @@ }}} \def\firststructureelementinlist#1% - {\ctxlua{commands.firstinlist("#1")}} + {\ctxcommand{firstinlist("#1")}} \def\structurelistsize {\ctxlua{structures.lists.size()}} diff --git a/tex/context/base/strc-mar.mkiv b/tex/context/base/strc-mar.mkiv index abec8d201..2fe8631b2 100644 --- a/tex/context/base/strc-mar.mkiv +++ b/tex/context/base/strc-mar.mkiv @@ -85,31 +85,31 @@ \def\dodefinemarking[#1][#2]% marking parent {\doifelsenothing{#2} - {\ctxlua{commands.definemarking("#1")}% + {\ctxcommand{definemarking("#1")}% \getparameters[\??mk#1][\s!parent=\??mk]} - {\ctxlua{commands.definemarking("#1",{ parent = "#2" })}% + {\ctxcommand{definemarking("#1",{ parent = "#2" })}% \getparameters[\??mk#1][\s!parent=\??mk#2]}} \def\dorelatemarking[#1][#2]% - {\ctxlua{commands.relatemarking("#1","#2")}} + {\ctxcommand{relatemarking("#1","#2")}} \def\dosetmarking[#1]#2% {\ifconditional\inhibitsetmarking % nothing \else \doifelse{\namedmarkingparameter{#1}\c!expansion}\v!yes - {\ctxlua{commands.setmarking("#1",\!!bs#2\!!es)}} - {\ctxlua{commands.setmarking("#1",\!!bs\detokenize{#2}\!!es)}}% + {\ctxcommand{setmarking("#1",\!!bs#2\!!es)}} + {\ctxcommand{setmarking("#1",\!!bs\detokenize{#2}\!!es)}}% \fi} \def\doresetmarking[#1]% - {\ctxlua{commands.resetmarking("#1")}} + {\ctxcommand{resetmarking("#1")}} \def\doifelsemarking#1% - {\ctxlua{commands.doifelsemarking("#1")}} + {\ctxcommand{doifelsemarking("#1")}} \def\dosynchronizemarking[#1][#2]% class boxnumber (some day also name), maybe second argument table - {\ifvoid#2\else\ctxlua{commands.synchronizemarking("#1",\number#2)}\fi} + {\ifvoid#2\else\ctxcommand{synchronizemarking("#1",\number#2)}\fi} % \appendtoks % \dosynchronizemarking[\v!page][\normalpagebox]% @@ -141,25 +141,25 @@ \setsystemmode\v!marking \the\everymarking \ifthirdargument - \ctxlua{commands.getmarking("#1","#2","#3")}% + \ctxcommand{getmarking("#1","#2","#3")}% \else - \ctxlua{commands.getmarking("#1","\v!page","#2")}% + \ctxcommand{getmarking("#1","\v!page","#2")}% \fi \endgroup}} % the fetchers are fully expandable: [name][method] -\def\fetchonemark[#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchonemark ("#1","\v!page","#2")}\fi} -\def\fetchtwomarks [#1]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchtwomarks("#1","\v!page")}\fi} -\def\fetchallmarks [#1]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchallmarks("#1","\v!page")}\fi} +\def\fetchonemark[#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchonemark ("#1","\v!page","#2")}\fi} +\def\fetchtwomarks [#1]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchtwomarks("#1","\v!page")}\fi} +\def\fetchallmarks [#1]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchallmarks("#1","\v!page")}\fi} \let\fetchmark\fetchonemark % also fully expandable but here we have: [name][range][method] -\def\fetchonemarking[#1]#2[#3]#4[#5]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchonemark ("#1","#3","#5")}\fi} -\def\fetchtwomarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchtwomarks("#1","#3")}\fi} -\def\fetchallmarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxlua{commands.fetchallmarks("#1","#3")}\fi} +\def\fetchonemarking[#1]#2[#3]#4[#5]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchonemark ("#1","#3","#5")}\fi} +\def\fetchtwomarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchtwomarks("#1","#3")}\fi} +\def\fetchallmarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchallmarks("#1","#3")}\fi} \let\fetchmarking\fetchonemarking diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index dddc771c9..c5f6f632c 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -675,39 +675,14 @@ \unexpanded\def\placeformula {\global\settrue\insideplaceformula \settrue\incrementformulanumber - \dodoubleempty\doplaceformula} + \dosingleempty\doplaceformula} \unexpanded\def\placesubformula {\global\settrue\insideplacesubformula \setfalse\incrementformulanumber - \dodoubleempty\doplaceformula} + \dosingleempty\doplaceformula} -% \def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces -% {\def\currentplaceformulareference{#1}% -% \let\currentplaceformulasuffix\empty -% \futurelet\next\redoplaceformulaone} -% -% \let\mathdollarsign$ % no def -% -% \def\redoplaceformulaone % use doifnextcharelse -% {\ifx\next\bgroup -% \@EA\moreplaceformula % [ref]{} -% \else -% \@EA\redoplaceformulatwo -% \fi} -% -% \long\def\moreplaceformula#1#2% #1 dummy #1 gobbles spaces -% {\def\currentplaceformulasuffix{#1}% -% \futurelet\next\redoplaceformulatwo#2} -% -% \def\redoplaceformulatwo -% {\ifx\next\mathdollarsign -% \@EA\dispplaceformula % [ref]$$ -% \else -% \@EA\dodoplaceformula % [ref]\start -% \fi}% - -\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces +\def\doplaceformula[#1]% {\def\currentplaceformulareference{#1}% \let\currentplaceformulasuffix\empty \doifnextbgroupelse\moreplaceformula\redoplaceformula} % [ref]{} diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv index 6f445fabd..a9a19515c 100644 --- a/tex/context/base/strc-ref.mkiv +++ b/tex/context/base/strc-ref.mkiv @@ -1327,8 +1327,8 @@ \def\dousefile[#1][#2][#3]% {\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")}} +\def\doifurldefinedelse #1{\ctxcommand{doifurldefinedelse ("#1")}} +\def\doiffiledefinedelse#1{\ctxcommand{doiffiledefinedelse("#1")}} %D \macros %D {url,setupurl} diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv index 3431e76e0..ea551625b 100644 --- a/tex/context/base/strc-syn.mkiv +++ b/tex/context/base/strc-syn.mkiv @@ -359,7 +359,7 @@ \endgroup} \def\completelistofsorts - {\dodoubleemptydocompletelistofsorts} + {\dodoubleempty\docompletelistofsorts} \def\docompletelistofsorts[#1][#2]% {\normalexpanded{\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}% diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv index 541dec15e..addff193b 100644 --- a/tex/context/base/strc-tag.mkiv +++ b/tex/context/base/strc-tag.mkiv @@ -211,6 +211,6 @@ % \doifinelementelse{division:*-structure:chapter} {yes} {no} \def\doifinelementelse#1% - {\ctxlua{commands.testcase(structures.atlocation("#1"))}} + {\ctxcommand{testcase(structures.atlocation("#1"))}} \protect diff --git a/tex/context/base/supp-ali.mkiv b/tex/context/base/supp-ali.mkiv index cfaeb213e..1bd31eb78 100644 --- a/tex/context/base/supp-ali.mkiv +++ b/tex/context/base/supp-ali.mkiv @@ -146,7 +146,7 @@ % provide a means to use multiple alignments mixed \def\pushcharacteralign - {\ifundefined{@cac@\alignmentclass}% + {\ifcsname @cac@\alignmentclass\endcsname\else \doglobal\appendetoks\noexpand\do{\alignmentclass}\to\@@characteralignlst \fi \setxvalue{@cac@\alignmentclass}{\noexpand\do diff --git a/tex/context/base/supp-box.mkiv b/tex/context/base/supp-box.mkiv index 2860c7556..f449e1d76 100644 --- a/tex/context/base/supp-box.mkiv +++ b/tex/context/base/supp-box.mkiv @@ -967,7 +967,7 @@ %D \stoptyping \def\doshowhyphenatednextbox - {\ctxlua{commands.showhyphenatedinlist(tex.box[\number\nextbox].list)}} + {\ctxcommand{showhyphenatedinlist(tex.box[\number\nextbox].list)}} \def\showhyphens{\dowithnextbox\doshowhyphenatednextbox\hbox} @@ -980,7 +980,7 @@ %D \stoptyping \def\dohyphenatednextbox - {\ctxlua{commands.hyphenatedlist(tex.box[\number\nextbox])}% + {\ctxcommand{hyphenatedlist(tex.box[\number\nextbox])}% \unhbox\nextbox} \def\hyphenatedword {\dowithnextbox\dohyphenatednextbox \hbox} @@ -1304,14 +1304,14 @@ {\dontleavehmode \begingroup \setbox\scratchbox\normalhbox{#1}% - \ctxlua{commands.applytochars(\number\scratchbox,"\strippedcsname#2",true)}% + \ctxcommand{applytochars(\number\scratchbox,"\strippedcsname#2",true)}% \endgroup} \def\processisolatedwords#1#2% {\dontleavehmode \begingroup \setbox\scratchbox\normalhbox{#1}% - \ctxlua{commands.applytowords(\number\scratchbox,"\strippedcsname#2",true)}% + \ctxcommand{applytowords(\number\scratchbox,"\strippedcsname#2",true)}% \endgroup} \unexpanded\def\processwords#1% @@ -1323,12 +1323,12 @@ \def\applytocharacters#1% {\dontleavehmode - \dowithnextbox{\ctxlua{commands.applytochars(\number\nextbox,"\strippedcsname#1",true)}}% + \dowithnextbox{\ctxcommand{applytochars(\number\nextbox,"\strippedcsname#1",true)}}% \normalhbox} \def\applytowords#1% {\dontleavehmode - \dowithnextbox{\ctxlua{commands.applytowords(\number\nextbox,"\strippedcsname#1",true)}}% + \dowithnextbox{\ctxcommand{applytowords(\number\nextbox,"\strippedcsname#1",true)}}% \normalhbox} %D \macros diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua index 4370e1163..0ea1fa2b8 100644 --- a/tex/context/base/supp-fil.lua +++ b/tex/context/base/supp-fil.lua @@ -20,9 +20,11 @@ local find, gsub, match, format, concat = string.find, string.gsub, string.match local texcount = tex.count local isfile = lfs.isfile -local trace_modules = false trackers.register("modules.loading", function(v) trace_modules = v end) +local trace_modules = false trackers.register("modules.loading", function(v) trace_modules = v end) +local trace_files = false trackers.register("resolvers.readfile", function(v) trace_files = v end) local report_modules = logs.new("modules") +local report_files = logs.new("resolvers") commands = commands or { } local commands = commands @@ -106,23 +108,44 @@ local function readfilename(specification,backtrack,treetoo) local name = specification.filename local fnd = found[name] if not fnd then - if fnd ~= "" and isfile(name) then + if isfile(name) then + if trace_files then + report_files("readfile local, found %s",fname) + end fnd = name end - if backtrack and (not fnd or fnd == "") then + if backtrack then local fname = name for i=1,backtrack,1 do fname = "../" .. fname if isfile(fname) then + if trace_files then + report_files("readfile backtracking, found %s",fname) + end fnd = fname break + elseif trace_files then + report_files("readfile backtracking, not found %s",fname) end end end if not fnd and treetoo then - fnd = resolvers.findtexfile(name) + fnd = resolvers.findtexfile(name) or "" + if trace_files then + if fnd ~= "" then + report_files("readfile tree lookup, found %s",fnd) + else + report_files("readfile tree lookup, not found %s",name) + end + end end found[name] = fnd + elseif trace_files then + if fnd ~= "" then + report_files("readfile reuse, already found: %s",fnd) + else + report_files("readfile reuse, already ñot found: %s",name) + end end return fnd or "" end @@ -309,16 +332,19 @@ function commands.uselibrary(name,patterns,action,failure) loaded[filename] = true for i=1,#patterns do local filename = format(patterns[i],filename) - -- local foundname = resolvers.find_file(filename) or "" + -- local foundname = resolvers.findfile(filename) or "" local foundname = finders.doreadfile("any",".",filename) if foundname ~= "" then action(name,foundname) done = true end end + if done then + break + end end end - if not done then + if failure and not done then failure(name) end end diff --git a/tex/context/base/supp-fil.mkiv b/tex/context/base/supp-fil.mkiv index 5db8098e3..555d1240a 100644 --- a/tex/context/base/supp-fil.mkiv +++ b/tex/context/base/supp-fil.mkiv @@ -98,8 +98,8 @@ \def\writeln#1{\write#1{}} -\def\doiffileexistselse #1{\ctxlua{commands.doiffileexistelse([[#1]])}} -\def\lastfoundexistingfile {\ctxlua{commands.lastexistingfile()}} +\def\doiffileexistselse #1{\ctxcommand{doiffileexistelse([[#1]])}} +\def\lastfoundexistingfile {\ctxcommand{lastexistingfile()}} %D \macros %D {doprocessfile,fileline,fileprocessedtrue,dofinishfile} @@ -164,13 +164,13 @@ {\edef#3{#2}} {\edef#3{#1\f!pathseparator#2}}} -\def\sanitizefilename#1\to#2{\edef#2{\ctxlua{commands.thesanitizedfilename([[#1]])}}} +\def\sanitizefilename#1\to#2{\edef#2{\ctxcommand{thesanitizedfilename([[#1]])}}} %D NEW: \newconstant\kindoffile % 0=normal 1=full path spec (or http) / set at the lua end -\def\checkfilename#1{\ctxlua{commands.checkfilename([[#1]])}} +\def\checkfilename#1{\ctxcommand{checkfilename([[#1]])}} %D \macros %D {input, normalinput} @@ -240,13 +240,13 @@ \let \everyreadfile \everybeforereadfile -\def\maxreadlevel{\ctxlua{commands.maxreadlevel()}} +\def\maxreadlevel{\ctxcommand{maxreadlevel()}} % We need to postpone loading, else we got frozen type-* files and so when % a format is generated on a source path. \def\doreadfile#1#2#3% protocol path filename true false - {\edef\readfilename{\ctxlua{commands.doreadfile("#1","#2","#3")}}% + {\edef\readfilename{\ctxcommand{doreadfile("#1","#2","#3")}}% \ifx\readfilename\empty \expandafter\doreadfilenop \else @@ -399,7 +399,7 @@ \ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi -\def\doifparentfileelse#1{\ctxlua{commands.doifparentfileelse([[#1]])}} +\def\doifparentfileelse#1{\ctxcommand{doifparentfileelse([[#1]])}} \newcount\readingfilelevel @@ -454,7 +454,7 @@ \let\splitoffname\empty \let\splitofftype\empty -\def\splitfilename#1{\ctxlua{commands.splitfilename([[#1]])}} -\def\splitfiletype#1{\ctxlua{commands.splitfiletype([[#1]])}} +\def\splitfilename#1{\ctxcommand{splitfilename([[#1]])}} +\def\splitfiletype#1{\ctxcommand{splitfiletype([[#1]])}} \protect \endinput diff --git a/tex/context/base/supp-fun.mkiv b/tex/context/base/supp-fun.mkiv index 6b2643703..a8db3b634 100644 --- a/tex/context/base/supp-fun.mkiv +++ b/tex/context/base/supp-fun.mkiv @@ -134,7 +134,7 @@ \def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars {\defconvertedargument\asciia{#7}% \defconvertedcommand \asciib{\DroppedString}% - \ExpandBothAfter\doifinstringelse\asciia\asciib + \doifinstringelse\asciia\asciib {\noindentation \dontleavehmode \checkindentation % redo this one diff --git a/tex/context/base/supp-ran.mkiv b/tex/context/base/supp-ran.mkiv index 9d429598f..bd9a385aa 100644 --- a/tex/context/base/supp-ran.mkiv +++ b/tex/context/base/supp-ran.mkiv @@ -18,13 +18,13 @@ \registerctxluafile{supp-ran}{1.001} -\def\getrandomcount #1#2#3{#1=\ctxlua{commands.getrandomcounta(\number#2,\number#3)}} -\def\getrandomdimen #1#2#3{#1=\ctxlua{commands.getrandomcounta(\number\dimexpr#2,\number\dimexpr#3)}\scaledpoint} -\def\getrandomnumber#1#2#3{\edef#1{\ctxlua{commands.getrandomcounta(\number#2,\number#3)}}} -\def\getrandomfloat #1#2#3{\edef#1{\ctxlua{commands.getrandomcountb(\number\dimexpr#2\points,\number\dimexpr#3\points)}}} -\def\setrandomseed #1{\ctxlua{commands.setrandomseed(\number#1)}} -\def\getrandomseed {\ctxlua{commands.getrandomseed()}} -\def\freezerandomseed {\ctxlua{commands.freezerandomseed()}} -\def\defrostrandomseed {\ctxlua{commands.defrostrandomseed()}} +\def\getrandomcount #1#2#3{#1=\ctxcommand{getrandomcounta(\number#2,\number#3)}} +\def\getrandomdimen #1#2#3{#1=\ctxcommand{getrandomcounta(\number\dimexpr#2,\number\dimexpr#3)}\scaledpoint} +\def\getrandomnumber#1#2#3{\edef#1{\ctxcommand{getrandomcounta(\number#2,\number#3)}}} +\def\getrandomfloat #1#2#3{\edef#1{\ctxcommand{getrandomcountb(\number\dimexpr#2\points,\number\dimexpr#3\points)}}} +\def\setrandomseed #1{\ctxcommand{setrandomseed(\number#1)}} +\def\getrandomseed {\ctxcommand{getrandomseed()}} +\def\freezerandomseed {\ctxcommand{freezerandomseed()}} +\def\defrostrandomseed {\ctxcommand{defrostrandomseed()}} \endinput diff --git a/tex/context/base/symb-run.mkiv b/tex/context/base/symb-run.mkiv index 8efb5e63d..33bbb7927 100644 --- a/tex/context/base/symb-run.mkiv +++ b/tex/context/base/symb-run.mkiv @@ -45,7 +45,7 @@ \unprotect \gdef\doshowsymbolset[#1]% - {\ctxlua{commands.showsymbolset("#1","\symbolset{#1}")}} + {\ctxcommand{showsymbolset("#1","\symbolset{#1}")}} \gdef\showsymbolset {\dosingleargument\doshowsymbolset} diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index c2a47b828..d0a557c19 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -1,5 +1,5 @@ %D \module -%D [ file=syst-gen, +%D [ file=syst-aux, % merge of syst-gen cum suis %D version=1996.03.20, %D title=\CONTEXT\ System Macros, %D subtitle=General, @@ -65,6 +65,8 @@ %D %D The \type {yyyy.mm.dd} syntax is rather strict. +% todo: lua + \def\@@versiontonumber#1.#2.#3#4#5\relax {\numexpr#1*\plustenthousand+#2*\plushundred+#3#4\relax} @@ -174,73 +176,26 @@ %D commalist or when data stored in macros is fed to index of %D list commands. If needed, one should use \type{\noexpand} %D inside the argument. Later on we will meet some more clever -%D alternatives to this command. +%D alternatives to this command. Beware, only the simple one +%D has \type {\noexpand} before its argument. -\long\def\@@expanded{} % always long; global (less restores) + \long\def\@@expanded{} % always long; global (less restores) \long\def\expanded#1% {\long\xdef\@@expanded{\noexpand#1}\@@expanded} -%D Beware, the next one has no \type {\noexpand} before its -%D argument. - \long\def\startexpanded#1\stopexpanded % see x-fo for example {\long\xdef\@@expanded{#1}\@@expanded} %D Recent \TEX's have a primitive \expanded -% \long\def\expanded -% {\normalexpanded\bgroup\noexpand\gobblenexttoken} - -%D \macros -%D {safeexpanded,everysafeexpanded} -%D -%D In addition we provide: - -\newtoks\everysafeexpanded - -\long\def\safeexpanded#1% why the \noexpand - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#1}% - \endgroup - \@@expanded} - -\def\safeedef#1#2% - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% - \endgroup - \let#1\@@expanded} - -\def\safexdef#1#2% - {\begingroup - \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}% - \endgroup - \global\let#1\@@expanded} - -%D You can append protective measures to the token register if -%D needed, as we will do later. - -%D \macros -%D {expandoneargafter,expandtwoargsafter} -%D -%D These two commands make macros more readable by hiding a -%D lot of \type {\expandafter}'s. They expand the arguments -%D after the first command. -%D -%D \starttyping -%D \expandoneargafter \command{\abc} -%D \expandtwoargsafter\command{\abc}{\def} -%D \stoptyping -%D -%D These commands expect the arguments to be macros. - -\def\expandoneargafter #1{\@EA#1\@EA} -\def\expandtwoargsafter#1#2{\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA} - -%D These two do a full expansion: - -\def\fullexpandoneargafter #1#2{\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} -\def\fullexpandtwoargsafter#1#2#3{\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} +% not yet as we need to adapt ##'s in calls +% +% \long\def\expanded#1% +% {\normalexpanded{\noexpand#1}} +% +% \long\def\startexpanded#1\stopexpanded +% {\normalexpanded{#1}} %D \macros %D {gobbleoneargument,gobble...arguments} @@ -310,18 +265,23 @@ %D test in a run. Of course it also is more convenient to read a %D trace then. +\newif\ifnextblankspacetoken + \let\nextoptionalcharactertoken=[ \long\def\doifnextoptionalelse#1#2% {\def\nextoptionalcommandyes{#1}% \def\nextoptionalcommandnop{#2}% + \let\ifnextblankspacetoken\iffalse \futurelet\nexttoken\inspectnextoptionalcharacter} + \def\inspectnextoptionalcharacter {\ifx\nexttoken\blankspace \@EA\reinspectnextoptionalcharacter \else \@EA\inspectnextoptionalcharacterindeed \fi} + \def\inspectnextoptionalcharacterindeed {\ifx\nexttoken\nextoptionalcharactertoken \@EA\nextoptionalcommandyes @@ -334,6 +294,7 @@ \long\def\doifnextbgroupelse#1#2% {\def\nextbgroupcommandyes{#1}% \def\nextbgroupcommandnop{#2}% + \let\ifnextblankspacetoken\iffalse \futurelet\nexttoken\inspectnextbgroupcharacter} \def\inspectnextbgroupcharacter @@ -355,6 +316,7 @@ \long\def\doifnextparenthesiselse#1#2% {\def\nextparenthesiscommandyes{#1}% \def\nextparenthesiscommandnop{#2}% + \let\ifnextblankspacetoken\iffalse \futurelet\nexttoken\inspectnextparenthesischaracter} \def\inspectnextparenthesischaracter @@ -376,6 +338,7 @@ \long\def\doiffastoptionalcheckelse#1#2% {\def\nextoptionalcommandyes{#1}% \def\nextoptionalcommandnop{#2}% + \let\ifnextblankspacetoken\iffalse % not needed \futurelet\nexttoken\dodoiffastoptionalcheckelse} \def\dodoiffastoptionalcheckelse @@ -405,13 +368,13 @@ \def\:{\let\blankspace= } \: \def\:{\reinspectnextcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextcharacter} +\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextcharacter} \def\:{\reinspectnextoptionalcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextoptionalcharacter} +\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextoptionalcharacter} \def\:{\reinspectnextbgroupcharacter} -\expandafter\def\: {\futurelet\nexttoken\inspectnextbgroupcharacter} +\expandafter\def\: {\let\ifnextblankspacetoken\iftrue\futurelet\nexttoken\inspectnextbgroupcharacter} \let\:\next @@ -499,8 +462,10 @@ %D \ifundefined\NameB ... \else ... \fi %D \stoptyping -\def\ifundefined#1% obsolete - {\unless\ifcsname#1\endcsname} +% \def\ifundefined#1% obsolete +% {\unless\ifcsname#1\endcsname} +% +% use a real if like \ifcsname#1\endcsname\else instead \ifdefined\suppressifcsnameerror @@ -864,21 +829,6 @@ % !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop} % !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop} -% \def\p!doifcommonelse#1#2#3#4% -% {\donefalse -% \def\p!docommoncheck##1{\doifinset{##1}{#4}\donetrue\ifdone\quitcommalist\fi}% -% \processcommalist[#3]\p!docommoncheck -% \ifdone\expandafter#1\else\expandafter#2\fi} -% -% \def\doifcommonelse -% {\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments} -% -% \def\doifcommon -% {\p!doifcommonelse\firstofoneargument \gobbleoneargument} -% -% \def\doifnotcommon -% {\p!doifcommonelse\gobbleoneargument \firstofoneargument} - \long\def\doquitifcommonelse#1],\relax#2],\relax{\firstoftwoarguments} \long\def\doquitifcommonelsenop{\secondoftwoarguments} @@ -927,23 +877,6 @@ \fi\fi #1#2} -% \def\p!doifcommonelse#1#2#3% -% {\edef\!!stringa{#3}% -% \ifx\!!stringa\empty -% \expandafter\secondofthreearguments -% \else -% \expandafter\p!dodoifcommonelse -% \fi -% #1#2} % #4 - -% \def\p!dodoifcommonelse#1#2#3% -% {\edef\!!stringb{#3}% -% \ifx\!!stringb\empty -% \expandafter\secondoftwoarguments -% \else -% \expandafter\pp!doifcommonelse -% \fi#1#2} - \def\pp!doifcommonelse {\def\p!docommoncheck{\expandafter\docheckifcommonelsetwo\!!stringb,],\relax}% \expandafter\docheckifcommonelseone\!!stringa,],\relax} @@ -989,15 +922,6 @@ \def\dododoprocesscommaitem {\csname\s!next\the\commalevel\endcsname} -% \def\dodoprocesscommaitem -% {\ifx\nexttoken\blankspace -% \@EA\redoprocesscommaitem -% \else\ifx\nexttoken]% -% \@EAEAEA\gobbleoneargument -% \else -% \@EAEAEA\dododoprocesscommaitem -% \fi\fi} - \def\dodoprocesscommaitem {\ifx\nexttoken\blankspace \@EA\redoprocesscommaitem @@ -1090,20 +1014,8 @@ %D Commands that are part of the list are expanded, so the %D use of this macro has its limits. -% \def\processcommacommand[#1]% -% {\expanded{\processcommalist[#1]}} - \unexpanded\def\processcommacommand[#1]% - {\expandafter\processcommalist\expandafter[\normalexpanded{#1}]} - -% \def\processcommacommand[#1]% -% {\edef\expandedcommacommand{#1% -% \ifx\expandedcommacommand\empty\else -% \doprocesscommacommand -% \fi} -% -% \def\doprocesscommacommand -% {\expandafter\processcommalist\expandafter[\expandedcommacommand]} + {\normalexpanded{\processcommalist[#1]}} %D The argument to \type{\command} is not delimited. Because %D we often use \type{[]} as delimiters, we also have: @@ -1133,7 +1045,7 @@ \long\unexpanded\def\startprocesscommacommand[#1]#2\stopprocesscommacommand {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}% - \normalexpanded{\noexpand\processcommacommand[#1]}\currentcommalistcommand} + \normalexpanded{\processcommalist[#1]}\currentcommalistcommand} %D \macros %D {processaction, @@ -1416,25 +1328,10 @@ % replaces prev -% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} -% {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here -% \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here - \long\def\p!doifinstringelse#1#2% ##2 can be {abc} {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here \expandafter\pp!doifinstringelse\normalexpanded{#2#1}@@\war} % expand #2 here -% faster but at some costs -% -% \def\setp!doifinstringelse#1#2% ##2 can be {abc} -% {\long\expandafter\gdef\csname @diie:#1\@EA\endcsname\@EA##\@EA1#1##2##3\war{\unless\if##2@}}% expand #1 here -% -% \long\def\p!doifinstringelse#1#2% ##2 can be {abc} -% {\ifcsname @diie:#1\endcsname \else -% \setp!doifinstringelse{#1}{#2}% -% \fi -% \csname @diie:#1\expandafter\endcsname\normalexpanded{#2#1}@@\war} % expand #2 here - %D The next alternative proved to be upto twice as fast on %D tasks like checking reserved words in pretty verbatim %D typesetting! This is mainly due to the fact that passing @@ -1821,10 +1718,6 @@ \let\p!doassign\p!n!doassign -% \def\doassign [#1][#2]{\p!doassign\dosetvalue #1\@relax@#2==\empty\@relax@} -% \def\doeassign [#1][#2]{\p!doassign\dosetevalue #1\@relax@#2==\empty\@relax@} -% \def\undoassign[#1][#2]{\p!doassign\doresetvalue#1\@relax@#2==\empty\@relax@} - \def\doassign [#1][#2]{\let\setsomevalue\dosetvalue \p!doassign#1\@relax@#2==\empty\@relax@} \def\doeassign [#1][#2]{\let\setsomevalue\dosetevalue \p!doassign#1\@relax@#2==\empty\@relax@} \def\undoassign[#1][#2]{\let\setsomevalue\doresetvalue\p!doassign#1\@relax@#2==\empty\@relax@} @@ -1843,12 +1736,12 @@ %D We can optimize this one if needed but it's not a core macro so hardly %D worth the trouble and tokens. -\def\processassignmentlist[#1]#2% #2 == \command{key}{value] +\unexpanded\def\processassignmentlist[#1]#2% #2 == \command{key}{value] {\def\doprocessassignmententry##1{#2}% {##2}{##3} % namespace is ignored \dogetparameters\doprocessassignmententry[][#1]} -\def\processassignmentcommand[#1]% - {\normalexpanded{\noexpand\processassignmentlist[#1]}} +\unexpanded\def\processassignmentcommand[#1]% + {\normalexpanded{\processassignmentlist[#1]}} \long\unexpanded\def\startprocessassignmentlist[#1]#2\stopprocessassignmentlist {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% @@ -1856,7 +1749,7 @@ \long\unexpanded\def\startprocessassignmentcommand[#1]#2\stopprocessassignmentcommand {\long\def\currentassignmentlistcommand##1##2{\def\currentassignmentlistkey{##1}\def\currentassignmentlistvalue{##2}#2}% - \normalexpanded{\noexpand\processassignmentlist[#1]}\currentassignmentlistcommand} + \normalexpanded{\processassignmentlist[#1]}\currentassignmentlistcommand} %D \macros{currentvalue} %D @@ -1895,16 +1788,6 @@ \def\xdoget@n@parameters#1]% {\xprocesscommaitem#1,],\@relax@} -% \def\xdoget@e@parameters#1]% -% {\let\dosetnvalue\dosetvalue -% \let\dosetvalue\dosetevalue -% \let\p!doassign\p!e!doassign -% \xprocesscommaitem#1,],\@relax@ -% \let\p!doassign\p!n!doassign -% \let\dosetvalue\dosetnvalue -% \let\xdogetparameters\xdoget@n@parameters -% \let\currentvalue\empty} - \def\xdoget@e@parameters#1]% {\let\dosetnvalue\setsomevalue \let\setsomevalue\dosetevalue @@ -2037,18 +1920,6 @@ \scratchtoks\expandafter{\expandafter[\commacommand]}% \expandafter\getcommalistsize\the\scratchtoks } -% to be tested first -% -% \def\getcommacommandsize[#1]% -% {\expanded{\getcommalistsize[#1]}} - -% \def\p!dogetfromcommalist#1% -% {\advance\commalistcounter \minusone -% \ifcase\commalistcounter -% \def\commalistelement{#1}% -% \begingroup\def\doprocesscommaitem##1]{\endgroup}% -% \fi} - \def\p!dogetfromcommalist#1% {\advance\commalistcounter \minusone \ifcase\commalistcounter @@ -2216,8 +2087,6 @@ %D use the \type{\if...argument} boolean. For novice: watch %D the stepwise doubling of \type{#}'s -% idea: \ignorespaces afterwards - \setnewconstant\noexpectedarguments\zerocount \setnewconstant\expectedarguments \zerocount @@ -2233,163 +2102,668 @@ \def\noshowargumenterror {\let\expectedarguments\noexpectedarguments} -\long\def\dogetargument#1#2#3#4% - {\let\charactertoken=#1% - \def\!!stringa{\noshowargumenterror#3\dodogetargument}% - \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}% - \futurelet\nexttoken\inspectnextcharacter} - -\def\getsingleempty#1#2#3% - {\def\dodogetargument% - {#3}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getdoubleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument% - {#3#1{##1}#2}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\gettripleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getquadrupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getquintupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getsixtupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument#1################################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2% - #1{################################1}#2}% - \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\getseventupleempty#1#2#3% - {\def\dodogetargument#1##1#2% - {\def\dodogetargument#1####1#2% - {\def\dodogetargument#1########1#2% - {\def\dodogetargument#1################1#2% - {\def\dodogetargument#1################################1#2% - {\def\dodogetargument#1################################% - ################################1#2% - {\def\dodogetargument% - {#3#1{##1}#2% - #1{####1}#2% - #1{########1}#2% - #1{################1}#2% - #1{################################1}#2% - #1{################################% - ################################1}#2}% - \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}% - \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% - \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% - \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% - \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% - \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% - \dogetargument#1#2\firstargumenttrue\firstargumentfalse} - -\def\dosingleempty {\getsingleempty []} -\def\dodoubleempty {\getdoubleempty []} -\def\dotripleempty {\gettripleempty []} -\def\doquadrupleempty {\getquadrupleempty []} -\def\doquintupleempty {\getquintupleempty []} -\def\dosixtupleempty {\getsixtupleempty []} -\def\doseventupleempty{\getseventupleempty[]} +% \long\def\dogetargument#1#2#3#4% +% {\let\charactertoken=#1% +% \def\!!stringa{\noshowargumenterror#3\dodogetargument}% +% \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}% +% \futurelet\nexttoken\inspectnextcharacter} + +% \def\getsingleempty#1#2#3% +% {\def\dodogetargument% +% {#3}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\getdoubleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\gettripleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument#1####1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2% +% #1{####1}#2}% +% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\getquadrupleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument#1####1#2% +% {\def\dodogetargument#1########1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2% +% #1{####1}#2% +% #1{########1}#2}% +% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% +% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\getquintupleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument#1####1#2% +% {\def\dodogetargument#1########1#2% +% {\def\dodogetargument#1################1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2% +% #1{####1}#2% +% #1{########1}#2% +% #1{################1}#2}% +% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% +% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% +% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\getsixtupleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument#1####1#2% +% {\def\dodogetargument#1########1#2% +% {\def\dodogetargument#1################1#2% +% {\def\dodogetargument#1################################1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2% +% #1{####1}#2% +% #1{########1}#2% +% #1{################1}#2% +% #1{################################1}#2}% +% \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% +% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% +% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% +% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\getseventupleempty#1#2#3% +% {\def\dodogetargument#1##1#2% +% {\def\dodogetargument#1####1#2% +% {\def\dodogetargument#1########1#2% +% {\def\dodogetargument#1################1#2% +% {\def\dodogetargument#1################################1#2% +% {\def\dodogetargument#1################################% +% ################################1#2% +% {\def\dodogetargument% +% {#3#1{##1}#2% +% #1{####1}#2% +% #1{########1}#2% +% #1{################1}#2% +% #1{################################1}#2% +% #1{################################% +% ################################1}#2}% +% \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}% +% \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}% +% \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}% +% \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}% +% \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}% +% \dogetargument#1#2\secondargumenttrue\secondargumentfalse}% +% \dogetargument#1#2\firstargumenttrue\firstargumentfalse} + +% \def\dosingleempty {\getsingleempty []} +% \def\dodoubleempty {\getdoubleempty []} +% \def\dotripleempty {\gettripleempty []} +% \def\doquadrupleempty {\getquadrupleempty []} +% \def\doquintupleempty {\getquintupleempty []} +% \def\dosixtupleempty {\getsixtupleempty []} +% \def\doseventupleempty{\getseventupleempty[]} %D Because some of these are called quite often, we will now %D replace the more general version by alternatives tuned for %D speed. -\def\dosingleempty#1% we can make dedicated doifnextoptional's - {\noshowargumenterror % \relax % prevents lookahead, brr +% \def\dosingleempty#1% we can make dedicated doifnextoptional's +% {\noshowargumenterror % \relax % prevents lookahead, brr +% \doifnextoptionalelse +% {\firstargumenttrue#1}% +% {\dosinglefakeempty#1}} +% +% \def\dosinglefakeempty#1% +% {\firstargumentfalse#1[]} +% +% \def\dodoubleempty#1% +% {\noshowargumenterror % \relax % prevents lookahead, brr +% \doifnextoptionalelse +% {\dodoubletestempty#1}% +% {\dodoublefakeempty#1}} +% +% \def\dodoublefakeempty#1% +% {\firstargumentfalse\secondargumentfalse#1[][]} +% +% \long\def\dodoubletestempty#1[#2]% +% {\firstargumenttrue +% \doifnextoptionalelse +% {\secondargumenttrue #1[{#2}]}% +% {\secondargumentfalse#1[{#2}][]}} +% +% \def\dotripleempty#1% +% {\noshowargumenterror % \relax % prevents lookahead, brr +% \doifnextoptionalelse +% {\dotripletestempty#1}% +% {\dotriplefakeempty#1}} +% +% \def\dotriplefakeempty#1% +% {\firstargumentfalse\secondargumentfalse\thirdargumentfalse#1[][][]} +% +% \long\def\dotripletestempty#1[#2]% +% {\firstargumenttrue +% \doifnextoptionalelse +% {\dotripletestemptyx #1[{#2}]}% +% {\secondargumentfalse +% \thirdargumentfalse #1[{#2}][][]}} +% +% \long\def\dotripletestemptyx#1[#2][#3]% +% {\secondargumenttrue +% \doifnextoptionalelse +% {\thirdargumenttrue #1[{#2}][{#3}]}% +% {\thirdargumentfalse#1[{#2}][{#3}][]}} + +%D We can obey following spaces with a bit more code. + +% 0.172 0.187 new (per 10000) +% 0.156 0.140 old (per 10000) +% +% \def\test[#1]{(#1)} +% +% \dosingleempty\test[] xxx\par +% \dosingleempty\test xxx\par +% +% \def\test[#1][#2]{(#1,#2)} +% +% \dodoubleempty\test[][] xxx\par +% \dodoubleempty\test[] xxx\par +% \dodoubleempty\test xxx\par +% +% \def\test[#1][#2][#3]{(#1,#2,#3)} +% +% \dotripleempty\test[][][] xxx\par +% \dotripleempty\test[][] xxx\par +% \dotripleempty\test[] xxx\par +% \dotripleempty\test xxx\par + +%D Single: + +\def\dosingleempty#1% + {\noshowargumenterror \doifnextoptionalelse {\firstargumenttrue#1}% - {\dosinglefakeempty#1}} + {\dosingleemptyNOPone#1}} + +\def\dosingleemptyNOPone#1% + {\firstargumentfalse + #1[]} + +%D Double \def\dodoubleempty#1% - {\noshowargumenterror % \relax % prevents lookahead, brr + {\noshowargumenterror \doifnextoptionalelse - {\dodoubletestempty#1}% - {\dodoublefakeempty#1}} + {\dodoubleemptyYESone#1}% + {\dodoubleemptyNOPone#1}} + +\long\def\dodoubleemptyYESone#1[#2]% + {\firstargumenttrue + \doifnextoptionalelse + {\secondargumenttrue#1[{#2}]}% + {\dodoubleemptyNOPtwo#1{#2}}} + +\def\dodoubleemptyNOPone#1% + {\firstargumentfalse + \secondargumentfalse + #1[][]} + +\def\dodoubleemptyNOPtwo + {\secondargumentfalse + \ifnextblankspacetoken + \expandafter\dodoubleemptyonespaced + \else + \expandafter\dodoubleemptyonenormal + \fi} + +\def\dodoubleemptyonespaced#1#2{#1[{#2}][] } +\def\dodoubleemptyonenormal#1#2{#1[{#2}][]} + +% Three \def\dotripleempty#1% - {\noshowargumenterror % \relax % prevents lookahead, brr + {\noshowargumenterror + \doifnextoptionalelse + {\dotripleemptyYESone#1}% + {\dotripleemptyNOPone#1}} + +\long\def\dotripleemptyYESone#1[#2]% + {\firstargumenttrue + \doifnextoptionalelse + {\dotripleemptyYEStwo#1{#2}}% + {\dotripleemptyNOPtwo#1{#2}}} + +\long\def\dotripleemptyYEStwo#1#2[#3]% + {\secondargumenttrue + \doifnextoptionalelse + {\thirdargumenttrue#1[{#2}][{#3}]}% + {\dotripleemptyNOPthree#1{#2}{#3}}} + +\def\dotripleemptyNOPone#1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + #1[][][]} + +\def\dotripleemptyNOPtwo + {\secondargumentfalse + \thirdargumentfalse + \ifnextblankspacetoken + \expandafter\dotripleemptytwospaced + \else + \expandafter\dotripleemptytwonormal + \fi} + +\def\dotripleemptyNOPthree + {\thirdargumentfalse + \ifnextblankspacetoken + \expandafter\dotripleemptythreespaced + \else + \expandafter\dotripleemptythreenormal + \fi} + +\def\dotripleemptytwospaced #1#2{#1[{#2}][][] } +\def\dotripleemptytwonormal #1#2{#1[{#2}][][]} +\def\dotripleemptythreespaced#1#2#3{#1[{#2}][{#3}][] } +\def\dotripleemptythreenormal#1#2#3{#1[{#2}][{#3}][]} + +%D Four: + +\def\doquadrupleempty#1% + {\noshowargumenterror + \doifnextoptionalelse + {\doquadrupleemptyYESone#1}% + {\doquadrupleemptyNOPone#1}} + +\long\def\doquadrupleemptyYESone#1[#2]% + {\firstargumenttrue + \doifnextoptionalelse + {\doquadrupleemptyYEStwo#1{#2}}% + {\doquadrupleemptyNOPtwo#1{#2}}} + +\long\def\doquadrupleemptyYEStwo#1#2[#3]% + {\secondargumenttrue + \doifnextoptionalelse + {\doquadrupleemptyYESthree#1{#2}{#3}}% + {\doquadrupleemptyNOPthree#1{#2}{#3}}} + +\long\def\doquadrupleemptyYESthree#1#2#3[#4]% + {\thirdargumenttrue + \doifnextoptionalelse + {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}% + {\doquadrupleemptyNOPfour#1{#2}{#3}{#4}}} + +\def\doquadrupleemptNOPone#1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + #1[][][][]} + +\def\doquadrupleemptyNOPtwo + {\secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \ifnextblankspacetoken + \expandafter\doquadrupleemptytwospaced + \else + \expandafter\doquadrupleemptytwonormal + \fi} + +\def\doquadrupleemptyNOPthree + {\thirdargumentfalse + \fourthargumentfalse + \ifnextblankspacetoken + \expandafter\doquadrupleemptythreespaced + \else + \expandafter\doquadrupleemptythreenormal + \fi} + +\def\doquadrupleemptyNOPfour + {\fourthargumentfalse + \ifnextblankspacetoken + \expandafter\doquadrupleemptyfourspaced + \else + \expandafter\doquadrupleemptyfournormal + \fi} + +\def\doquadrupleemptytwospaced #1#2{#1[{#2}][][][] } +\def\doquadrupleemptytwonormal #1#2{#1[{#2}][][][]} +\def\doquadrupleemptythreespaced #1#2#3{#1[{#2}][{#3}][][] } +\def\doquadrupleemptythreenormal #1#2#3{#1[{#2}][{#3}][][]} +\def\doquadrupleemptyfourspaced #1#2#3#4{#1[{#2}][{#3}][{#4}][] } +\def\doquadrupleemptyfournormal #1#2#3#4{#1[{#2}][{#3}][{#4}][]} + +%D Five: + +\def\doquintupleempty#1% + {\noshowargumenterror \doifnextoptionalelse - {\dotripletestempty#1}% - {\dotriplefakeempty#1}} + {\doquintupleemptyYESone#1}% + {\doquintupleemptyNOPone#1}} -\def\dosinglefakeempty#1% - {\firstargumentfalse#1[]} +\long\def\doquintupleemptyYESone#1[#2]% + {\firstargumenttrue + \doifnextoptionalelse + {\doquintupleemptyYEStwo#1{#2}}% + {\doquintupleemptyNOPtwo#1{#2}}} -\def\dodoublefakeempty#1% - {\firstargumentfalse\secondargumentfalse#1[][]} +\long\def\doquintupleemptyYEStwo#1#2[#3]% + {\secondargumenttrue + \doifnextoptionalelse + {\doquintupleemptyYESthree#1{#2}{#3}}% + {\doquintupleemptyNOPthree#1{#2}{#3}}} -\def\dotriplefakeempty#1% - {\firstargumentfalse\secondargumentfalse\thirdargumentfalse#1[][][]} +\long\def\doquintupleemptyYESthree#1#2#3[#4]% + {\thirdargumenttrue + \doifnextoptionalelse + {\doquintupleemptyYESfour#1{#2}{#3}{#4}}% + {\doquintupleemptyNOPfour#1{#2}{#3}{#4}}} -\long\def\dodoubletestempty#1[#2]% +\long\def\doquintupleemptyYESfour#1#2#3#4[#5]% + {\fourthargumenttrue + \doifnextoptionalelse + {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}% + {\doquintupleemptyNOPfive#1{#2}{#3}{#4}{#5}}} + +\def\doquintupleemptNOPone#1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + #1[][][][][]} + +\def\doquintupleemptyNOPtwo + {\secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \ifnextblankspacetoken + \expandafter\doquintupleemptytwospaced + \else + \expandafter\doquintupleemptytwonormal + \fi} + +\def\doquintupleemptyNOPthree + {\thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \ifnextblankspacetoken + \expandafter\doquintupleemptythreespaced + \else + \expandafter\doquintupleemptythreenormal + \fi} + +\def\doquintupleemptyNOPfour + {\fourthargumentfalse + \fifthargumentfalse + \ifnextblankspacetoken + \expandafter\doquintupleemptyfourspaced + \else + \expandafter\doquintupleemptyfournormal + \fi} + +\def\doquintupleemptyNOPfive + {\fifthargumentfalse + \ifnextblankspacetoken + \expandafter\doquintupleemptyfivespaced + \else + \expandafter\doquintupleemptyfivenormal + \fi} + +\def\doquintupleemptytwospaced #1#2{#1[{#2}][][][][] } +\def\doquintupleemptytwonormal #1#2{#1[{#2}][][][][]} +\def\doquintupleemptythreespaced #1#2#3{#1[{#2}][{#3}][][][] } +\def\doquintupleemptythreenormal #1#2#3{#1[{#2}][{#3}][][][]} +\def\doquintupleemptyfourspaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][] } +\def\doquintupleemptyfournormal #1#2#3#4{#1[{#2}][{#3}][{#4}][][]} +\def\doquintupleemptyfivespaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][] } +\def\doquintupleemptyfivenormal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][]} + +%D Six + +\def\dosixtupleempty#1% + {\noshowargumenterror + \doifnextoptionalelse + {\dosixtupleemptyYESone#1} + {\dosixtupleemptyNOPone#1}} + +\long\def\dosixtupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse - {\secondargumenttrue #1[{#2}]}% - {\secondargumentfalse#1[{#2}][]}} + {\dosixtupleemptyYEStwo#1{#2}}% + {\dosixtupleemptyNOPtwo#1{#2}}} + +\long\def\dosixtupleemptyYEStwo#1#2[#3]% + {\secondargumenttrue + \doifnextoptionalelse + {\dosixtupleemptyYESthree#1{#2}{#3}}% + {\dosixtupleemptyNOPthree#1{#2}{#3}}} + +\long\def\dosixtupleemptyYESthree#1#2#3[#4]% + {\thirdargumenttrue + \doifnextoptionalelse + {\dosixtupleemptyYESfour#1{#2}{#3}{#4}}% + {\dosixtupleemptyNOPfour#1{#2}{#3}{#4}}} -\long\def\dotripletestempty#1[#2]% +\long\def\dosixtupleemptyYESfour#1#2#3#4[#5]% + {\fourthargumenttrue + \doifnextoptionalelse + {\dosixtupleemptyYESfive#1{#2}{#3}{#4}{#5}}% + {\dosixtupleemptyNOPfive#1{#2}{#3}{#4}{#5}}} + +\long\def\dosixtupleemptyYESfive#1#2#3#4#5[#6]% + {\fifthargumenttrue + \doifnextoptionalelse + {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}% + {\dosixtupleemptyNOPsix#1{#2}{#3}{#4}{#5}{#6}}} + +\def\dosixemptNOPone#1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + #1[][][][][][]} + +\def\dosixtupleemptyNOPtwo + {\secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \ifnextblankspacetoken + \expandafter\dosixemptytwospaced + \else + \expandafter\dosixemptytwonormal + \fi} + +\def\dosixtupleemptyNOPthree + {\thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \ifnextblankspacetoken + \expandafter\dosixemptythreespaced + \else + \expandafter\dosixemptythreenormal + \fi} + +\def\dosixtupleemptyNOPfour + {\fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \ifnextblankspacetoken + \expandafter\dosixemptyfourspaced + \else + \expandafter\dosixemptyfournormal + \fi} + +\def\dosixtupleemptyNOPfive + {\fifthargumentfalse + \sixthargumentfalse + \ifnextblankspacetoken + \expandafter\dosixemptyfivespaced + \else + \expandafter\dosixemptyfivenormal + \fi} + +\def\dosixtupleemptyNOPsix + {\sixthargumentfalse + \ifnextblankspacetoken + \expandafter\dosixemptysixspaced + \else + \expandafter\dosixemptysixnormal + \fi} + +\def\dosixemptytwospaced #1#2{#1[{#2}][][][][][] } +\def\dosixemptytwonormal #1#2{#1[{#2}][][][][][]} +\def\dosixemptythreespaced #1#2#3{#1[{#2}][{#3}][][][][] } +\def\dosixemptythreenormal #1#2#3{#1[{#2}][{#3}][][][][]} +\def\dosixemptyfourspaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][] } +\def\dosixemptyfournormal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][]} +\def\dosixemptyfivespaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][] } +\def\dosixemptyfivenormal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][]} +\def\dosixemptysixspaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][] } +\def\dosixemptysixnormal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][]} + +%D Seven: + +\def\doseventupleempty#1% + {\noshowargumenterror + \doifnextoptionalelse + {\doseventupleemptyYESone#1} + {\doseventupleemptyNOPone#1}} + +\long\def\doseventupleemptyYESone#1[#2]% {\firstargumenttrue \doifnextoptionalelse - {\dotripletestemptyx #1[{#2}]}% - {\secondargumentfalse - \thirdargumentfalse #1[{#2}][][]}} + {\doseventupleemptyYEStwo#1{#2}}% + {\doseventupleemptyNOPtwo#1{#2}}} -\long\def\dotripletestemptyx#1[#2][#3]% +\long\def\doseventupleemptyYEStwo#1#2[#3]% {\secondargumenttrue \doifnextoptionalelse - {\thirdargumenttrue #1[{#2}][{#3}]}% - {\thirdargumentfalse#1[{#2}][{#3}][]}} + {\doseventupleemptyYESthree#1{#2}{#3}}% + {\doseventupleemptyNOPthree#1{#2}{#3}}} + +\long\def\doseventupleemptyYESthree#1#2#3[#4]% + {\thirdargumenttrue + \doifnextoptionalelse + {\doseventupleemptyYESfour#1{#2}{#3}{#4}}% + {\doseventupleemptyNOPfour#1{#2}{#3}{#4}}} + +\long\def\doseventupleemptyYESfour#1#2#3#4[#5]% + {\fourthargumenttrue + \doifnextoptionalelse + {\doseventupleemptyYESfive#1{#2}{#3}{#4}{#5}}% + {\doseventupleemptyNOPfive#1{#2}{#3}{#4}{#5}}} + +\long\def\doseventupleemptyYESfive#1#2#3#4#5[#6]% + {\fifthargumenttrue + \doifnextoptionalelse + {\doseventupleemptyYESsix#1{#2}{#3}{#4}{#5}{#6}}% + {\doseventupleemptyNOPsix#1{#2}{#3}{#4}{#5}{#6}}} + +\long\def\doseventupleemptyYESsix#1#2#3#4#5#6[#7]% + {\sixthargumenttrue + \doifnextoptionalelse + {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}% + {\doseventupleemptyNOPseven#1{#2}{#3}{#4}{#5}{#6}{#7}}} + +\def\dosevenemptNOPone#1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \seventhargumentfalse + #1[][][][][][][]} + +\def\doseventupleemptyNOPtwo + {\secondargumentfalse + \thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptytwospaced + \else + \expandafter\dosevenemptytwonormal + \fi} + +\def\doseventupleemptyNOPthree + {\thirdargumentfalse + \fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptythreespaced + \else + \expandafter\dosevenemptythreenormal + \fi} + +\def\doseventupleemptyNOPfour + {\fourthargumentfalse + \fifthargumentfalse + \sixthargumentfalse + \seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptyfourspaced + \else + \expandafter\dosevenemptyfournormal + \fi} + +\def\doseventupleemptyNOPfive + {\fifthargumentfalse + \sixthargumentfalse + \seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptyfivespaced + \else + \expandafter\dosevenemptyfivenormal + \fi} + +\def\doseventupleemptyNOPsix + {\sixthargumentfalse + \seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptysixspaced + \else + \expandafter\dosevenemptysixnormal + \fi} + +\def\doseventupleemptyNOPseven + {\seventhargumentfalse + \ifnextblankspacetoken + \expandafter\dosevenemptysevenspaced + \else + \expandafter\dosevenemptysevennormal + \fi} + +\def\dosevenemptytwospaced #1#2{#1[{#2}][][][][][][] } +\def\dosevenemptytwonormal #1#2{#1[{#2}][][][][][][]} +\def\dosevenemptythreespaced #1#2#3{#1[{#2}][{#3}][][][][][] } +\def\dosevenemptythreenormal #1#2#3{#1[{#2}][{#3}][][][][][]} +\def\dosevenemptyfourspaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][] } +\def\dosevenemptyfournormal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][]} +\def\dosevenemptyfivespaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][] } +\def\dosevenemptyfivenormal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][]} +\def\dosevenemptysixspaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][] } +\def\dosevenemptysixnormal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][]} +\def\dosevenemptysevenspaced#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][] } +\def\dosevenemptysevennormal#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][]} %D \macros %D {strippedcsname} @@ -2527,11 +2901,6 @@ %D potentially being an \type {conditional} token. Okay, these macros %D are not called that often but it saves crap when tracing. -% \def\dogetgroupargument#1#2% -% {\let\dogroupargumentyes#1% -% \let\dogroupargumentnop#2% -% \futurelet\nextargument\dodogetgroupargument} - \def\dodogetgroupargument {\ifx\nextargument\bgroup \expandafter\dodogetgroupargumentA @@ -2543,20 +2912,6 @@ {\noshowargumenterror \dogroupargumentyes\dodogetargument} -% \def\dodogetgroupargumentB -% {\ifcase\@@permitspacesbetweengroups -% \expandafter\dodogetgroupargumentC -% \else -% \expandafter\dodogetgroupargumentD -% \fi} - -% \def\dodogetgroupargumentC -% {\ifx\nextargument\lineending -% \expandafter\dodogetgroupargumentE -% \else -% \expandafter\dodogetgroupargumentF -% \fi} - \def\dodogetgroupargumentB {\ifcase\@@permitspacesbetweengroups \expandafter\dodogetgroupargumentF @@ -2568,9 +2923,6 @@ {\doshowargumenterror \dogroupargumentnop\dodogetargument{}} -% \def\dodogetgroupargumentE -% {\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\} - \begingroup \def\\ {\dogetgroupargument\dogroupargumentyes\dogroupargumentnop} \global\let\dodogetgroupargumentE\\ @@ -2937,14 +3289,14 @@ \long\gdef\dododostarttexdefinition#1#2#3\stoptexdefinition% {\egroup% - \long\setvalue{#1}#2{#3}} + \expandafter\def\csname#1\endcsname#2{#3}} \long\gdef\nonostarttexdefinition#1 {\nononostarttexdefinition{#1}{}} \long\gdef\nononostarttexdefinition#1#2#3\stoptexdefinition% {\egroup% - \long\setvalue{#1}{#3}} + \expandafter\def\csname#1\endcsname{#3}} \egroup @@ -3066,8 +3418,6 @@ \edef#1{\the\maximumsignal}% \fi} -\let\newskimen\newdimen % it's all etex or later now - %D \macros %D {strippedcsname} %D @@ -3239,7 +3589,7 @@ \else \let\nextrecurse\exitstepwiserecurse \fi - \fi\normalexpanded{\noexpand\nextrecurse{\number#1}{\number#2}{\number#3}}} + \fi\normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} \long\def\dodostepwiserecurse#1#2#3% from to step {\ifnum#1>#2\relax @@ -3249,21 +3599,13 @@ \@EAEAEA\redostepwiserecurse\@EA \fi\@EA{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} -\def\expandrecursecontent +\unexpanded\def\expandrecursecontent {\csname\@@arecurse\recursedepth\endcsname} -\def\redostepwiserecurse +\unexpanded\def\redostepwiserecurse {\expandrecursecontent\dodostepwiserecurse} -\long\def\dodostepwisereverse#1#2#3% from to step - {\ifnum#1<#2\relax - \@EA\nodostepwiserecurse - \else - \def\recurselevel{#1}% - \@EAEAEA\redostepwisereverse\@EA - \fi\@EA{\the\numexpr\recurselevel#3\relax}{#2}{#3}} - -\long\def\dodostepwisereverse#1#2#3% from to step +\long\unexpanded\def\dodostepwisereverse#1#2#3% from to step {\ifnum#1<#2\relax \@EA\nodostepwiserecurse \else @@ -3273,21 +3615,21 @@ \@EAEAEA\redostepwisereverse\@EA \fi\@EA{\the\innerrecurse}{#2}{#3}} -\def\redostepwisereverse +\unexpanded\def\redostepwisereverse {\expandrecursecontent\dodostepwisereverse} -\def\exitstepwiserecurse +\unexpanded\def\exitstepwiserecurse {\nodostepwiserecurse\relax} -\def\nodostepwiserecurse#1#2#3#4% +\unexpanded\def\nodostepwiserecurse#1#2#3#4% {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\def\nonostepwiserecurse#1#2#3% +\unexpanded\def\nonostepwiserecurse#1#2#3% {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\def\dorecurse#1% +\unexpanded\def\dorecurse#1% {\dostepwiserecurse1{#1}1} %D As we can see here, the simple command \type{\dorecurse} is @@ -3309,7 +3651,7 @@ %D Because the simple case is used often, we implement it %D more efficiently: -\long\def\dorecurse#1% +\long\unexpanded\def\dorecurse#1% {\ifcase#1\relax \expandafter\gobbletwoarguments \or @@ -3318,13 +3660,13 @@ \expandafter\xdorecurse \fi{#1}} -\long\def\xdorecurse#1#2% +\long\unexpanded\def\xdorecurse#1#2% {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#2}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \@EA\dodorecurse\@EA1\@EA{\number#1}} -\long\def\ydorecurse#1#2% +\long\unexpanded\def\ydorecurse#1#2% {\global\advance\outerrecurse \plusone \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\recurselevel\!!plusone @@ -3332,7 +3674,7 @@ \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\long\def\dodorecurse#1#2% from to +\long\unexpanded\def\dodorecurse#1#2% from to {\ifnum#1>#2\relax \@EA\nodorecurse \else @@ -3340,7 +3682,7 @@ \@EAEAEA\redorecurse \fi\@EA{\the\numexpr\recurselevel+\plusone\relax}{#2}} -\long\def\dodorecurse#1#2% from to +\long\unexpanded\def\dodorecurse#1#2% from to {\ifnum#1>#2\relax \@EA\nodorecurse \else @@ -3349,10 +3691,10 @@ \@EAEAEA\redorecurse \fi\@EA{\the\innerrecurse}{#2}} -\def\redorecurse +\unexpanded\def\redorecurse {\expandrecursecontent\dodorecurse} -\def\nodorecurse#1#2#3% +\unexpanded\def\nodorecurse#1#2#3% {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone } @@ -3376,29 +3718,29 @@ \let\endofloop\donothing -\long\def\doloop#1% +\unexpanded\long\def\doloop#1% {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#1}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\endofloop\dodoloop \dodoloop1} % no \plusone else \recurselevel wrong -\long\def\dodoloop#1% +\unexpanded\long\def\dodoloop#1% {\def\recurselevel{#1}% \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}} -\def\redoloop +\unexpanded\def\redoloop {\expandrecursecontent\endofloop} -\def\nodoloop#1% +\unexpanded\def\nodoloop#1% {\let\endofloop\dodoloop % new, permits nested \doloop's \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse\minusone} -\def\exitloop % \exitloop quits at end +\unexpanded\def\exitloop % \exitloop quits at end {\let\endofloop\nodoloop} -\long\def\exitloopnow#1\endofloop % \exitloopnow quits directly +\long\unexpanded\def\exitloopnow#1\endofloop % \exitloopnow quits directly {\nodoloop} %D The loop is executed at least once, so beware of situations @@ -3442,13 +3784,13 @@ \def\expandrecursecontent {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}} -\long\def\xdorecurse#1#2% +\long\unexpanded\def\xdorecurse#1#2% {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \@EA\dodorecurse\@EA1\@EA{\number#1}} -\long\def\ydorecurse#1#2% +\long\unexpanded\def\ydorecurse#1#2% {\global\advance\outerrecurse \plusone \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel \let\recurselevel\!!plusone @@ -3457,7 +3799,7 @@ \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname \global\advance\outerrecurse \minusone} -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel @@ -3477,9 +3819,9 @@ \else \let\nextrecurse\exitstepwiserecurse \fi - \fi\normalexpanded{\noexpand\nextrecurse{\number#1}{\number#2}{\number#3}}} + \fi\normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} -\long\def\doloop#1% +\long\unexpanded\def\doloop#1% {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel @@ -3490,7 +3832,7 @@ % faster -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel @@ -3511,11 +3853,11 @@ \let\nextrecurse\exitstepwiserecurse \fi \fi - \expandafter\nextrecurse\normalexpanded{{\number#1}{\number#2}{\number#3}}} + \normalexpanded{\nextrecurse{\number#1}{\number#2}{\number#3}}} % slightly faster -\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +\long\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel @@ -3531,13 +3873,38 @@ \let\@swrd\dodostepwiserecurse \let\@swrr\dodostepwisereverse +% quite okay too, but untested +% +% \long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +% {\global\advance\outerrecurse \plusone +% \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}% +% \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel +% \normalexpanded +% {\ifnum#3>\zerocount +% \ifnum#2<#1 +% \exitstepwiserecurse +% \else +% \dodostepwiserecurse +% \fi +% \else +% \ifnum#3<\zerocount +% \ifnum#1<#2 +% \exitstepwiserecurse +% \else +% \dodostepwisereverse +% \fi +% \else +% \exitstepwiserecurse +% \fi +% \fi{\number#1}{\number#2}{\number#3}}} + %D For special purposes: \newcount\fastrecursecounter \newcount\lastrecursecounter \newcount\steprecursecounter -\def\dofastrecurse#1#2#3#4% +\unexpanded\def\dofastrecurse#1#2#3#4% {\def\fastrecursebody{#4}% \fastrecursecounter#1\relax \lastrecursecounter#2\relax @@ -3545,9 +3912,9 @@ \def\recurselevel{\number\fastrecursecounter}% \dodofastrecurse} -\def\resetrecurselevel{\let\recurselevel\!!zerocount} +\unexpanded\def\resetrecurselevel{\let\recurselevel\!!zerocount} -\def\dodofastrecurse +\unexpanded\def\dodofastrecurse {\ifnum\fastrecursecounter>\lastrecursecounter % \resetrecurselevel % slows down \else @@ -3578,11 +3945,11 @@ %D The use of \type{\od} as a dilimiter would have made nested %D use more problematic. -%D Don't use this one, it's kind of obsolete. - -\def\for#1=#2\to#3\step#4\do#5% - {\dostepwiserecurse{#2}{#3}{#4} - {\let#1\recurselevel#5\let#1\recurselevel}} +% obsolete: +% +% \def\for#1=#2\to#3\step#4\do#5% +% {\dostepwiserecurse{#2}{#3}{#4} +% {\let#1\recurselevel#5\let#1\recurselevel}} %D \macros %D {newevery,everyline,EveryLine,EveryPar} @@ -3838,70 +4205,14 @@ %D \doifsamestringelse{\jobname}{oeps}{YES}{NO} %D \stoptyping -% \def\@@doifsamestringelse#1#2#3#4% -% {\edef\!!stringa{#3}\convertcommand\!!stringa\to\!!stringa -% \edef\!!stringb{#4}\convertcommand\!!stringb\to\!!stringb -% \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} - \def\@@doifsamestringelse#1#2#3#4% {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#3}}}% \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#4}}}% \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi} \def\doifsamestringelse{\@@doifsamestringelse\firstoftwoarguments\secondoftwoarguments} -\def\doifsamestring {\@@doifsamestringelse\firstofoneargument\gobbleoneargument} -\def\doifnotsamestring {\@@doifsamestringelse\gobbleoneargument\firstofoneargument} - -%D \macros -%D {ExpandFirstAfter,ExpandSecondAfter,ExpandBothAfter} -%D -%D These three commands support expansion of arguments before -%D executing the commands that uses them. We can best -%D illustrate this with an example. -%D -%D \starttyping -%D \def\first {alfa,beta,gamma} -%D \def\second {alfa,epsilon,zeta} -%D -%D \ExpandFirstAfter \doifcommon {\first} {alfa} {\message{OK}} -%D \ExpandSecondAfter \doifcommon {alfa} {\second} {\message{OK}} -%D \ExpandBothAfter \doifcommon {\first} {\second} {\message{OK}} -%D -%D \ExpandFirstAfter\processcommalist[\first]\message -%D -%D \ExpandAfter \doifcommon {\first} {alfa} {\message{OK}} -%D \stoptyping -%D -%D The first three calls result in the threefold message -%D \type{OK}, the fourth one shows the three elements of -%D \type{\first}. The command \type{\ExpandFirstAfter} takes -%D care of (first) arguments that are delimited by \type{[ ]}, -%D but the faster \type{\ExpandAfter} does not. - -\def\simpleExpandFirstAfter#1% - {\long\xdef\@@expanded{\noexpand\ExpandCommand{#1}}\@@expanded} - -\def\complexExpandFirstAfter[#1]% - {\long\xdef\@@expanded{\noexpand\ExpandCommand[#1]}\@@expanded} - -\def\ExpandFirstAfter#1% - {\let\ExpandCommand#1% - \doifnextoptionalelse\complexExpandFirstAfter\simpleExpandFirstAfter} - -\def\ExpandSecondAfter#1#2#3% - {\scratchtoks{#2}% - \long\xdef\@@expanded{\noexpand#1{\the\scratchtoks}{#3}}\@@expanded} - -\def\ExpandBothAfter#1#2#3% - {\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded} - -\def\ExpandAfter#1#2% - {\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded} - -%D Now we can for instance define \type{\ifinstringelse} as: - -\def\ifinstringelse - {\ExpandBothAfter\p!doifinstringelse} +\def\doifsamestring {\@@doifsamestringelse\firstofoneargument \gobbleoneargument } +\def\doifnotsamestring {\@@doifsamestringelse\gobbleoneargument \firstofoneargument } %D \macros %D {ConvertToConstant,ConvertConstantAfter} @@ -4419,7 +4730,7 @@ {\ifx#2\empty % redundant but gives cleaner extensions #4{#1}% \else\ifnum#1<\zerocount - \normalexpanded{\noexpand\dorecurse{\number-\number#1}}{#4{-#2#3}}% + \normalexpanded{\dorecurse{\number-\number#1}}{#4{-#2#3}}% \else\ifx#2+% \dorecurse{#1}{#4{#3}}% \else @@ -5257,38 +5568,38 @@ %D We have to use a two||step implementation, because the %D expansion has to take place outside \type{\uppercase}. -\def\p!DOIF#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% +\unexpanded\def\DOIF#1#2% + {\uppercase{{$#1$}{$#2$}}% \expandafter\firstofoneargument \else \expandafter\gobbleoneargument \fi} -\def\p!DOIFNOT#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% +\unexpanded\def\DOIFNOT#1#2% + {\uppercase{{$#1$}{$#2$}}% \expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} -\def\p!DOIFELSE#1#2% - {\uppercase{\ifinstringelse{$#1$}{$#2$}}% +\unexpanded\def\DOIFELSE#1#2% + {\uppercase{{$#1$}{$#2$}}% \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} -\def\p!DOIFINSTRINGELSE#1#2% - {\uppercase{\ifinstringelse{#1}{#2}}% +\unexpanded\def\DOIFINSTRINGELSE#1#2% + {\uppercase{{$#1$}{$#2$}}% \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} -\def\DOIF {\ExpandBothAfter\p!DOIF} -\def\DOIFNOT {\ExpandBothAfter\p!DOIFNOT} -\def\DOIFELSE {\ExpandBothAfter\p!DOIFELSE} -\def\DOIFINSTRINGELSE {\ExpandBothAfter\p!DOIFINSTRINGELSE} +\def\DOIF #1#2{\normalexpanded{\p!DOIF {#1}{#2}}} +\def\DOIFNOT #1#2{\normalexpanded{\p!DOIFNOT {#1}{#2}}} +\def\DOIFELSE #1#2{\normalexpanded{\p!DOIFELSE {#1}{#2}}} +\def\DOIFINSTRINGELSE #1#2{\normalexpanded{\p!DOIFINSTRINGELSE{#1}{#2}}} %D \macros %D {dosingleargumentwithset, @@ -6619,8 +6930,8 @@ % \fi % \def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax} -\def\resettimer {\ctxlua{commands.resettimer()}} -\def\elapsedtime {\ctxlua{commands.elapsedtime()}} +\def\resettimer {\ctxcommand{resettimer()}} +\def\elapsedtime {\ctxcommand{elapsedtime()}} \let\elapsedseconds \elapsedtime \newcount\featuretest @@ -6728,14 +7039,6 @@ \long\def\@@if@@equal@@true #1\@@then#2#3{#2} \long\def\@@if@@equal@@false#1\@@then#2#3{#3} -%D new stuff : - -\def\partialexpanded#1% - {\let\@@notexpanded\noexpand - \long\xdef\@@expanded{\noexpand#1}% - \let\@@notexpanded\empty - \@@expanded} - \def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}} \def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname} \def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname} @@ -6753,6 +7056,8 @@ %D bibliography module. The numbers compressor converts the %D list in a list of ranges. The normal compressor remove duplicate %D and empty entries. +%D +%D This is now obsolete (and more a \LUA\ thing anyway). \def\compresscommalistnrs[#1]% {\let\compressedlist\empty @@ -6861,18 +7166,6 @@ %D \stoplines %D \macros -%D {stripstring} -%D -%D Needed in bookmarks: -%D -%D \starttyping -%D {\sanitizePDFdocencoding test \CONTEXT\ test \to\oeps\stripstring\oeps\tttf[\oeps]} -%D \stoptyping - -\def\stripstring#1% #1 is \cs - {\edef\cs{\ctxlua{tex.sprint(tex.vrbcatcodes,string.strip(\!!bs\detokenize\expandafter{#1}\!!es))}}} - -%D \macros %D {dowithrange} %D %D This one is for Mojca Miklavec, who made me aware of the fact that diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua index 2fb2ee8a2..bcc020528 100644 --- a/tex/context/base/syst-con.lua +++ b/tex/context/base/syst-con.lua @@ -16,11 +16,20 @@ the top of <l n='luatex'/>'s char range but outside the unicode range.</p> local tonumber = tonumber local char, texsprint, format = unicode.utf8.char, tex.sprint, string.format -function converters.hexstringtonumber(n) texsprint(tonumber(n,16)) end -function converters.octstringtonumber(n) texsprint(tonumber(n, 8)) end -function converters.rawcharacter (n) texsprint(char(0x110000+n)) end -function converters.lchexnumber (n) texsprint(format("%x" ,n)) end -function converters.uchexnumber (n) texsprint(format("%X" ,n)) end -function converters.lchexnumbers (n) texsprint(format("%02x",n)) end -function converters.uchexnumbers (n) texsprint(format("%02X",n)) end -function converters.octnumber (n) texsprint(format("%03o",n)) end +function converters.hexstringtonumber(n) tonumber(n,16) end +function converters.octstringtonumber(n) tonumber(n, 8) end +function converters.rawcharacter (n) char(0x110000+n) end +function converters.lchexnumber (n) format("%x" ,n) end +function converters.uchexnumber (n) format("%X" ,n) end +function converters.lchexnumbers (n) format("%02x",n) end +function converters.uchexnumbers (n) format("%02X",n) end +function converters.octnumber (n) format("%03o",n) end + +function commands.hexstringtonumber(n) context(tonumber(n,16)) end +function commands.octstringtonumber(n) context(tonumber(n, 8)) end +function commands.rawcharacter (n) context(char(0x110000+n)) end +function commands.lchexnumber (n) context(format("%x" ,n)) end +function commands.uchexnumber (n) context(format("%X" ,n)) end +function commands.lchexnumbers (n) context(format("%02x",n)) end +function commands.uchexnumbers (n) context(format("%02X",n)) end +function commands.octnumber (n) context(format("%03o",n)) end diff --git a/tex/context/base/syst-con.mkiv b/tex/context/base/syst-con.mkiv index af9fa16bd..1091be859 100644 --- a/tex/context/base/syst-con.mkiv +++ b/tex/context/base/syst-con.mkiv @@ -46,10 +46,10 @@ %D [\expandafter\uchexnumber\expandafter{\the\zerocount}] %D \stoptyping -\def\lchexnumber #1{\ctxlua{converters.lchexnumber(\number#1)}} -\def\uchexnumber #1{\ctxlua{converters.uchexnumber(\number#1)}} -\def\lchexnumbers#1{\ctxlua{converters.lchexnumbers(\number#1)}} -\def\uchexnumbers#1{\ctxlua{converters.uchexnumbers(\number#1)}} +\def\lchexnumber #1{\ctxcommand{lchexnumber(\number#1)}} +\def\uchexnumber #1{\ctxcommand{uchexnumber(\number#1)}} +\def\lchexnumbers#1{\ctxcommand{lchexnumbers(\number#1)}} +\def\uchexnumbers#1{\ctxcommand{uchexnumbers(\number#1)}} \let\hexnumber\uchexnumber @@ -58,7 +58,7 @@ %D %D For unicode remapping purposes, we need octal numbers. -\def\octnumber#1{\ctxlua{converters.octnumber(\number#1)}} +\def\octnumber#1{\ctxcommand{octnumber(\number#1)}} %D \macros %D {hexstringtonumber,octstringtonumber} @@ -67,8 +67,8 @@ %D a decimal number, thereby taking care of lowercase characters %D as well. -\def\hexstringtonumber#1{\ctxlua{converters.hexstringtonumber("#1")}} -\def\octstringtonumber#1{\ctxlua{converters.octstringtonumber("#1")}} +\def\hexstringtonumber#1{\ctxcommand{hexstringtonumber("#1")}} +\def\octstringtonumber#1{\ctxcommand{octstringtonumber("#1")}} %D \macros %D {rawcharacter} @@ -76,7 +76,7 @@ %D This macro can be used to produce proper 8 bit characters %D that we sometimes need in backends and round||trips. -\def\rawcharacter#1{\ctxlua{converters.rawcharacter(\number#1)}} +\def\rawcharacter#1{\ctxcommand{rawcharacter(\number#1)}} %D \macros %D {twodigits, threedigits} diff --git a/tex/context/base/syst-lua.mkiv b/tex/context/base/syst-lua.mkiv index a5dce5461..3ed70cc0b 100644 --- a/tex/context/base/syst-lua.mkiv +++ b/tex/context/base/syst-lua.mkiv @@ -15,15 +15,15 @@ \unprotect -\def\expdoifelse#1#2{\ctxlua{commands.doifelse(\!!bs#1\!!es==\!!bs#2\!!es)}} -\def\expdoif #1#2{\ctxlua{commands.doif (\!!bs#1\!!es==\!!bs#2\!!es)}} -\def\expdoifnot #1#2{\ctxlua{commands.doifnot (\!!bs#1\!!es==\!!bs#2\!!es)}} +\def\expdoifelse#1#2{\ctxcommand{doifelse(\!!bs#1\!!es==\!!bs#2\!!es)}} +\def\expdoif #1#2{\ctxcommand{doif (\!!bs#1\!!es==\!!bs#2\!!es)}} +\def\expdoifnot #1#2{\ctxcommand{doifnot (\!!bs#1\!!es==\!!bs#2\!!es)}} % \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3 % \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5 -\def\expdoifcommonelse#1#2{\ctxlua{commands.doifcommonelse("#1","#2")}} -\def\expdoifinsetelse #1#2{\ctxlua{commands.doifinsetelse("#1","#2")}} +\def\expdoifcommonelse#1#2{\ctxcommand{doifcommonelse("#1","#2")}} +\def\expdoifinsetelse #1#2{\ctxcommand{doifinsetelse("#1","#2")}} % we define these here, just in case ... @@ -32,7 +32,7 @@ \edef\!!bs{[\luastringsep[} \edef\!!es{]\luastringsep]} -\def\writestatus#1#2{\ctxlua{commands.writestatus(\!!bs#1\!!es,\!!bs#2\!!es)}} +\def\writestatus#1#2{\ctxcommand{writestatus(\!!bs#1\!!es,\!!bs#2\!!es)}} % a handy helper (we can probably omit the tex.ctxcatcodes here as nowadays we seldom % change the regime at the tex end diff --git a/tex/context/base/syst-str.mkiv b/tex/context/base/syst-str.mkiv deleted file mode 100644 index 57d76dc03..000000000 --- a/tex/context/base/syst-str.mkiv +++ /dev/null @@ -1,36 +0,0 @@ -%D \module -%D [ file=syst-str, -%D version=2006.09.18, -%D title=\CONTEXT\ System Macros, -%D subtitle=String Processing, -%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. - -\unprotect - -% nb: these macros might go away ! -% -% todo: escape special chars in expr (\luaescapeexpression) - -%D I got tired of making dedicated clean up macros using the -%D same mechanism again and again, so now we have: -%D -%D \starttyping -%D \def\xxxx{abc.d} \replacecharacters\xxxx{a.}{-} \xxxx -%D \stoptyping - -\def\replacecharacters#1#2#3% macro characters replacement - {\dodoglobal\edef#1{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,\!!bs#2\!!es,"#3")))}}} - -\def\separatestring#1\to#2% - {\dodoglobal\def#2{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,"\letterpercent s+",",")))}}} - -\def\unspacefilename#1\to#2% - {\dodoglobal\def#2{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,"\letterpercent s+","-")))}}} - -\protect \endinput diff --git a/tex/context/base/tabl-ltb.mkiv b/tex/context/base/tabl-ltb.mkiv index 66d3c0265..06e3eca29 100644 --- a/tex/context/base/tabl-ltb.mkiv +++ b/tex/context/base/tabl-ltb.mkiv @@ -583,42 +583,6 @@ \globallet\noflinetableparts\!!zerocount \egroup} -% \def\checklinecolumnwidth -% {\ifundefined{\??lew\number\linetablecolumn}% -% \donetrue -% \else\ifdim\getvalue{\??lew\number\linetablecolumn}<\wd\linetablecell -% \donetrue -% \else -% \donefalse -% \fi\fi -% \ifdone -% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% -% \fi} -% -% \def\checklinecolumnwidth -% {\ifcsname\??lew\number\linetablecolumn\endcsname -% \ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell -% \donetrue -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% -% \fi} - -% \def\checklinecolumnwidth -% {\expandafter\xdef\csname\??lew\number\linetablecolumn\endcsname -% {\expandafter\ifx\csname\??lew\number\linetablecolumn\endcsname\relax -% \the\wd\linetablecell -% \else\ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell -% \the\wd\linetablecell -% \else -% \csname\??lew\number\linetablecolumn\endcsname -% \fi\fi}} - \def\checklinecolumndimension#1#2#3% {\expandafter\xdef\csname#1\number#3\endcsname {\expandafter\ifx\csname#1\number#3\endcsname\relax diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index 4b7e2f15d..e3e88d83f 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -22,7 +22,6 @@ % todo: fast if % todo: avoid halign (just do it manual) and thereby globals - % \unexpanded\def\startrow {\bTR} % \unexpanded\def\stoprow {\eTR} % \unexpanded\def\startcell#1\stopcell{\bTD#1\eTD} @@ -39,7 +38,6 @@ % \stopcelltable % \stoptext - % optie=rek beschrijven \writestatus{loading}{ConTeXt Table Macros / Natural Tables} @@ -488,17 +486,17 @@ \newcount\currentcol \newcount\tblspn -\def\parseTR[#1][#2]% [#2] is dummy that kills spaces / no #3 argument +\def\settblref#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:x\endcsname} +\def\gettblref#1#2{\ifcsname\@@tblprefix\number#1:\number#2:x\endcsname\csname\@@tblprefix\number#1:\number#2:x\endcsname\fi} + +\def\parseTR[#1]% {\currentcol\zerocount \advance\maximumrow\plusone \iffirstargument \setvalue{\@@tblprefix\c!y++\number\maximumrow}{\getparameters[\@@tbl\@@tbl][#1]}% maybe also in mkii \fi} -\def\settblref#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:x\endcsname} -\def\gettblref#1#2{\ifcsname\@@tblprefix\number#1:\number#2:x\endcsname\csname\@@tblprefix\number#1:\number#2:x\endcsname\fi} - -\long\def\parseTD[#1][#2]#3\eTD % [#2] is dummy that kills spaces +\long\def\parseTD[#1]#2\eTD {\def\tblny{\tblnr}% \def\tblnx{\tblnc}% \let\tblnc\plusone @@ -515,7 +513,7 @@ \else\ifnum\@@tblnindeed=\currentcol\else \scratchcounter\numexpr\@@tblnindeed-\currentcol+\minusone-\tblspn\relax \ifnum\scratchcounter>\zerocount - \normalexpanded{\noexpand\parseTD[\c!nx=\the\scratchcounter,\c!n=,\c!m=,*sq=\v!no][]}\eTD + \normalexpanded{\noexpand\parseTD[\c!nx=\the\scratchcounter,\c!n=,\c!m=,*sq=\v!no]}\eTD \fi % can also be made faster \getparameters[\@@tbl][\c!ny=\tblnr,\c!nx=\tblnc,nc=1,nr=1,#1,\c!n=,\c!m=]% @@ -524,7 +522,7 @@ \ifx\@@tblmindeed\empty \else \ifnum\@@tblmindeed=\currentcol \else \scratchcounter\numexpr\@@tblmindeed-\currentcol+\minusone-\tblspn\relax - \dorecurse\scratchcounter{\normalexpanded{\noexpand\parseTD[\c!n=,\c!m=][]}\eTD}% + \dorecurse\scratchcounter{\normalexpanded{\noexpand\parseTD[\c!n=,\c!m=]}\eTD}% % can be sped up \getparameters[\@@tbl][\c!ny=\tblnr,\c!nx=\tblnc,nc=1,nr=1,#1,\c!n=,\c!m=]% kind of double, see prev \fi @@ -552,7 +550,7 @@ \settblref\maximumrow\currentcol{\ifcsname\@@tbl\c!action\endcsname\csname\@@tbl\c!action\endcsname\fi}% % save text \edef\celltag{{\number\maximumrow}{\number\currentcol}}% - \@EA\settbltxt\@EA\maximumrow\@EA\currentcol\@EA{\@EA\handleTBLcell\celltag[#1]{#3}}} + \@EA\settbltxt\@EA\maximumrow\@EA\currentcol\@EA{\@EA\handleTBLcell\celltag[#1]{#2}}} \def\presetTBLcell {\row\maximumrow @@ -610,8 +608,6 @@ \long\def\parseTH[#1]#2\eTH {\parseTD[#1,\c!color=\tbltblheadcolor,\c!style=\tbltblheadstyle,\c!aligncharacter=\v!no]#2\eTD} - -%D new \long\def\parseTN[#1]#2\eTN {\parseTD[#1]\digits#2\relax\eTD} @@ -722,7 +718,7 @@ [\tbltblheader] [\v!repeat=>\multipleTBLheadstrue]% \presetallTABLEparameters - \ExpandFirstAfter\processallactionsinset + \processallactionsinset [\tbltbloption] [\v!stretch=>\autoTBLspreadtrue]% \linewidth\tbltblrulethickness % needs to be frozen @@ -736,10 +732,10 @@ \let\bTH\dobTH \let\bTN\dobTN} -\unexpanded\def\dobTR{\dodoubleempty\parseTR} -\unexpanded\def\dobTD{\dodoubleempty\parseTD} -\unexpanded\def\dobTH{\dodoubleempty\parseTH} -\unexpanded\def\dobTN{\dodoubleempty\parseTN} +\unexpanded\def\dobTR{\dosingleempty\parseTR} +\unexpanded\def\dobTD{\dosingleempty\parseTD} +\unexpanded\def\dobTH{\dosingleempty\parseTH} +\unexpanded\def\dobTN{\dosingleempty\parseTN} % permits \expanded{\bTD ... \eTD} @@ -1057,8 +1053,7 @@ \dotagTABLEcell} % right spot \def\inTBLcell#1#2% hm, do we need #1 #2 ? we use tblcol anyway - {\ExpandBothAfter\doifinsetelse\localwidth{\v!fit,\v!broad} % user set - {} + {\doifnotinset\localwidth{\v!fit,\v!broad}% user set {\scratchdimen\gettblaut\tblcol\relax \ifdim\localwidth>\scratchdimen \settblaut\tblcol{\the\dimexpr\localwidth\relax}% diff --git a/tex/context/base/tabl-nte.mkiv b/tex/context/base/tabl-nte.mkiv index cde64a033..2a9e14703 100644 --- a/tex/context/base/tabl-nte.mkiv +++ b/tex/context/base/tabl-nte.mkiv @@ -84,13 +84,9 @@ \expandafter\dododoTABLENC \fi} -% \long\def\dododoTABLENC#1\NC -% {\ifconditional\inTABLEnc\else\settrue\inTABLEnc\parseTR[][]\fi -% \parseTD[][]#1\eTD\NC} - \long\def\dododoTABLENC#1\NC - {\ifconditional\inTABLEnc\else\settrue\inTABLEnc\parseTR[][]\fi - \dodoubleempty\parseTD#1\eTD\NC} + {\ifconditional\inTABLEnc\else\settrue\inTABLEnc\dobTR[]\fi + \dobTD#1\eTD\NC} %D The related structure commands are also available: diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index f1d82b942..b8ebb5ee7 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -319,7 +319,7 @@ \unexpanded\def\beginreshapedtabulatepar {\dowithnextbox - {\ctxlua{commands.doreshapeframedbox(\number\nextbox)}\ifvmode\unvbox\else\box\fi\nextbox} + {\ctxcommand{doreshapeframedbox(\number\nextbox)}\ifvmode\unvbox\else\box\fi\nextbox} \vbox\bgroup} \let\endreshapedtabulatepar\egroup @@ -1612,7 +1612,7 @@ \tabulatepreamble{\aligntab\flushtabulateindent\strut\alignmark\alignmark\aligntab\alignmark\alignmark\tabskip\zeropoint}% \fi \tabulatewidth\zeropoint - \ctxlua{commands.presettabulate(\!!bs\detokenize{#1}\!!es)}% + \ctxcommand{presettabulate(\!!bs\detokenize{#1}\!!es)}% \edef\totaltabulatecolumns{\the\numexpr3*\tabulatecolumns+4}% \tabulatewidth\zeropoint \initializetableboxes\tabulatecolumns diff --git a/tex/context/base/type-ini.lua b/tex/context/base/type-ini.lua index 668766f4e..fd1282474 100644 --- a/tex/context/base/type-ini.lua +++ b/tex/context/base/type-ini.lua @@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['type-ini'] = { -- more code will move here local format, gsub = string.format, string.gsub -local find_file = resolvers.find_file local patterns = { "type-imp-%s.mkiv", "type-imp-%s.tex", "type-%s.mkiv", "type-%s.tex" } @@ -17,7 +16,6 @@ function commands.doprocesstypescriptfile(name) name = gsub(name,"^type%-","") for i=1,#patterns do local filename = format(patterns[i],name) - -- local foundname = find_file(filename) or "" local foundname = resolvers.finders.doreadfile("any",".",filename) if foundname ~= "" then context.startreadingfile() diff --git a/tex/context/base/type-ini.mkiv b/tex/context/base/type-ini.mkiv index b6942376e..7c4dd7819 100644 --- a/tex/context/base/type-ini.mkiv +++ b/tex/context/base/type-ini.mkiv @@ -190,7 +190,7 @@ \expandafter\let\csname\??ts:\c!file:\currenttypefile\endcsname\loadedtypescripts} \def\doprocesstypescriptfile - {\ctxlua{commands.doprocesstypescriptfile("\currenttypefile")}} + {\ctxcommand{doprocesstypescriptfile("\currenttypefile")}} % \def\doprocesstypescriptfile % {\startreadingfile @@ -499,7 +499,7 @@ \def\usetypefile[#1]% recurses on path ! % no storage? obsolete? {\edef\currenttypefile{#1}% - \ctxlua{commands.doprocesstypescriptfile("\currenttypefile")}} + \ctxcommand{doprocesstypescriptfile("\currenttypefile")}} %D For Taco: %D diff --git a/tex/context/base/type-run.mkiv b/tex/context/base/type-run.mkiv index e91398095..60061bcbe 100644 --- a/tex/context/base/type-run.mkiv +++ b/tex/context/base/type-run.mkiv @@ -21,7 +21,7 @@ \def\dochecktypescript##1##2% script use {\doifelsenothing{##1##2} {\donetrue} - {\ExpandBothAfter\doifcommonelse{##1}{##2}\donetrue\donefalse}} + {\doifcommonelse{##1}{##2}\donetrue\donefalse}} \edef\typescriptone {\truetypescript{#1}}% \edef\typescripttwo {\truetypescript{#2}}% \edef\typescriptthree{\truetypescript{#3}}% diff --git a/tex/context/base/unic-ini.mkiv b/tex/context/base/unic-ini.mkiv index 7146d7c0a..0b7f19153 100644 --- a/tex/context/base/unic-ini.mkiv +++ b/tex/context/base/unic-ini.mkiv @@ -20,7 +20,7 @@ \def\unicodechar #1{\char\numexpr#1\relax} % no lookahead \def\unicodenumber #1{\the \numexpr#1\relax} % no lookahead -\def\unicodehexnumber#1{\ctxlua{tex.sprint(number.toevenhex(\number#1))}} +\def\unicodehexnumber#1{\cldcontext{number.toevenhex(\number#1))}} \unexpanded\def\unknownchar{{\hbox{\vrule\!!width.5em\!!height1ex\!!depth\zeropoint}}} diff --git a/tex/context/base/x-asciimath.lua b/tex/context/base/x-asciimath.lua index d278b0d6a..925911a8d 100644 --- a/tex/context/base/x-asciimath.lua +++ b/tex/context/base/x-asciimath.lua @@ -10,7 +10,11 @@ if not modules then modules = { } end modules ['x-asciimath'] = { <p>Some backgrounds are discussed in <t>x-asciimath.mkiv</t>.</p> --ldx]]-- -local trace_mapping = false if trackers then trackers.register("asciimath.mapping", function(v) trace_mapping = v end) end +local trace_mapping = false if trackers then trackers.register("modules.asciimath.mapping", function(v) trace_mapping = v end) end + +local asciimath = { } +local moduledata = moduledata or { } +moduledata.asciimath = asciimath local report_asciimath = logs.new("asciimath") @@ -264,6 +268,5 @@ parser = Cs { "main", } -asciimath = { } -asciimath.reserved = reserved -asciimath.convert = converted +asciimath.reserved = reserved +asciimath.convert = converted diff --git a/tex/context/base/x-asciimath.mkiv b/tex/context/base/x-asciimath.mkiv index cc0e66e99..fac3980a0 100644 --- a/tex/context/base/x-asciimath.mkiv +++ b/tex/context/base/x-asciimath.mkiv @@ -15,6 +15,8 @@ \registerctxluafile{x-asciimath}{} +\def\ctxmoduleasciimath#1{\directlua\zerocount{moduledata.asciimath.#1}} + %D The following code is not officially supported and is only meant %D for the Math4All project. %D @@ -62,13 +64,13 @@ \writestatus{asciimath}{beware, this is an experimental (m4all only) module} -\unexpanded\def\asciimath#1{\ctxlua{asciimath.convert(\!!bs\detokenize{#1}\!!es,true)}} +\unexpanded\def\asciimath#1{\ctxmoduleasciimath{convert(\!!bs\detokenize{#1}\!!es,true)}} \protect \doifnotmode{demo}{\endinput} -\enabletrackers[asciimath.mapping] +\enabletrackers[modules.asciimath.mapping] \starttext diff --git a/tex/context/base/x-calcmath.lua b/tex/context/base/x-calcmath.lua index 27ad56f58..bcf72f26f 100644 --- a/tex/context/base/x-calcmath.lua +++ b/tex/context/base/x-calcmath.lua @@ -9,12 +9,9 @@ if not modules then modules = { } end modules ['x-calcmath'] = { local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub local lpegmatch = lpeg.match -local texsprint = (tex and tex.sprint) or function(catcodes,str) print(str) end - -moduledata = moduledata or { } -moduledata.calcmath = moduledata.calcmath or { } - -local calcmath = moduledata.calcmath +local calcmath = { } +local moduledata = moduledata or { } +moduledata.calcmath = calcmath local list_1 = { "median", "min", "max", "round", "ln", "log", @@ -78,7 +75,7 @@ local function nsub(str,tag,pre,post) end)) end -function calcmath.totex(str,mode) +local function totex(str,mode) if not frozen then freeze() end local n = 0 -- crap @@ -163,19 +160,18 @@ function calcmath.totex(str,mode) end -- csnames str = gsub(str,"(\\[A-Z]+)", lower) - -- trace ---~ print(str) -- report return str end +calcmath.totex = totex + function calcmath.tex(str,mode) - texsprint(tex.texcatcodes,calcmath.totex(str)) + context(totex(str)) end function calcmath.xml(id,mode) - local str = lxml.id(id).dt[1] - texsprint(tex.texcatcodes,calcmath.totex(str,mode)) + context(totex(lxml.id(id).dt[1],mode)) end -- work in progress ... lpeg variant diff --git a/tex/context/base/x-calcmath.mkiv b/tex/context/base/x-calcmath.mkiv index 0b5793a96..7dfa60e0e 100644 --- a/tex/context/base/x-calcmath.mkiv +++ b/tex/context/base/x-calcmath.mkiv @@ -15,12 +15,14 @@ \registerctxluafile{x-calcmath}{} +\def\ctxmodulecalcmath#1{\directlua\zerocount{moduledata.calcmath.#1}} + %D Interface: \unprotect -\def\inlinecalcmath #1{\mathematics{\ctxlua{moduledata.calcmath.tex("#1",1)}}} -\def\displaycalcmath#1{\startformula\ctxlua{moduledata.calcmath.tex("#1",2)}\stopformula} +\unexpanded\def\inlinecalcmath #1{\mathematics{\ctxmodulecalcmath{tex("#1",1)}}} +\unexpanded\def\displaycalcmath#1{\startformula\ctxmodulecalcmath{tex("#1",2)}\stopformula} \let\calcmath\inlinecalcmath @@ -37,24 +39,24 @@ \xmlregistersetup{xml:cam:define} % tex -> lua -> tex -> lua -> tex -% \mathematics{\ctxlua{moduledata.calcmath.xml(\!!bs\xmlflush{#1}\!!es,1)}} +% \mathematics{\ctxmodulecalcmath{xml(\!!bs\xmlflush{#1}\!!es,1)}} % tex -> lua -> tex -% \mathematics{\ctxlua{moduledata.calcmath.xml("#1",1)}}% +% \mathematics{\ctxmodulecalcmath{xml("#1",1)}}% \startxmlsetups cam:i - \mathematics{\ctxlua{moduledata.calcmath.xml("#1",1)}}% + \mathematics{\ctxmodulecalcmath{xml("#1",1)}}% \stopxmlsetups \startxmlsetups cam:d - \startformula\ctxlua{moduledata.calcmath.xml("#1",2)}\stopformula + \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula \stopxmlsetups \startxmlsetups cam:icm - \mathematics{\ctxlua{moduledata.calcmath.xml("#1",1)}} + \mathematics{\ctxmodulecalcmath{xml("#1",1)}} \stopxmlsetups \startxmlsetups cam:dcm - \startformula\ctxlua{moduledata.calcmath.xml("#1",2)}\stopformula + \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula \stopxmlsetups \protect \endinput diff --git a/tex/context/base/x-cals.lua b/tex/context/base/x-cals.lua index 5d15b4e30..0ccbaab54 100644 --- a/tex/context/base/x-cals.lua +++ b/tex/context/base/x-cals.lua @@ -13,9 +13,9 @@ local n_todimen, s_todimen = number.todimen, string.todimen -- there is room for speedups as well as cleanup (using context functions) -lxml.cals = lxml.cals or { } - -local cals = lxml.cals +local cals = { } +local moduledata = moduledata or { } +moduledata.cals = cals cals.ignore_widths = false cals.shrink_widths = false diff --git a/tex/context/base/x-cals.mkiv b/tex/context/base/x-cals.mkiv index 3e37048c9..e0d2ac11f 100644 --- a/tex/context/base/x-cals.mkiv +++ b/tex/context/base/x-cals.mkiv @@ -21,12 +21,12 @@ % \xmlsetsetup {\xmldocument} {cals:table} {*} % \stopxmlsetups % \startxmlsetups cals:table -% \ctxlua{lxml.cals.table("#1")} +% \ctxlua{moduledata.cals.table("#1")} % \stopxmlsetups % \xmlregistersetup{xml:cals:process} \startxmlsetups xml:cals:process - \xmlsetfunction {\xmldocument} {cals:table} {lxml.cals.table} + \xmlsetfunction {\xmldocument} {cals:table} {moduledata.cals.table} \stopxmlsetups \xmlregistersetup{xml:cals:process} diff --git a/tex/context/base/x-chemml.lua b/tex/context/base/x-chemml.lua new file mode 100644 index 000000000..387935c8b --- /dev/null +++ b/tex/context/base/x-chemml.lua @@ -0,0 +1,51 @@ +if not modules then modules = { } end modules ['x-chemml'] = { + version = 1.001, + comment = "companion to x-chemml.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- not yet acceptable cld + +local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub +local concat = table.concat + +local chemml = { } +local moduledata = moduledata or { } +moduledata.chemml = chemml + +function chemml.pi(id) + local str = xml.content(lxml.id(id)) + local _, class, key, value = str:match("^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*$") + if key and value then + context("\\setupCMLappearance[%s][%s=%s]",class, key, value) + end +end + +function chemml.do_graphic(id) + local t = { } + for r, d, k in xml.elements(lxml.id(id),"cml:graphic") do + t[#t+1] = xml.tostring(d[k].dt) + end + concat(concat(t,",")) +end + +function chemml.no_graphic(id) + local t = { } + for r, d, k in xml.elements(lxml.id(id),"cml:text|cml:oxidation|cml:annotation") do + local dk = d[k] + if dk.tg == "oxidation" then + t[#t+1] = format("\\chemicaloxidation{%s}{%s}{%s}",r.at.sign or "",r.at.n or 1,xml.tostring(dk.dt)) + elseif dk.tg == "annotation" then + local location = r.at.location or "r" + local caption = xml.content(xml.first(dk,"cml:caption")) + local text = xml.content(xml.first(dk,"cml:text")) + t[#t+1] = format("\\doCMLannotation{%s}{%s}{%s}",location,caption,text) + else + t[#t+1] = xml.tostring(dk.dt) or "" + end + end + context(concat(t,",")) +end + diff --git a/tex/context/base/x-chemml.mkiv b/tex/context/base/x-chemml.mkiv index 658f3a452..9ad8ed6c1 100644 --- a/tex/context/base/x-chemml.mkiv +++ b/tex/context/base/x-chemml.mkiv @@ -13,6 +13,10 @@ \writestatus{loading}{ConTeXt XML Macros / Chemistry} +\registerctxluafile{x-chemml}{} + +\def\ctxmodulechemml#1{\directlua\zerocount{moduledata.chemml.#1}} + \usemodule[pictex,chemic] % someday we will do structural fomulas in mp %D The following code assumes a load||flush approach to \XML. @@ -20,7 +24,6 @@ \unprotect \startxmlsetups xml:cml:process - \xmlstrip {\xmldocument} {cml:chem|cml:ichem|cml:dchem|cml:reaction|cml:molecule|cml:ion|cml:structure} \xmlgrab {\xmldocument} {cml:*} {*} @@ -39,16 +42,6 @@ \setupCMLappearance [ion] [\c!alternative=\v!a] -\startluacode - function lxml.cml_do_pi(id) - local str = xml.content(lxml.id(id)) - local _, class, key, value = str:match("^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*$") - if key and value then - tex.sprint(tex.ctxcatcodes,string.format("\\setupCMLappearance[%s][%s=%s]",class, key, value)) - end - end -\stopluacode - \def\doifelseCMLvariable#1#2#3% id key value {\doifelse{\xmlatt{#1}{#2}}{#3} \firstoftwoarguments @@ -57,7 +50,7 @@ \secondoftwoarguments}} \startxmlsetups cml:pi - \ctxlua{lxml.cml_do_pi(#1)} + \ctxmodulechemml{pi(#1)} \stopxmlsetups \startxmlsetups cml:chem @@ -194,38 +187,11 @@ % It makes not much sense to adapt ppchtex to accept different input. Maybe some day. -\startluacode - function lxml.cml_do_graphic(id) - local t = { } - for r, d, k in xml.elements(lxml.id(id),"cml:graphic") do - t[#t+1] = xml.tostring(d[k].dt) - end - tex.sprint(tex.ctxcatcodes,table.concat(t,",")) - end - function lxml.cml_no_graphic(id) - local t = { } - for r, d, k in xml.elements(lxml.id(id),"cml:text|cml:oxidation|cml:annotation") do - local dk = d[k] - if dk.tg == "oxidation" then - t[#t+1] = string.format("\\chemicaloxidation{%s}{%s}{%s}",r.at.sign or "",r.at.n or 1,xml.tostring(dk.dt)) - elseif dk.tg == "annotation" then - local location = r.at.location or "r" - local caption = xml.content(xml.first(dk,"cml:caption")) - local text = xml.content(xml.first(dk,"cml:text")) - t[#t+1] = string.format("\\doCMLannotation{%s}{%s}{%s}",location,caption,text) - else - t[#t+1] = xml.tostring(dk.dt) or "" - end - end - tex.sprint(tex.ctxcatcodes,table.concat(t,",")) - end -\stopluacode - \startxmlsetups cml:component \expanded { \chemical - [\ctxlua{lxml.cml_do_graphic("#1")}] - [\ctxlua{lxml.cml_no_graphic("#1")}] + [\ctxmodulechemml{do_graphic("#1")}] + [\ctxmodulechemml{no_graphic("#1")}] } \stopxmlsetups diff --git a/tex/context/base/x-css.lua b/tex/context/base/x-css.lua new file mode 100644 index 000000000..da21fd21b --- /dev/null +++ b/tex/context/base/x-css.lua @@ -0,0 +1,92 @@ +if not modules then modules = { } end modules ['lxml-css'] = { + version = 1.001, + comment = "companion to lxml-css.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tonumber = tonumber +local P, S, C, R, Cb, Cg, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns + +local css = { } +local moduledata = moduledata or { } +moduledata.css = css + +local dimenfactors = number.dimenfactors + +local bpf, cmf, mmf, inf = 1/dimenfactors.bp, 1/dimenfactors.cm, 1/dimenfactors.mm, 1/dimenfactors["in"] + +local validdimen = Cg(lpegpatterns.number,'a') * ( + Cb('a') * P("pt") / function(s) return tonumber(s) * bpf end + + Cb('a') * P("cm") / function(s) return tonumber(s) * cmf end + + Cb('a') * P("mm") / function(s) return tonumber(s) * mmf end + + Cb('a') * P("in") / function(s) return tonumber(s) * inf end + + Cb('a') * P("px") * Carg(1) / function(s,pxf) return tonumber(s) * pxf end + + Cb('a') * P("%") * Carg(2) / function(s,pcf) return tonumber(s) * pcf end + + Cb('a') * P("ex") * Carg(3) / function(s,exf) return tonumber(s) * exf end + + Cb('a') * P("em") * Carg(4) / function(s,emf) return tonumber(s) * emf end + + Cb('a') * Carg(1) / function(s,pxf) return tonumber(s) * pxf end + ) + +local pattern = (validdimen * lpegpatterns.whitespace^0)^1 + +-- todo: default if "" + +local function padding(str,pixel,percent,exheight,emwidth) + local top, bottom, left, right = lpegmatch(pattern,str,1,pixel,percent,exheight,emwidth) + if not bottom then + bottom, left, right = top, top, top + elseif not left then + bottom, left, right = top, bottom, bottom + elseif not right then + bottom, left, right = left, bottom, bottom + end + return top, bottom, left, right +end + +css.padding = padding + +-- local hsize = 655360*100 +-- local exheight = 65536*4 +-- local emwidth = 65536*10 +-- local pixel = emwidth/100 +-- +-- print(padding("10px",pixel,hsize,exheight,emwidth)) +-- print(padding("10px 20px",pixel,hsize,exheight,emwidth)) +-- print(padding("10px 20px 30px",pixel,hsize,exheight,emwidth)) +-- print(padding("10px 20px 30px 40px",pixel,hsize,exheight,emwidth)) +-- +-- print(padding("10%",pixel,hsize,exheight,emwidth)) +-- print(padding("10% 20%",pixel,hsize,exheight,emwidth)) +-- print(padding("10% 20% 30%",pixel,hsize,exheight,emwidth)) +-- print(padding("10% 20% 30% 40%",pixel,hsize,exheight,emwidth)) +-- +-- print(padding("10",pixel,hsize,exheight,emwidth)) +-- print(padding("10 20",pixel,hsize,exheight,emwidth)) +-- print(padding("10 20 30",pixel,hsize,exheight,emwidth)) +-- print(padding("10 20 30 40",pixel,hsize,exheight,emwidth)) +-- +-- print(padding("10pt",pixel,hsize,exheight,emwidth)) +-- print(padding("10pt 20pt",pixel,hsize,exheight,emwidth)) +-- print(padding("10pt 20pt 30pt",pixel,hsize,exheight,emwidth)) +-- print(padding("10pt 20pt 30pt 40pt",pixel,hsize,exheight,emwidth)) + +local fontidentifiers = fonts.identifiers +local currentfont = font.current +local texdimen = tex.dimen + +local function padding(str) + local fnt = fontidentifiers[currentfont()] + local exheight = fnt.ex_height + local emwidth = fnt.quad + local hsize = texdimen.hsize/100 + local pixel = emwidth/100 + return padding(str,pixel,hsize,exheight,emwidth) +end + +--~ function css.simplepadding(str) +--~ context("%ssp",padding(str,pixel,hsize,exheight,emwidth)) +--~ end + diff --git a/tex/context/base/x-css.mkiv b/tex/context/base/x-css.mkiv new file mode 100644 index 000000000..cc7f8682a --- /dev/null +++ b/tex/context/base/x-css.mkiv @@ -0,0 +1,39 @@ +%D \module +%D [ file=x-css, +%D version=2010.01.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Css Helpers, +%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. + +\registerctxluafile{x-css}{} + +\def\ctxmodulecss#1{\directlua\zerocount{moduledata.css.#1}} + +% No stable interface yet. + +% \edef\CellPadding{\xmlatt{#1}{cellpadding}} +% \ifx\CellPadding\empty +% \edef\CellPadding{.25ex} +% \else +% \edef\CellPadding{\cssgetsinglepadding{\xmlatt{#1}{cellpadding}}} +% \fi + +% \starttexdefinition cssgetsinglepadding #1 +% \ctxlua { +% context((moduledata.css.padding( +% "#1", +% \number\dimexpr0.1ex, +% \number\dimexpr0.01\hsize, +% \number\dimexpr1ex, +% \number\dimexpr1em +% ))) % returns 4 values therefore () +% }sp +% \stoptexdefinition + +\endinput diff --git a/tex/context/base/x-dir-05.mkiv b/tex/context/base/x-dir-05.mkiv index c29c9ea2a..120f725ca 100644 --- a/tex/context/base/x-dir-05.mkiv +++ b/tex/context/base/x-dir-05.mkiv @@ -22,6 +22,8 @@ % \savefilestate[zip-latest][context/latest/cont-#2.zip]% +% TODO: move to module namespace + \startluacode local filestates = { } function commands.savefilestate(tag,name) diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua index 99ea6c34b..654925f7a 100644 --- a/tex/context/base/x-mathml.lua +++ b/tex/context/base/x-mathml.lua @@ -16,7 +16,9 @@ local lxmltext, getid = lxml.text, lxml.getid local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local lpegmatch = lpeg.match -lxml.mml = lxml.mml or { } +local mathml = { } +local moduledata = moduledata = { } +moduledata.mathml = mathml -- an alternative is to remap to private codes, where we can have -- different properties .. to be done; this will move and become @@ -445,11 +447,11 @@ function xml.functions.remapopenmath(e) e.rn = "mml" end -function lxml.mml.checked_operator(str) +function mathml.checked_operator(str) texsprint(ctxcatcodes,(utfgsub(str,".",o_replacements))) end -function lxml.mml.stripped(str) +function mathml.stripped(str) tex.sprint(ctxcatcodes,str:strip()) end @@ -457,7 +459,7 @@ function characters.remapentity(chr,slot) -- brrrrrr texsprint(format("{\\catcode%s=13\\xdef%s{\\string%s}}",slot,utfchar(slot),chr)) end -function lxml.mml.mn(id,pattern) +function mathml.mn(id,pattern) -- maybe at some point we need to interpret the number, but -- currently we assume an upright font local str = xmlcontent(getid(id)) or "" @@ -465,12 +467,12 @@ function lxml.mml.mn(id,pattern) texsprint(ctxcatcodes,(gsub(str,".",n_replacements))) end -function lxml.mml.mo(id) +function mathml.mo(id) local str = xmlcontent(getid(id)) or "" texsprint(ctxcatcodes,(utfgsub(str,".",o_replacements))) end -function lxml.mml.mi(id) +function mathml.mi(id) local str = xmlcontent(getid(id)) or "" -- str = gsub(str,"^%s*(.-)%s*$","%1") local rep = i_replacements[str] @@ -481,7 +483,7 @@ function lxml.mml.mi(id) end end -function lxml.mml.mfenced(id) -- multiple separators +function mathml.mfenced(id) -- multiple separators id = getid(id) local left, right, separators = id.at.open or "(", id.at.close or ")", id.at.separators or "," local l, r = l_replacements[left], r_replacements[right] @@ -554,7 +556,7 @@ local function flush(e,tag,toggle) return not toggle end -function lxml.mml.mmultiscripts(id) +function mathml.mmultiscripts(id) local done, toggle = false, false for e in lxml.collected(id,"/*") do local tag = e.tg @@ -601,7 +603,7 @@ local frametypes = { -- crazy element ... should be a proper structure instead of such a mess -function lxml.mml.mcolumn(root) +function mathml.mcolumn(root) root = getid(root) local matrix, numbers = { }, 0 local function collect(m,e) @@ -697,7 +699,7 @@ end local spacesplitter = lpeg.Ct(lpeg.splitat(" ")) -function lxml.mml.mtable(root) +function mathml.mtable(root) -- todo: align, rowspacing, columnspacing, rowlines, columnlines root = getid(root) local at = root.at @@ -755,7 +757,7 @@ function lxml.mml.mtable(root) --~ context.eTABLE() end -function lxml.mml.csymbol(root) +function mathml.csymbol(root) root = getid(root) local at = root.at local encoding = at.encoding or "" @@ -767,7 +769,7 @@ function lxml.mml.csymbol(root) texsprint(ctxcatcodes,"\\mmlapplycsymbol{",full,"}{",base,"}{",encoding,"}{",text,"}") end -function lxml.mml.menclosepattern(root) +function mathml.menclosepattern(root) root = getid(root) local a = root.at.notation if a and a ~= "" then diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv index 50092ef94..44e2b7432 100644 --- a/tex/context/base/x-mathml.mkiv +++ b/tex/context/base/x-mathml.mkiv @@ -23,6 +23,8 @@ \registerctxluafile{x-mathml}{} +\def\ctxmodulemathml#1{\directlua\zerocount{moduledata.mathml.#1}} + \startxmlsetups xml:mml:define \xmlsetsetup{\xmldocument} {(formula|subformula)} {mml:formula} \xmlfilter {\xmldocument} {omt:*/function(remapopenmath)} @@ -465,7 +467,7 @@ \stoptexdefinition \startxmlsetups mml:csymbol - \ctxlua{lxml.mml.csymbol("#1")} + \ctxmodulemathml{csymbol("#1")} \stopxmlsetups \startxmlsetups mml:csymbol:cdots @@ -1814,12 +1816,12 @@ % setups \startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground - \ctxlua{lxml.mml.mi("#1")} + \ctxmodulemathml{mi("#1")} \stopxmlsetups \startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground \begingroup - \mr \ctxlua{lxml.mml.mn("#1")}% no \hbox, would be ok for . , but spoils rest + \mr \ctxmodulemathml{mn("#1")}% no \hbox, would be ok for . , but spoils rest \endgroup \stopxmlsetups @@ -1830,7 +1832,7 @@ \startxmlsetups mml:mo \doif {\xmlatt{#1}{maxsize}} {1} {\settrue\mmlignoredelimiter} \doif {\xmlatt{#1}{stretchy}} {false} {\settrue\mmlignoredelimiter} - \ctxlua{lxml.mml.mo("#1")} + \ctxmodulemathml{mo("#1")} \setfalse\mmlignoredelimiter \stopxmlsetups @@ -1838,7 +1840,7 @@ \def\MMLleft {\left }% weird \def\MMLright {\right} \def\MMLmiddle{\middle} - \ctxlua{lxml.mml.mfenced("#1")} + \ctxmodulemathml{mfenced("#1")} \stopxmlsetups \defineoverlay [mml:enclose:box] [\useMPgraphic{mml:enclose:box}] @@ -1900,7 +1902,7 @@ \stopuseMPgraphic \startxmlsetups mml:menclose - \edef\mmlmenclosenotation{\ctxlua{lxml.mml.menclosepattern("#1")}} + \edef\mmlmenclosenotation{\ctxmodulemathml{menclosepattern("#1")}} \ifx\mmlmenclosenotation\empty \xmlflush{#1} \else @@ -1991,7 +1993,7 @@ \domathtext { \applymmlsometext{#1}{ \doifelse\MMLscriptsalternative\v!a { - %\ctxlua{lxml.mml.stripped(\!!bs\xmlflush{#1}\!!es)} + %\ctxmodulemathml{stripped(\!!bs\xmlflush{#1}\!!es)} \ignorespaces \xmlflush{#1} \unskip @@ -2164,11 +2166,11 @@ % tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd) \startxmlsetups mml:mtable % some more attributes need to be supported - \vcenter{\ctxlua{lxml.mml.mtable("#1")}} + \vcenter{\ctxmodulemathml{mtable("#1")}} \stopxmlsetups \startxmlsetups mml:mcolumn - \ctxlua{lxml.mml.mcolumn("#1")} + \ctxmodulemathml{mcolumn("#1")} \stopxmlsetups \def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox} @@ -2249,7 +2251,7 @@ \startxmlsetups mml:mprescripts \stopxmlsetups \startxmlsetups mml:mmultiscripts - \ctxlua{lxml.mml.mmultiscripts("#1")} + \ctxmodulemathml{mmultiscripts("#1")} \stopxmlsetups % goodie diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 052224006..72a377434 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 : 01/26/11 11:02:23 +-- merge date : 01/31/11 16:59:33 do -- begin closure to overcome local limits and interference @@ -417,6 +417,14 @@ function lpeg.keeper(str) end end +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end + +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + -- Just for fun I looked at the used bytecode and -- p = (p and p + pp) or pp gets one more (testset). @@ -2443,6 +2451,14 @@ function resolvers.findbinfile(name,kind) return resolvers.findfile(name,(kind and remapper[kind]) or kind) end +function resolvers.resolve(s) + return s +end + +function resolvers.unresolve(s) + return s +end + -- Caches ... I will make a real stupid version some day when I'm in the -- mood. After all, the generic code does not need the more advanced -- ConTeXt features. Cached data is not shared between ConTeXt and other @@ -4160,6 +4176,7 @@ function tfm.checkedfilename(metadata,whatever) if not foundfilename then local askedfilename = metadata.filename or "" if askedfilename ~= "" then + askedfilename = resolvers.resolve(askedfilename) -- no shortcut foundfilename = resolvers.findbinfile(askedfilename,"") or "" if foundfilename == "" then report_define("source file '%s' is not found",askedfilename) @@ -6132,7 +6149,7 @@ end actions["prepare tables"] = function(data,filename,raw) local luatex = { - filename = filename, + filename = resolvers.unresolve(filename), -- no shortcut version = otf.version, creator = "context mkiv", } @@ -11312,6 +11329,7 @@ if not modules then modules = { } end modules ['font-map'] = { local allocate = utilities.storage.allocate +fonts = fonts or { } fonts.enc = fonts.enc or { } local enc = fonts.enc local agl = { } @@ -11460,7 +11478,7 @@ agl.names = allocate { -- to name [0x00AC] = "logicalnot", [0x00AD] = "softhyphen", [0x00AE] = "registered", - [0x00AF] = "overscore", + [0x00AF] = "macron", [0x00B0] = "degree", [0x00B1] = "plusminus", [0x00B2] = "twosuperior", @@ -14998,9 +15016,267 @@ agl.names = allocate { -- to name [0xFFE3] = "macronmonospace", [0xFFE5] = "yenmonospace", [0xFFE6] = "wonmonospace", + + -- extra entries taken from char-def: + + [0x0020] = "space", + [0x007C] = "bar", + [0x00B5] = "mu", + [0x0110] = "Dcroat", + [0x0111] = "dcroat", + [0x013F] = "Ldot", + [0x0140] = "ldot", + [0x0149] = "napostrophe", + [0x017F] = "longs", + [0x01FE] = "Oslashacute", + [0x01FF] = "oslashacute", + [0x02BC] = "afii57929", + [0x02BD] = "afii64937", + [0x0309] = "hookabovecomb", + [0x03C2] = "sigma1", + [0x03D1] = "theta1", + [0x03D2] = "Upsilon1", + [0x03D5] = "phi1", + [0x03D6] = "omega1", + [0x0431] = "afii10066", + [0x0432] = "afii10067", + [0x0433] = "afii10068", + [0x0434] = "afii10069", + [0x0435] = "afii10070", + [0x0436] = "afii10072", + [0x0437] = "afii10073", + [0x0438] = "afii10074", + [0x0439] = "afii10075", + [0x043A] = "afii10076", + [0x043B] = "afii10077", + [0x043C] = "afii10078", + [0x043D] = "afii10079", + [0x043E] = "afii10080", + [0x043F] = "afii10081", + [0x0440] = "afii10082", + [0x0441] = "afii10083", + [0x0442] = "afii10084", + [0x0443] = "afii10085", + [0x0444] = "afii10086", + [0x0445] = "afii10087", + [0x0446] = "afii10088", + [0x0447] = "afii10089", + [0x0448] = "afii10090", + [0x0449] = "afii10091", + [0x044A] = "afii10092", + [0x044B] = "afii10093", + [0x044C] = "afii10094", + [0x044D] = "afii10095", + [0x044E] = "afii10096", + [0x044F] = "afii10097", + [0x0451] = "afii10071", + [0x0452] = "afii10099", + [0x0453] = "afii10100", + [0x0454] = "afii10101", + [0x0455] = "afii10102", + [0x0456] = "afii10103", + [0x0457] = "afii10104", + [0x0458] = "afii10105", + [0x0459] = "afii10106", + [0x045A] = "afii10107", + [0x045B] = "afii10108", + [0x045C] = "afii10109", + [0x045E] = "afii10110", + [0x045F] = "afii10193", + [0x0463] = "afii10194", + [0x0473] = "afii10195", + [0x0475] = "afii10196", + [0x0491] = "afii10098", + [0x04D9] = "afii10846", + [0x05B0] = "afii57799", + [0x05B1] = "afii57801", + [0x05B2] = "afii57800", + [0x05B3] = "afii57802", + [0x05B4] = "afii57793", + [0x05B5] = "afii57794", + [0x05B6] = "afii57795", + [0x05B7] = "afii57798", + [0x05B8] = "afii57797", + [0x05B9] = "afii57806", + [0x05BB] = "afii57796", + [0x05BC] = "afii57807", + [0x05BD] = "afii57839", + [0x05BE] = "afii57645", + [0x05BF] = "afii57841", + [0x05C0] = "afii57842", + [0x05C1] = "afii57804", + [0x05C2] = "afii57803", + [0x05C3] = "afii57658", + [0x05D0] = "afii57664", + [0x05D1] = "afii57665", + [0x05D2] = "afii57666", + [0x05D3] = "afii57667", + [0x05D4] = "afii57668", + [0x05D5] = "afii57669", + [0x05D6] = "afii57670", + [0x05D7] = "afii57671", + [0x05D8] = "afii57672", + [0x05D9] = "afii57673", + [0x05DA] = "afii57674", + [0x05DB] = "afii57675", + [0x05DC] = "afii57676", + [0x05DD] = "afii57677", + [0x05DE] = "afii57678", + [0x05DF] = "afii57679", + [0x05E0] = "afii57680", + [0x05E1] = "afii57681", + [0x05E2] = "afii57682", + [0x05E3] = "afii57683", + [0x05E4] = "afii57684", + [0x05E5] = "afii57685", + [0x05E6] = "afii57686", + [0x05E7] = "afii57687", + [0x05E8] = "afii57688", + [0x05E9] = "afii57689", + [0x05EA] = "afii57690", + [0x05F0] = "afii57716", + [0x05F1] = "afii57717", + [0x05F2] = "afii57718", + [0x060C] = "afii57388", + [0x061B] = "afii57403", + [0x061F] = "afii57407", + [0x0621] = "afii57409", + [0x0622] = "afii57410", + [0x0623] = "afii57411", + [0x0624] = "afii57412", + [0x0625] = "afii57413", + [0x0626] = "afii57414", + [0x0627] = "afii57415", + [0x0628] = "afii57416", + [0x0629] = "afii57417", + [0x062A] = "afii57418", + [0x062B] = "afii57419", + [0x062C] = "afii57420", + [0x062D] = "afii57421", + [0x062E] = "afii57422", + [0x062F] = "afii57423", + [0x0630] = "afii57424", + [0x0631] = "afii57425", + [0x0632] = "afii57426", + [0x0633] = "afii57427", + [0x0634] = "afii57428", + [0x0635] = "afii57429", + [0x0636] = "afii57430", + [0x0637] = "afii57431", + [0x0638] = "afii57432", + [0x0639] = "afii57433", + [0x063A] = "afii57434", + [0x0640] = "afii57440", + [0x0641] = "afii57441", + [0x0642] = "afii57442", + [0x0643] = "afii57443", + [0x0644] = "afii57444", + [0x0645] = "afii57445", + [0x0646] = "afii57446", + [0x0647] = "afii57470", + [0x0648] = "afii57448", + [0x0649] = "afii57449", + [0x064A] = "afii57450", + [0x064B] = "afii57451", + [0x064C] = "afii57452", + [0x064D] = "afii57453", + [0x064E] = "afii57454", + [0x064F] = "afii57455", + [0x0650] = "afii57456", + [0x0651] = "afii57457", + [0x0652] = "afii57458", + [0x0660] = "afii57392", + [0x0661] = "afii57393", + [0x0662] = "afii57394", + [0x0663] = "afii57395", + [0x0664] = "afii57396", + [0x0665] = "afii57397", + [0x0666] = "afii57398", + [0x0667] = "afii57399", + [0x0668] = "afii57400", + [0x0669] = "afii57401", + [0x066A] = "afii57381", + [0x066D] = "afii63167", + [0x0679] = "afii57511", + [0x067E] = "afii57506", + [0x0686] = "afii57507", + [0x0688] = "afii57512", + [0x0691] = "afii57513", + [0x0698] = "afii57508", + [0x06A4] = "afii57505", + [0x06AF] = "afii57509", + [0x06BA] = "afii57514", + [0x06D2] = "afii57519", + [0x200C] = "afii61664", + [0x2015] = "afii208", + [0x2025] = "twodotenleader", + [0x20A1] = "colonmonetary", + [0x20AA] = "afii57636", + [0x20AC] = "Euro", + [0x2105] = "afii61248", + [0x2113] = "afii61289", + [0x2116] = "afii61352", + [0x21A8] = "arrowupdnbse", + [0x21D0] = "arrowdblleft", + [0x21D2] = "arrowdblright", + [0x21D4] = "arrowdblboth", + [0x2203] = "existential", + [0x2206] = "Delta", + [0x2207] = "gradient", + [0x2209] = "notelement", + [0x221F] = "orthogonal", + [0x223C] = "similar", + [0x2282] = "propersubset", + [0x2283] = "propersuperset", + [0x2286] = "reflexsubset", + [0x2287] = "reflexsuperset", + [0x2295] = "circleplus", + [0x2297] = "circlemultiply", + [0x250C] = "SF10000", + [0x2510] = "SF30000", + [0x2514] = "SF20000", + [0x2518] = "SF40000", + [0x251C] = "SF80000", + [0x2524] = "SF90000", + [0x252C] = "SF60000", + [0x2534] = "SF70000", + [0x253C] = "SF50000", + [0x2591] = "ltshade", + [0x2592] = "shade", + [0x2593] = "dkshade", + [0x25A1] = "H22073", + [0x25AA] = "H18543", + [0x25AB] = "H18551", + [0x25CB] = "circle", + [0x25CF] = "H18533", + [0x25D9] = "invcircle", + [0x25E6] = "openbullet", + [0x263A] = "smileface", + [0x2640] = "female", + [0x2642] = "male", + [0x2660] = "spade", + [0x2663] = "club", + [0x2665] = "heart", + } -agl.unicodes = allocate(table.swapped(agl.names)) -- to unicode +local unicodes = allocate(table.swapped(agl.names)) -- to unicode + +agl.unicodes = unicodes + +-- dofile("char-def.lua") +-- +-- for k,v in table.sortedpairs(characters.data) do +-- if v.adobename then +-- if unicodes[v.adobename] ~= k then +-- if not unicodes[k] then +-- print(string.format('[0x%04X] = "%s",',k,v.adobename)) +-- else +-- -- print(string.format('unicodes[%s] = %s,',v.adobename,k)) +-- end +-- end +-- end +-- end end -- closure diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua index 072f06980..b420f485c 100644 --- a/web2c/contextcnf.lua +++ b/web2c/contextcnf.lua @@ -11,21 +11,43 @@ return { variables = { - TEXMFCACHE = "$SELFAUTOPARENT/texmf-cache", + -- The following variable is predefined (but can be overloaded) and in + -- most cases you can leve this one untouched. The built-in definition + -- permits relocation of the tree. + -- + -- TEXMFCNF = "{selfautodir:,selfautoparent:}{,{/share,}/texmf{-local,}/web2c}" + -- + -- more readable than "selfautoparent:{/texmf{-local,}{,/web2c},}}" is: + -- + -- TEXMFCNF = { + -- "selfautoparent:/texmf-local", + -- "selfautoparent:/texmf-local/web2c", + -- "selfautoparent:/texmf", + -- "selfautoparent:/texmf/web2c", + -- "selfautoparent:", + -- } + + -- We have only one cache path but there can be more. The first writable one + -- will be chose but there can be more readable paths. - TEXMFOS = "$SELFAUTODIR", - TEXMFSYSTEM = "$SELFAUTOPARENT/texmf-$SELFAUTOSYSTEM", - TEXMFMAIN = "$SELFAUTOPARENT/texmf", - TEXMFCONTEXT = "$SELFAUTOPARENT/texmf-context", - TEXMFLOCAL = "$SELFAUTOPARENT/texmf-local", - TEXMFFONTS = "$SELFAUTOPARENT/texmf-fonts", - TEXMFPROJECT = "$SELFAUTOPARENT/texmf-project", + TEXMFCACHE = "$SELFAUTOPARENT/texmf-cache", -- I don't like this texmf under home and texmf-home would make more -- sense. One never knows what installers put under texmf anywhere and - -- sorting out problems will be a pain. - - TEXMFHOME = "$HOME/texmf", -- "tree:///$HOME/texmf + -- sorting out problems will be a pain. But on the other hand ... home + -- mess is normally under the users own responsibility. + -- + -- By using prefixes we don't get expanded paths in the cache __path__ + -- entry. This makes the tex root relocatable. + + TEXMFOS = "selfautodir:", + TEXMFSYSTEM = "selfautoparent:texmf-$SELFAUTOSYSTEM", + TEXMFMAIN = "selfautoparent:texmf", + TEXMFCONTEXT = "selfautoparent:texmf-context", + TEXMFLOCAL = "selfautoparent:texmf-local", + TEXMFFONTS = "selfautoparent:texmf-fonts", + TEXMFPROJECT = "selfautoparent:texmf-project", + TEXMFHOME = "home:texmf", -- We need texmfos for a few rare files but as I have a few more bin trees -- a hack is needed. Maybe other users also have texmf-platform-new trees. @@ -46,22 +68,22 @@ return { OFMFONTS = ".;$TEXMF/fonts/{data,ofm,tfm}//", OVFFONTS = ".;$TEXMF/fonts/{data,ovf,vf}//", - TEXINPUTS = ".;$TEXMF/tex/{context,plain/base,generic}//", - MPINPUTS = ".;$TEXMF/metapost/{context,base,}//", + TEXINPUTS = ".;{$CTXDEVTXPATH};$TEXMF/tex/{context,plain/base,generic}//", + MPINPUTS = ".;{$CTXDEVMPPATH};$TEXMF/metapost/{context,base,}//", -- In the next variable the inputs path will go away. - TEXMFSCRIPTS = ".;$TEXMF/scripts/context/{lua,ruby,python,perl}//;$TEXINPUTS", - PERLINPUTS = ".;$TEXMF/scripts/context/perl", - PYTHONINPUTS = ".;$TEXMF/scripts/context/python", - RUBYINPUTS = ".;$TEXMF/scripts/context/ruby", - LUAINPUTS = ".;$TEXINPUTS;$TEXMF/scripts/context/lua//", + TEXMFSCRIPTS = ".;$CTXDEVLUPATH;$CTXDEVRBPATH;$CTXDEVPLPATH;$TEXMF/scripts/context/{lua,ruby,python,perl}//;$TEXINPUTS", + PERLINPUTS = ".;$CTXDEVPLPATH;$TEXMF/scripts/context/perl", + PYTHONINPUTS = ".;$CTXDEVPYPATH;$TEXMF/scripts/context/python", + RUBYINPUTS = ".;$CTXDEVRBPATH;$TEXMF/scripts/context/ruby", + LUAINPUTS = ".;$CTXDEVLUPATH;$TEXINPUTS;$TEXMF/scripts/context/lua//", CLUAINPUTS = ".;$SELFAUTOLOC/lib/{$progname,$engine,}/lua//", -- Not really used by MkIV so they might go away. - BIBINPUTS = ".;$TEXMF/bibtex/bib//", - BSTINPUTS = ".;$TEXMF/bibtex/bst//", + BIBINPUTS = ".;{$CTXDEVTXPATH};$TEXMF/bibtex/bib//", + BSTINPUTS = ".;{$CTXDEVTXPATH};$TEXMF/bibtex/bst//", -- Experimental @@ -78,6 +100,18 @@ return { FONTCONFIG_PATH = "$TEXMFSYSTEM/fonts/conf", FC_CACHEDIR = "$TEXMFSYSTEM/fonts/cache", -- not needed + -- The io modes are similar to the traditional ones. Possible values + -- are all, paranoid and restricted. + + output_mode = "restricted", + input_mode = "any", + + -- The following variable is under consideration. We do have protection + -- mechanims but it's not enabled by default. + + command_mode = "any", -- any none list + command_list = "mtxrun, convert, inkscape, gs, imagemagick, curl, bibtex, pstoedit", + }, -- We have a few reserved subtables. These control runtime behaviour. The |