From 3a75fc96a5e7607afbead86fd9a3a9a8831494aa Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sun, 13 Dec 2009 23:27:00 +0100 Subject: beta 2009.12.13 23:27 --- context/data/scite/context.properties | 2 +- scripts/context/lua/luatools.lua | 164 +++++++++----- scripts/context/lua/mtx-context.lua | 44 ++-- scripts/context/lua/mtx-fonts.lua | 20 +- scripts/context/lua/mtx-server-ctx-fonttest.lua | 244 ++++++++++++--------- scripts/context/lua/mtx-server-ctx-help.lua | 64 +++--- scripts/context/lua/mtx-server-ctx-startup.lua | 32 +-- scripts/context/lua/mtx-timing.lua | 41 ++-- scripts/context/lua/mtx-tools.lua | 89 +++++++- scripts/context/lua/mtx-update.lua | 6 +- scripts/context/lua/mtx-watch.lua | 266 ++++++++++++----------- scripts/context/lua/mtxrun.lua | 272 ++++++++++++++++++------ scripts/context/stubs/mswin/luatools.lua | 164 +++++++++----- scripts/context/stubs/mswin/mtxrun.lua | 272 ++++++++++++++++++------ scripts/context/stubs/unix/luatools | 164 +++++++++----- scripts/context/stubs/unix/mtxrun | 272 ++++++++++++++++++------ tex/context/base/attr-ini.mkiv | 1 + tex/context/base/bibl-tra.mkiv | 28 ++- tex/context/base/colo-ini.mkiv | 19 ++ tex/context/base/cont-new.mkiv | 2 + tex/context/base/cont-new.tex | 2 +- tex/context/base/context-base.lmx | 67 ++++-- tex/context/base/context.mkiv | 4 +- tex/context/base/context.tex | 2 +- tex/context/base/core-job.mkiv | 3 +- tex/context/base/data-lua.lua | 84 +++++++- tex/context/base/data-pre.lua | 10 + tex/context/base/data-res.lua | 9 +- tex/context/base/data-tmf.lua | 2 +- tex/context/base/font-syn.lua | 38 +++- tex/context/base/grph-inc.lua | 1 + tex/context/base/l-dir.lua | 29 +++ tex/context/base/l-lpeg.lua | 2 + tex/context/base/l-os.lua | 111 +++++----- tex/context/base/l-string.lua | 14 ++ tex/context/base/l-unicode.lua | 25 ++- tex/context/base/l-xml.lua | 12 +- tex/context/base/lpdf-ini.mkiv | 9 + tex/context/base/lxml-mis.lua | 2 +- tex/context/base/lxml-tex.lua | 11 +- tex/context/base/math-dim.lua | 5 +- tex/context/base/node-rul.mkiv | 13 +- tex/context/base/node-tra.lua | 11 +- tex/context/base/page-set.mkii | 7 +- tex/context/base/page-set.mkiv | 6 +- tex/context/base/spac-hor.mkiv | 2 +- tex/context/base/strc-pag.mkiv | 4 + tex/context/base/strc-ref.lua | 21 +- tex/context/base/strc-ref.mkiv | 21 +- tex/context/base/syst-ini.tex | 4 +- tex/context/base/trac-deb.lua | 53 ++--- tex/context/base/trac-lmx.lua | 258 +++++++++++++--------- tex/context/base/trac-tim.lua | 58 +++-- tex/context/base/typo-spa.lua | 2 +- tex/context/base/verb-eif.mkii | 2 +- tex/context/base/verb-ini.mkii | 25 +-- tex/context/base/verb-js.mkii | 2 +- tex/context/base/verb-jv.mkii | 2 +- tex/context/base/verb-pas.mkii | 2 +- tex/context/base/verb-raw.mkii | 6 +- tex/context/base/verb-sql.mkii | 2 +- tex/context/base/x-dir-05.mkii | 51 +++++ tex/context/base/x-dir-05.mkiv | 72 +++++++ tex/context/interface/cont-cs.xml | 5 + tex/context/interface/cont-de.xml | 5 + tex/context/interface/cont-en.xml | 5 + tex/context/interface/cont-fr.xml | 5 + tex/context/interface/cont-it.xml | 5 + tex/context/interface/cont-nl.xml | 5 + tex/context/interface/cont-pe.xml | 5 + tex/context/interface/cont-ro.xml | 5 + tex/generic/context/luatex-fonts-merged.lua | 18 +- 72 files changed, 2216 insertions(+), 1074 deletions(-) create mode 100644 tex/context/base/x-dir-05.mkii create mode 100644 tex/context/base/x-dir-05.mkiv diff --git a/context/data/scite/context.properties b/context/data/scite/context.properties index c75d1227e..13fa079c0 100644 --- a/context/data/scite/context.properties +++ b/context/data/scite/context.properties @@ -115,7 +115,7 @@ name.metafun.mptopdf=$(name.context.mtxrun) --script mptopdf # if needed one can set MTX_SERVER_ROOT to the root of the documentation if PLAT_WIN - name.context.wwwserver=cmd /c start /min "Context Documentation" $(name.context.mtxrun) --script server --start + name.context.wwwserver=cmd /c start /min "Context Documentation" $(name.context.mtxrun) --script server --auto if PLAT_GTK name.context.wwwserver=$(name.context.mtxrun) --script server --start > ~/context-wwwserver.log & diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua index 6feb7a9c5..06e2a1bfc 100644 --- a/scripts/context/lua/luatools.lua +++ b/scripts/context/lua/luatools.lua @@ -233,6 +233,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -295,6 +296,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1756,59 +1770,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2343,6 +2352,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -3166,9 +3204,9 @@ function aux.settings_to_hash_strict(str,existing) end end -local seperator = comma * space^0 +local separator = comma * space^0 local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(seperator*value)^0) +local pattern = lpeg.Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored @@ -3187,7 +3225,7 @@ local function set(t,v) end local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(seperator*value)^0 * lpeg.Carg(1) +local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) return pattern:match(str, nil, t) @@ -3238,6 +3276,13 @@ function aux.settings_to_set(str,t) return t end +local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace +local pattern = lpeg.Ct((space + value)^0) + +function aux.arguments_to_table(str) + return pattern:match(str) +end + -- temporary here function aux.getparameters(self,class,parentclass,settings) @@ -4068,7 +4113,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['luat-log'] = { +if not modules then modules = { } end modules ['trac-log'] = { version = 1.001, comment = "companion to trac-log.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4345,8 +4390,12 @@ end logs.simpleline = logs.reportline -function logs.help(message,option) +function logs.reportbanner() -- for scripts too logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() logs.reportline() logs.reportlines(message) local moreinfo = logs.moreinfo or "" @@ -4509,6 +4558,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -5728,9 +5782,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 40ab67eff..9ce164ab3 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -1390,27 +1390,36 @@ logs.extendbanner("ConTeXt Process Management 0.51",true) messages.help = [[ --run process (one or more) files (default action) --make create context formats ---generate generate file database etc. ---ctx=name use ctx file ---version report installed context version + +--ctx=name use ctx file (process management specification) +--interface use specified user interface (default: en) + +--autopdf close pdf file in viewer and start pdf viewer afterwards +--purge(all) purge files either or not after a run (--pattern=...) + +--usemodule=list load the given module or style, normally part o fthe distribution +--environment=list load the given environment file first (document styles) +--mode=list enable given the modes (conditional processing in styles) +--path=list also consult the given paths when files are looked for +--arguments=list set variables that can be consulted during a run (key/value pairs) +--randomseed=number set the randomseed +--result=name rename the resulting output to the given name +--trackers=list show/set tracker variables +--directives=list show/set directive variables + --forcexml force xml stub (optional flag: --mkii) --forcecld force cld (context lua document) stub ---autopdf close pdf file in viewer and start pdf viewer afterwards ---once only one run ---purge(all) purge files (--pattern=...) ---result=name rename result to given name ---arrange run extra arrange pass ---noarrange ignore arrange commands in the file + +--arrange run extra imposition pass, given that the style sets up imposition +--noarrange ignore imposition specifications in the style + +--once only run once (no multipass data file is produced) --batchmode run without stopping and don't show messages on the console --nonstopmode run without stopping ---usemodule=list load the given module (or style) ---environment=list load the given file first ---mode=list enable given the mode(s) ---path=list also consult the given paths when files are looked for + +--generate generate file database etc. (as luatools does) --paranoid don't descend to .. and ../.. ---randomseed=number set the randomseed ---arguments=list set variables that can be consulted during a run (key/value pairs) ---interface use specified user interface +--version report installed context version --expert expert options ]] @@ -1430,11 +1439,8 @@ expert options: --nostats omit runtime statistics at the end of the run --update update context from website (not to be confused with contextgarden) --profile profile job (use: mtxrun --script profile --analyse) ---trackers show/set tracker variables ---directives show/set directive variables --timing generate timing and statistics overview --tracefiles show some extra info when locating files (at the tex end) ---randomseed --extra=name process extra (mtx-context- in distribution) --extras show extras diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index bc93eaaa9..03c3eb068 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -96,20 +96,6 @@ local function showfeatures(tag,specification) logs.reportline() end -local function make_pattern(pattern) -- will become helper in string - pattern = pattern:lower() - pattern = pattern:gsub("%-","%%-") - pattern = pattern:gsub("%.","%%.") - pattern = pattern:gsub("%*",".*") - pattern = pattern:gsub("%?",".?") - if pattern == "" then - pattern = ".*" - else ---~ pattern = "^" .. pattern .. "$" - end - return pattern -end - local function reloadbase(reload) if reload then logs.simple("fontnames, reloading font database") @@ -195,7 +181,7 @@ function scripts.fonts.list() if environment.argument("name") then if pattern then --~ mtxrun --script font --list --name --pattern=*somename* - list_matches(fonts.names.list(make_pattern(pattern),reload,all)) + list_matches(fonts.names.list(string.topattern(pattern,true),reload,all)) elseif filter then logs.report("fontnames","not supported: --list --name --filter",name) elseif given then @@ -220,7 +206,7 @@ function scripts.fonts.list() elseif environment.argument("file") then if pattern then --~ mtxrun --script font --list --file --pattern=*somename* - list_specifications(fonts.names.collectfiles(make_pattern(pattern),reload,all)) + list_specifications(fonts.names.collectfiles(string.topattern(pattern,true),reload,all)) elseif filter then logs.report("fontnames","not supported: --list --spec",name) elseif given then @@ -231,7 +217,7 @@ function scripts.fonts.list() end elseif pattern then --~ mtxrun --script font --list --pattern=*somename* - list_matches(fonts.names.list(make_pattern(pattern),reload,all)) + list_matches(fonts.names.list(string.topattern(pattern,true),reload,all)) elseif given then --~ mtxrun --script font --list somename list_matches(fonts.names.list(given,reload,all)) diff --git a/scripts/context/lua/mtx-server-ctx-fonttest.lua b/scripts/context/lua/mtx-server-ctx-fonttest.lua index f3a5d7690..23a3b5d11 100644 --- a/scripts/context/lua/mtx-server-ctx-fonttest.lua +++ b/scripts/context/lua/mtx-server-ctx-fonttest.lua @@ -147,9 +147,10 @@ local cache = { } local function showfeatures(f) if f then + logs.simple("processing font '%s'",f) local features = cache[f] if features == nil then - features = fonts.get_features(f) + features = fonts.get_features(resolvers.find_file(f)) if not features then logs.simple("building cache for '%s'",f) io.savedata(file.join(temppath,file.addsuffix(tempname,"tex")),format(process_templates.cache,f,f)) @@ -217,25 +218,50 @@ local function showfeatures(f) end end +local template_h = [[ + + safe name     + family name     + style-variant-weight-width     + font name     + weight     + filename +]] + +local template_d = [[ + + %s     + %s     + %s-%s-%s-%s     + %s     + %s     + %s +]] + local function select_font() - local t = fonts.names.list(".*") + local t = fonts.names.list(".*",false,true) if t then local listoffonts = { } - local t = fonts.names.list(".*") - if t then - listoffonts[#listoffonts+1] = "" - listoffonts[#listoffonts+1] = "" - for k, id in ipairs(table.sortedkeys(t)) do - local ti = t[id] - local type, name, file, sub = ti[1], ti[2], ti[3], ti[4] - if type == "otf" or type == "ttf" or type == "ttc" then - if sub then sub = "(sub)" else sub = "" end - listoffonts[#listoffonts+1] = format("",id,id,name,file,sub,type) - end + listoffonts[#listoffonts+1] = "
safe namefont namefilenamesub font type
%s%s%s%s%s
" + listoffonts[#listoffonts+1] = template_h + for k, v in table.sortedpairs(t) do + local kind = v.format + if kind == "otf" or kind == "ttf" or kind == "ttc" then + local fontname = v.fontname + listoffonts[#listoffonts+1] = format(template_d, fontname, fontname, + v.familyname or "", + t.variant or "normal", + t.weight or "normal", + t.width or "normal", + t.style or "normal", + v.rawname or fontname, + v.fontweight or "", + v.filename or "" + ) end - listoffonts[#listoffonts+1] = "
" - return concat(listoffonts,"\n") end + listoffonts[#listoffonts+1] = "" + return concat(listoffonts,"\n") end return "no fonts" end @@ -260,59 +286,67 @@ local result_template = [[ scripts.webserver.registerpath(temppath) +local function get_specification(name) + return fonts.names.resolvedspecification(name or "") +end + local function edit_font(currentfont,detail,tempname) - local fontname, fontfile, issub = fonts.names.specification(currentfont or "") - local htmldata = showfeatures(fontfile) - if htmldata then - local features, languages, scripts, options = { }, { }, { }, { } - for k,v in ipairs(table.sortedkeys(htmldata.scripts)) do - local s = fonts.otf.tables.scripts[v] or v - if detail and v == detail.script then - scripts[#scripts+1] = format(" %s",s,v,v,v,v) - else - scripts[#scripts+1] = format(" %s",s,v,v,v,v) + logs.simple("entering edit mode for '%s'",currentfont) + local specification = get_specification(currentfont) + if specification then + local htmldata = showfeatures(specification.filename) + if htmldata then + local features, languages, scripts, options = { }, { }, { }, { } + for k,v in ipairs(table.sortedkeys(htmldata.scripts)) do + local s = fonts.otf.tables.scripts[v] or v + if detail and v == detail.script then + scripts[#scripts+1] = format(" %s",s,v,v,v,v) + else + scripts[#scripts+1] = format(" %s",s,v,v,v,v) + end end - end - for k,v in ipairs(table.sortedkeys(htmldata.languages)) do - local l = fonts.otf.tables.languages[v] or v - if detail and v == detail.language then - languages[#languages+1] = format(" %s",l,v,v,v,v) - else - languages[#languages+1] = format(" %s",l,v,v,v,v) + for k,v in ipairs(table.sortedkeys(htmldata.languages)) do + local l = fonts.otf.tables.languages[v] or v + if detail and v == detail.language then + languages[#languages+1] = format(" %s",l,v,v,v,v) + else + languages[#languages+1] = format(" %s",l,v,v,v,v) + end end - end - for k,v in ipairs(table.sortedkeys(htmldata.features)) do - local f = fonts.otf.tables.features[v] or v - if detail and detail["f-"..v] then - features[#features+1] = format(" %s",f,v,v,v,v) - else - features[#features+1] = format(" %s",f,v,v,v,v) + for k,v in ipairs(table.sortedkeys(htmldata.features)) do + local f = fonts.otf.tables.features[v] or v + if detail and detail["f-"..v] then + features[#features+1] = format(" %s",f,v,v,v,v) + else + features[#features+1] = format(" %s",f,v,v,v,v) + end end - end - for k, v in ipairs { "trace", "basemode" } do - if detail and detail["o-"..v] then - options[#options+1] = format(" %s",v,v,v) + for k, v in ipairs { "trace", "basemode" } do + if detail and detail["o-"..v] then + options[#options+1] = format(" %s",v,v,v) + else + options[#options+1] = format(" %s",v,v,v) + end + end + local e = format(edit_template, + (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "", + concat(scripts," "),concat(languages," "),concat(features," "),concat(options," ")) + if tempname then + local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex") + local r = format(result_template,pdffile,texfile,pdffile) + return e .. r, htmldata.javascript or "" else - options[#options+1] = format(" %s",v,v,v) + return e, htmldata.javascript or "" end - end - local e = format(edit_template, - (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "", - concat(scripts," "),concat(languages," "),concat(features," "),concat(options," ")) - if tempname then - local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex") - local r = format(result_template,pdffile,texfile,pdffile) - return e .. r, htmldata.javascript or "" else - return e, htmldata.javascript or "" + return "error, nothing set up yet" end else - return "error, nothing set up yet" + return "error, no info about font" end end local function process_font(currentfont,detail) -- maybe just fontname - local fontname, fontfile, issub = fonts.names.specification(currentfont or "") local features = { "mode=node", format("language=%s",detail.language or "dflt"), @@ -361,14 +395,27 @@ local function show_log(currentfont,detail) end local function show_font(currentfont,detail) - local fontname, fontfile, issub = fonts.names.specification(currentfont or "") - local features = fonts.get_features(fontfile) + local specification = get_specification(currentfont) + local features = fonts.get_features(specification.filename) local result = { } result[#result+1] = format("

names

",what) result[#result+1] = "" - result[#result+1] = format("",currentfont) - result[#result+1] = format("",fontname) - result[#result+1] = format("",fontfile) + result[#result+1] = format("",currentfont) + result[#result+1] = format("",specification.fontname or "-") + result[#result+1] = format("",specification.fontfile or "-") + result[#result+1] = format("",specification.familyname or "-") + result[#result+1] = format("",specification.fontweight or "-") + result[#result+1] = format("",specification.format or "-") + result[#result+1] = format("",specification.fullname or "-") + result[#result+1] = format("",specification.subfamily or "-") + result[#result+1] = format("",specification.rawname or "-") + result[#result+1] = format("",specification.designsize or "-") + result[#result+1] = format("",specification.minsize or "-") + result[#result+1] = format("",specification.maxsize or "-") + result[#result+1] = format("",specification.style ~= "" and specification.style or "normal") + result[#result+1] = format("",specification.variant ~= "" and specification.variant or "normal") + result[#result+1] = format("",specification.weight ~= "" and specification.weight or "normal") + result[#result+1] = format("",specification.width ~= "" and specification.width or "normal") result[#result+1] = "
fontname:%s
fullname:%s
filename:%s
fontname: %s
fullname: %s
filename: %s
familyname: %s
fontweight: %s
format: %s
fullname: %s
subfamily: %s
rawname: %s
designsize: %s
minimumsize:%s
maximumsize:%s
style: %s
variant: %s
weight: %s
width: %s
" if features then for what, v in table.sortedpairs(features) do @@ -486,10 +533,10 @@ local function deletestored(detail,currentfont,name) end local function save_font(currentfont,detail) - local fontname, fontfile, issub = fonts.names.specification(currentfont or "") + local specification = get_specification(currentfont) local name, title, script, language, features, options, text = currentfont, "", "dflt", "dflt", { }, { }, "" if detail then - local htmldata = showfeatures(fontfile) + local htmldata = showfeatures(specification.filename) script = detail.script or script language = detail.language or language text = string.strip(detail.sampletext or text) @@ -519,7 +566,7 @@ local function load_font(currentfont) local result = {} result[#result+1] = format("del name font fontname script language features title sampletext ") for k,v in table.sortedpairs(storage) do - local fontname, fontfile, issub = fonts.names.specification(v.font or "") + local fontname, fontfile = get_specification(v.font) result[#result+1] = format("x %s %s %s %s %s %s %s %s ", k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "") end @@ -562,6 +609,13 @@ local status_template = [[ ]] +local variables = { + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = 'ConTeXt Font Tester', + ['formaction'] = "mtx-server-ctx-fonttest.lua", +} + function doit(configuration,filename,hashed) local start = os.clock() @@ -589,65 +643,49 @@ function doit(configuration,filename,hashed) action = "extras" end - lmx.restore() - - local fontname, fontfile, issub = fonts.names.specification(currentfont or "") + local fontname, fontfile = get_specification(currentfont) if fontfile then - lmx.variables['title-default'] = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile) + variables.title = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile) else - lmx.variables['title-default'] = 'ConTeXt Font Tester' + variables.title = 'ConTeXt Font Tester' end - lmx.variables['color-background-green'] = '#4F6F6F' - lmx.variables['color-background-blue'] = '#6F6F8F' - lmx.variables['color-background-yellow'] = '#8F8F6F' - lmx.variables['color-background-purple'] = '#8F6F8F' - - lmx.variables['color-background-body'] = '#808080' - lmx.variables['color-background-main'] = '#3F3F3F' - lmx.variables['color-background-one'] = lmx.variables['color-background-green'] - lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - - lmx.variables['title'] = lmx.variables['title-default'] - - lmx.set('title', lmx.get('title')) - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - -- lua table and adapt - lmx.set('formaction', "mtx-server-ctx-fonttest.lua") - local menu = { } for k, v in ipairs { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras'} do menu[#menu+1] = format("",v,v) end - lmx.set('menu', concat(menu," ")) - logs.simple("action: %s",action or "no action") + variables.menu = concat(menu," ") + variables.status = format(status_template,currentfont or "") + variables.maintext = "" + variables.javascriptdata = "" + variables.javascripts = "" + variables.javascriptinit = "" - lmx.set("status",format(status_template,currentfont or "")) + logs.simple("action: %s",action or "no action") local result if action == "select" then - lmx.set('maintext',select_font()) + variables.maintext = select_font() elseif action == "info" then - lmx.set('maintext',info_about()) + variables.maintext = info_about() elseif action == "extras" then - lmx.set('maintext',do_extras()) + variables.maintext = do_extras() elseif currentfont and currentfont ~= "" then if action == "save" then - lmx.set('maintext',save_font(currentfont,detail)) + variables.maintext = save_font(currentfont,detail) elseif action == "load" then - lmx.set('maintext',load_font(currentfont,detail)) + variables.maintext = load_font(currentfont,detail) elseif action == "source" then - lmx.set('maintext',show_source(currentfont,detail)) + variables.maintext = show_source(currentfont,detail) elseif action == "log" then - lmx.set('maintext',show_log(currentfont,detail)) + variables.maintext = show_log(currentfont,detail) elseif action == "features" then - lmx.set('maintext',show_font(currentfont,detail)) + variables.maintext = show_font(currentfont,detail) else local e, s if action == "process" then @@ -659,16 +697,16 @@ function doit(configuration,filename,hashed) else e, s = process_font(currentfont,detail) end - lmx.set('maintext',e) - lmx.set('javascriptdata',s) - lmx.set('javascripts',javascripts) - lmx.set('javascriptinit', "check_form()") + variables.maintext = e + variables.javascriptdata = s + variables.javascripts = javascripts + variables.javascriptinit = "check_form()" end else - lmx.set('maintext',select_font()) + variables.maintext = select_font() end - result = { content = lmx.convert('context-fonttest.lmx') } + result = { content = lmx.convert('context-fonttest.lmx',false,variables) } logs.simple("time spent on page: %0.03f seconds",os.clock()-start) diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua index d77cc66e8..b6c97118b 100644 --- a/scripts/context/lua/mtx-server-ctx-help.lua +++ b/scripts/context/lua/mtx-server-ctx-help.lua @@ -548,25 +548,6 @@ end tex = tex or { } -lmx.variables['color-background-green'] = '#4F6F6F' -lmx.variables['color-background-blue'] = '#6F6F8F' -lmx.variables['color-background-yellow'] = '#8F8F6F' -lmx.variables['color-background-purple'] = '#8F6F8F' - -lmx.variables['color-background-body'] = '#808080' -lmx.variables['color-background-main'] = '#3F3F3F' -lmx.variables['color-background-main-left'] = '#3F3F3F' -lmx.variables['color-background-main-right'] = '#5F5F5F' -lmx.variables['color-background-one'] = lmx.variables['color-background-green'] -lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - -lmx.variables['title-default'] = 'ConTeXt Help Information' -lmx.variables['title'] = lmx.variables['title-default'] - -function lmx.loadedfile(filename) - return io.loaddata(resolvers.find_file(filename)) -- return resolvers.texdatablob(filename) -end - -- -- -- local interfaces = { @@ -582,6 +563,18 @@ local interfaces = { local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", 1 +local variables = { + ['color-background-main-left'] = '#3F3F3F', + ['color-background-main-right'] = '#5F5F5F', + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = 'ConTeXt Help Information', +} + +--~ function lmx.loadedfile(filename) +--~ return io.loaddata(resolvers.find_file(filename)) -- return resolvers.texdatablob(filename) +--~ end + local function doit(configuration,filename,hashed) local formats = document.setups.formats @@ -615,34 +608,32 @@ local function doit(configuration,filename,hashed) end end - lmx.restore() - lmx.set('title', 'ConTeXt Help Information') - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - local n = concat(refs,"
") local i = concat(ints,"

") if div then - lmx.set('names',div:format(n)) - lmx.set('interfaces',div:format(i)) + variables.names = div:format(n) + variables.interfaces = div:format(i) else - lmx.set('names', n) - lmx.set('interfaces', i) + variables.names = n + variables.interfaces = i end -- first we need to add information about mkii/mkiv + variables.maintitle = "no definition" + variables.maintext = "" + variables.extra = "" + if document.setups.showsources and lastsource and lastsource ~= "" then -- todo: mkii, mkiv, tex (can be different) local data = io.loaddata(resolvers.find_file(lastsource)) - lmx.set('maintitle', lastsource) - lmx.set('maintext', formats.listing:format(data)) + variables.maintitle = lastsource + variables.maintext = formats.listing:format(data) lastsource = "" elseif lastcommand and lastcommand ~= "" then local data = document.setups.collect(lastcommand,lastinterface,lastmode) if data then - lmx.set('maintitle', data.sequence) local extra = { } for k, v in ipairs { "environment", "category", "source", "mode" } do if data[v] and data[v] ~= "" then @@ -650,16 +641,15 @@ local function doit(configuration,filename,hashed) extra[#extra+1] = v .. ": " .. data[v] end end - lmx.set('extra', concat(extra,"   ")) - lmx.set('maintext', formats.parameters:format(concat(data.parameters))) + variables.maintitle = data.sequence + variables.maintext = formats.parameters:format(concat(data.parameters)) + variables.extra = concat(extra,"   ") else - lmx.set('maintext', "select command") + variables.maintext = "select command" end - else - lmx.set('maintext', "no definition") end - local content = lmx.convert('context-help.lmx') + local content = lmx.convert('context-help.lmx',false,variables) logs.simple("time spent on page: %0.03f seconds",os.clock()-start) diff --git a/scripts/context/lua/mtx-server-ctx-startup.lua b/scripts/context/lua/mtx-server-ctx-startup.lua index fcb757b3e..59536c36c 100644 --- a/scripts/context/lua/mtx-server-ctx-startup.lua +++ b/scripts/context/lua/mtx-server-ctx-startup.lua @@ -10,25 +10,6 @@ dofile(resolvers.find_file("trac-lmx.lua","tex")) function doit(configuration,filename,hashed) - lmx.restore() - - lmx.variables['color-background-green'] = '#4F6F6F' - lmx.variables['color-background-blue'] = '#6F6F8F' - lmx.variables['color-background-yellow'] = '#8F8F6F' - lmx.variables['color-background-purple'] = '#8F6F8F' - - lmx.variables['color-background-body'] = '#808080' - lmx.variables['color-background-main'] = '#3F3F3F' - lmx.variables['color-background-one'] = lmx.variables['color-background-green'] - lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - - lmx.variables['title'] = "Overview Of Goodies" - - lmx.set('title', lmx.get('title')) - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - - local list = { } local root = file.dirname(resolvers.find_file("mtx-server.lua") or ".") if root == "" then root = "." end @@ -42,11 +23,16 @@ function doit(configuration,filename,hashed) end end - lmx.set('maintext',table.concat(list,"\n")) - - result = { content = lmx.convert('context-base.lmx') } + local variables = { + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['title'] = "Overview Of Goodies", + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + ['maintext'] = table.concat(list,"\n"), + } - return result + return { content = lmx.convert('context-base.lmx',false,variables) } end diff --git a/scripts/context/lua/mtx-timing.lua b/scripts/context/lua/mtx-timing.lua index 375d5d90b..a9a0c8745 100644 --- a/scripts/context/lua/mtx-timing.lua +++ b/scripts/context/lua/mtx-timing.lua @@ -124,50 +124,39 @@ function goodies.progress.valid_file(name) end function goodies.progress.make_lmx_page(name,launch,remove) + local filename = name .. "-luatex-progress" local other = "elapsed_time" local template = 'context-timing.lmx' - lmx.variables['color-background-green'] = '#4F6F6F' - lmx.variables['color-background-blue'] = '#6F6F8F' - lmx.variables['color-background-yellow'] = '#8F8F6F' - lmx.variables['color-background-purple'] = '#8F6F8F' - - lmx.variables['color-background-body'] = '#808080' - lmx.variables['color-background-main'] = '#3F3F3F' - lmx.variables['color-background-one'] = lmx.variables['color-background-green'] - lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - - lmx.variables['title-default'] = 'ConTeXt Timing Information' - lmx.variables['title'] = lmx.variables['title-default'] - - lmx.htmfile = function(name) return name .. "-timing.xhtml" end - lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end - - lmx.set('title', format('ConTeXt Timing Information: %s',file.basename(name))) - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - goodies.progress.convert(filename) local menudata, metadata = goodies.progress.make_svg(filename,other) local htmldata = goodies.progress.makehtml(filename,other,menudata,metadata) - lmx.set('parametersmenu', concat(htmldata.parameters, "  ")) - lmx.set('nodesmenu', concat(htmldata.nodes, "  ")) - lmx.set('graphics', concat(htmldata.graphics, "\n\n")) + lmx.htmfile = function(name) return name .. "-timing.xhtml" end + lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end + + local variables = { + ['title-default'] = 'ConTeXt Timing Information', + ['title'] = format('ConTeXt Timing Information: %s',file.basename(name)), + ['parametersmenu'] = concat(htmldata.parameters, "  "), + ['nodesmenu'] = concat(htmldata.nodes, "  "), + ['graphics'] = concat(htmldata.graphics, "\n\n"), + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + } if launch then - local htmfile = lmx.show(template) + local htmfile = lmx.show(template,variables) if remove then os.sleep(1) -- give time to launch os.remove(htmfile) end else - lmx.make(template) + lmx.make(template,variables) end - lmx.restore() end scripts = scripts or { } diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua index ca2faaf29..5c90df071 100644 --- a/scripts/context/lua/mtx-tools.lua +++ b/scripts/context/lua/mtx-tools.lua @@ -6,9 +6,7 @@ if not modules then modules = { } end modules ['mtx-tools'] = { license = "see context related readme files" } --- data tables by Thomas A. Schmitz - -local find, gsub = string.find, string.gsub +local find, format, sub, rep, gsub = string.find, string.format, string.sub, string.rep, string.gsub scripts = scripts or { } scripts.tools = scripts.tools or { } @@ -44,14 +42,97 @@ function scripts.tools.disarmutfbomb() end end -logs.extendbanner("Some File Related Goodies 1.00",true) +function scripts.tools.dirtoxml() + + local join, removesuffix, extname, date = file.join, file.removesuffix, file.extname, os.date + + local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng" + local timestamp = "%Y-%m-%d %H:%M" + + local pattern = environment.argument('pattern') or ".*" + local url = environment.argument('url') or "no-url" + local root = environment.argument('root') or "." + local outputfile = environment.argument('output') + + local recurse = environment.argument('recurse') + local stripname = environment.argument('stripname') + local longname = environment.argument('longname') + + local function flush(list,result,n,path) + n, result = n or 1, result or { } + local d = rep(" ",n) + for name, attr in table.sortedpairs(list) do + local mode = attr.mode + if mode == "file" then + result[#result+1] = format("%s",d,(longname and path and join(path,name)) or name) + result[#result+1] = format("%s %s",d,removesuffix(name)) + result[#result+1] = format("%s %s",d,extname(name)) + result[#result+1] = format("%s %s",d,attr.size) + result[#result+1] = format("%s %s",d,sub(attr.permissions,7,9)) + result[#result+1] = format("%s %s",d,date(timestamp,attr.modification)) + result[#result+1] = format("%s",d) + elseif mode == "directory" then + result[#result+1] = format("%s",d,name) + flush(attr.list,result,n+1,(path and join(path,name)) or name) + result[#result+1] = format("%s",d) + end + end + end + + if not pattern or pattern == "" then + logs.report('provide --pattern=') + return + end + + if stripname then + pattern = file.dirname(pattern) + end + + local luapattern = string.topattern(pattern,true) + + lfs.chdir(root) + + local list = dir.collect_pattern(root,luapattern,recurse) + + if list[outputfile] then + list[outputfile] = nil + end + + local result = { "" } + result[#result+1] = format("",url,root,pattern,luapattern,xmlns,date(timestamp)) + flush(list,result) + result[#result+1] = "" + + result = table.concat(result,"\n") + + if not outputfile or outputfile == "" then + texio.write_nl(result) + else + io.savedata(outputfile,result) + end + +end + +logs.extendbanner("Some File Related Goodies 1.01",true) messages.help = [[ --disarmutfbomb remove utf bomb if present + --force remove indeed + +--dirtoxml glob directory into xml + --pattern glob pattern (default: .*) + --url url attribute (no processing) + --root the root of the globbed path (default: .) + --output output filename (console by default) + --recurse recurse into subdirecories + --stripname take pathpart of given pattern + --longname set name attributes to full path name ]] if environment.argument("disarmutfbomb") then scripts.tools.disarmutfbomb() +elseif environment.argument("dirtoxml") then + scripts.tools.dirtoxml() else logs.help(messages.help) end diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua index 61d6b0d84..48df6862a 100644 --- a/scripts/context/lua/mtx-update.lua +++ b/scripts/context/lua/mtx-update.lua @@ -195,7 +195,7 @@ function scripts.update.synchronize() if ok or not force then - local fetched, individual, osplatform = { }, { }, os.currentplatform() + local fetched, individual, osplatform = { }, { }, os.platform -- takes a collection as argument and returns a list of folders @@ -223,7 +223,7 @@ function scripts.update.synchronize() return prefix .. concat(list_of_folders, format(" %s", prefix)) end - -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.currentplatform))) + -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.platform))) -- rename function and add some more functionality: -- * recursive/non-recursive (default: non-recursive) @@ -507,7 +507,7 @@ if scripts.savestate then end end local valid = scripts.update.platforms - for r in gmatch(environment.argument("platform") or os.currentplatform(),"([^, ]+)") do + for r in gmatch(environment.argument("platform") or os.platform,"([^, ]+)") do if valid[r] then states.set("platforms." .. r, true) end end diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua index 44f61ae6b..9cfe2bbfd 100644 --- a/scripts/context/lua/mtx-watch.lua +++ b/scripts/context/lua/mtx-watch.lua @@ -9,160 +9,168 @@ if not modules then modules = { } end modules ['mtx-watch'] = { scripts = scripts or { } scripts.watch = scripts.watch or { } -do - - function scripts.watch.save_exa_modes(joblog,ctmname) - local t= { } - if joblog then - t[#t+1] = "\n" - t[#t+1] = "" - if joblog.values then - for k, v in pairs(joblog.values) do - t[#t+1] = string.format("\t%s", k, tostring(v)) - end - else - t[#t+1] = "" +function scripts.watch.save_exa_modes(joblog,ctmname) + local t= { } + if joblog then + t[#t+1] = "\n" + t[#t+1] = "" + if joblog.values then + for k, v in pairs(joblog.values) do + t[#t+1] = string.format("\t%s", k, tostring(v)) end - t[#t+1] = "" + else + t[#t+1] = "" end - os.remove(ctmname) - io.savedata(ctmname,table.concat(t,"\n")) + t[#t+1] = "" end + os.remove(ctmname) + io.savedata(ctmname,table.concat(t,"\n")) +end - function scripts.watch.watch() - local delay = environment.argument("delay") or 5 - local logpath = environment.argument("logpath") or "" - local pipe = environment.argument("pipe") or false - if #environment.files > 0 then - for _, path in ipairs(environment.files) do - logs.report("watch", "watching path ".. path) - end - local function glob(files,path) - for name in lfs.dir(path) do - if name:find("^%.") then - -- skip . and .. - else - name = path .. "/" .. name - local a = lfs.attributes(name) - if not a then - -- weird - elseif a.mode == "directory" then - if name:find("graphics$") or name:find("figures$") or name:find("resources$") then - -- skip these too - else - glob(files,name) - end - elseif name:find(".%luj$") then - files[name] = a.change or a.ctime or a.modification or a.mtime - end - end - end - end - local function toset(t) - if type(t) == "table" then - return table.concat(t,",") - else - return t - end - end - local function noset(t) - if type(t) == "table" then - return t[1] +local function toset(t) + if type(t) == "table" then + return table.concat(t,",") + else + return t + end +end + +local function noset(t) + if type(t) == "table" then + return t[1] + else + return t + end +end + +local lfsdir, lfsattributes = lfs.dir, lfs.attributes + +local function glob(files,path) + for name in lfsdir(path) do + if name:find("^%.") then + -- skip . and .. + else + name = path .. "/" .. name + local a = lfsattributes(name) + if not a then + -- weird + elseif a.mode == "directory" then + if name:find("graphics$") or name:find("figures$") or name:find("resources$") then + -- skip these too else - return t + glob(files,name) end + elseif name:find(".%luj$") then + files[name] = a.change or a.ctime or a.modification or a.mtime end - local function process() - local done = false - for _, path in ipairs(environment.files) do - lfs.chdir(path) - local files = { } - glob(files,path) - table.sort(files) -- what gets sorted here - for name, time in pairs(files) do - --~ local ok, joblog = xpcall(function() return dofile(name) end, function() end ) - local ok, joblog = pcall(dofile,name) - if ok and joblog then - if joblog.status == "processing" then - logs.report("watch",string.format("aborted job, %s added to queue",name)) - joblog.status = "queued" - io.savedata(name, table.serialize(joblog,true)) - elseif joblog.status == "queued" then - local command = joblog.command - if command then - local replacements = { - inputpath = toset((joblog.paths and joblog.paths.input ) or "."), - outputpath = noset((joblog.paths and joblog.paths.output) or "."), - filename = joblog.filename or "", - } - command = command:gsub("%%(.-)%%", replacements) - if command ~= "" then - joblog.status = "processing" - joblog.runtime = os.time() -- os.clock() - io.savedata(name, table.serialize(joblog,true)) - logs.report("watch",string.format("running: %s", command)) - local newpath = file.dirname(name) - io.flush() - local result = "" - local ctmname = file.basename(replacements.filename) - if ctmname == "" then ctmname = name end -- use self as fallback - ctmname = file.replacesuffix(ctmname,"ctm") - if newpath ~= "" and newpath ~= "." then - local oldpath = lfs.currentdir() - lfs.chdir(newpath) - scripts.watch.save_exa_modes(joblog,ctmname) - if pipe then result = os.resultof(command) else result = os.spawn(command) end - lfs.chdir(oldpath) - else - scripts.watch.save_exa_modes(joblog,ctmname) - if pipe then result = os.resultof(command) else result = os.spawn(command) end - end - logs.report("watch",string.format("return value: %s", result)) - done = true - local path, base = replacements.outputpath, file.basename(replacements.filename) - joblog.runtime = os.time() - joblog.runtime -- os.clock() - joblog.runtime + end + end +end + +function scripts.watch.watch() + local delay = environment.argument("delay") or 5 + local logpath = environment.argument("logpath") or "" + local pipe = environment.argument("pipe") or false + if #environment.files > 0 then + for _, path in ipairs(environment.files) do + logs.report("watch", "watching path ".. path) + end + local function process() + local done = false + for _, path in ipairs(environment.files) do + lfs.chdir(path) + local files = { } + glob(files,path) + table.sort(files) -- what gets sorted here + for name, time in pairs(files) do + --~ local ok, joblog = xpcall(function() return dofile(name) end, function() end ) + local ok, joblog = pcall(dofile,name) + if ok and joblog then + if joblog.status == "processing" then + logs.report("watch",string.format("aborted job, %s added to queue",name)) + joblog.status = "queued" + io.savedata(name, table.serialize(joblog,true)) + elseif joblog.status == "queued" then + local command = joblog.command + if command then + local replacements = { + inputpath = toset((joblog.paths and joblog.paths.input ) or "."), + outputpath = noset((joblog.paths and joblog.paths.output) or "."), + filename = joblog.filename or "", + } + command = command:gsub("%%(.-)%%", replacements) + if command ~= "" then + joblog.status = "processing" + joblog.runtime = os.clock() + io.savedata(name, table.serialize(joblog,true)) + logs.report("watch",string.format("running: %s", command)) + local newpath = file.dirname(name) + io.flush() + local result = "" + local ctmname = file.basename(replacements.filename) + if ctmname == "" then ctmname = name end -- use self as fallback + ctmname = file.replacesuffix(ctmname,"ctm") + if newpath ~= "" and newpath ~= "." then + local oldpath = lfs.currentdir() + lfs.chdir(newpath) + scripts.watch.save_exa_modes(joblog,ctmname) + if pipe then result = os.resultof(command) else result = os.spawn(command) end + lfs.chdir(oldpath) + else + scripts.watch.save_exa_modes(joblog,ctmname) + if pipe then result = os.resultof(command) else result = os.spawn(command) end + end + logs.report("watch",string.format("return value: %s", result)) + done = true + local path, base = replacements.outputpath, file.basename(replacements.filename) + joblog.runtime = os.clock() - joblog.runtime + if base ~= "" then joblog.result = file.replacesuffix(file.join(path,base),"pdf") joblog.size = lfs.attributes(joblog.result,"size") - joblog.status = "finished" - else - joblog.status = "invalid command" end + joblog.status = "finished" else - joblog.status = "no command" + joblog.status = "invalid command" end - -- pcall, when error sleep + again + else + joblog.status = "no command" + end + -- pcall, when error sleep + again + io.savedata(name, table.serialize(joblog,true)) + if logpath ~= "" then + local name = string.format("%s/%s%04i%09i.lua", logpath, os.time(), math.floor((os.clock()*100)%1000), math.random(99999999)) io.savedata(name, table.serialize(joblog,true)) - if logpath ~= "" then - local name = string.format("%s/%s%04i%09i.lua", logpath, os.time(), math.floor((os.clock()*100)%1000), math.random(99999999)) - io.savedata(name, table.serialize(joblog,true)) - logs.report("watch", "saving joblog ".. name) - end + logs.report("watch", "saving joblog ".. name) end end end end end - local n, start = 0, os.clock() - local function wait() - io.flush() - if not done then - n = n + 1 - if n >= 10 then - logs.report("watch", string.format("run time: %i seconds, memory usage: %0.3g MB", os.clock() - start, (status.luastate_bytes/1024)/1000)) - n = 0 - end - os.sleep(delay) + end + local n, start = 0, os.clock() + local function wait() + io.flush() + if not done then + n = n + 1 + if n >= 10 then + logs.report("watch", string.format("run time: %i seconds, memory usage: %0.3g MB", os.clock() - start, (status.luastate_bytes/1024)/1000)) + n = 0 end + os.sleep(delay) end - while true do + end + while true do + if false then + process() + wait() + else pcall(process) pcall(wait) end - else - logs.report("watch", "no paths to watch") end + else + logs.report("watch", "no paths to watch") end - end function scripts.watch.collect_logs(path) -- clean 'm up too diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index a1fc6eaf5..c5b0acd04 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -242,6 +242,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -304,6 +305,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1765,59 +1779,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2241,6 +2250,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -7264,6 +7302,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -8483,9 +8526,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end @@ -9473,6 +9516,16 @@ prefixes.full = prefixes.locate prefixes.file = prefixes.filename prefixes.path = prefixes.pathname +function resolvers.allprefixes(separator) + local all = table.sortedkeys(prefixes) + if separator then + for i=1,#all do + all[i] = all[i] .. ":" + end + end + return all +end + local function _resolve_(method,target) if prefixes[method] then return prefixes[method](target) @@ -10130,43 +10183,109 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local gsub = string.gsub -local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -local libpaths = file.split_path(package.path) +local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' +local clibformats = { 'lib' } +local libpaths = file.split_path(package.path) +local clibpaths = file.split_path(package.cpath) + +local function thepath(...) + local t = { ... } t[#t+1] = "?.lua" + local path = file.join(unpack(t)) + if trace_locating then + logs.report("fileio","! appending '%s' to 'package.path'",path) + end + return path +end + +function package.append_libpath(...) + table.insert(libpaths,thepath(...)) +end + +function package.prepend_libpath(...) + table.insert(libpaths,1,thepath(...)) +end + +-- beware, we need to return a loadfile result ! package.loaders[2] = function(name) -- was [#package.loaders+1] ---~ package.loaders[#package.loaders+1] = function(name) -- was + if trace_locating then -- mode detail + logs.report("fileio","! locating '%s'",name) + end for i=1,#libformats do local format = libformats[i] local resolved = resolvers.find_file(name,format) or "" + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'libformat path': '%s'",name,format) + end if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end end - local simple = file.removesuffix(name) + local simple = gsub(name,"%.lua$","") + local simple = gsub(simple,"%.","/") for i=1,#libpaths do -- package.path, might become option - local resolved = gsub(libpaths[i],"?",simple) + local libpath = libpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.path': '%s'",simple,libpath) + end if resolvers.isreadable.file(resolved) then if trace_locating then logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) + end + end + local libname = file.addsuffix(simple,os.libsuffix) + for i=1,#clibformats do + -- better have a dedicated loop + local format = clibformats[i] + local paths = resolvers.expanded_path_list_from_var(format) + for p=1,#paths do + local path = paths[p] + local resolved = file.join(path,libname) + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'clibformat path': '%s'",libname,path) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'clibformat': '%s'",libname,resolved) + end + return package.loadlib(resolved,name) + end + end + end + for i=1,#clibpaths do -- package.path, might become option + local libpath = clibpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.cpath': '%s'",simple,libpath) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.cpath': '%s'",name,resolved) + end + return package.loadlib(resolved,name) end end -- just in case the distribution is messed up + if trace_loading then -- more detail + logs.report("fileio","! checking for '%s' using 'luatexlibs': '%s'",name) + end local resolved = resolvers.find_file(file.basename(name),'luatexlibs') or "" if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located by basename via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end if trace_locating then logs.report("fileio",'? unable to locate lib: %s',name) end - return "unable to locate " .. name +-- return "unable to locate " .. name end resolvers.loadlualib = require @@ -10359,7 +10478,7 @@ if not modules then modules = { } end modules ['data-tmf'] = { function resolvers.check_environment(tree) logs.simpleline() os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.currentplatform())) + os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) logs.simpleline() @@ -10723,10 +10842,11 @@ runners = runners or { } -- global messages = messages or { } messages.help = [[ ---script run an mtx script (--noquotes), no script gives list ---execute run a script or program (--noquotes) +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) --resolve resolve prefixed arguments --ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) --locate locate given filename --autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' @@ -10750,11 +10870,13 @@ messages.help = [[ --edit launch editor with found file --launch (--all) launch files like manuals, assumes os support ---internal run script using built in libraries (same as --ctxlua) --timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) --usekpse use kpse as fallback (when no mkiv and cache installed, often slower) --forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes ]] runners.applications = { @@ -10800,6 +10922,13 @@ runners.launchers = { unix = { } } +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + function runners.prepare() local checkname = environment.argument("ifchanged") if checkname and checkname ~= "" then @@ -10890,6 +11019,7 @@ function runners.execute_script(fullname,internal,nosplit) end if internal then arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result dofile(result) else local binary = runners.applications[file.extname(result)] @@ -10993,7 +11123,7 @@ function runners.locate_file(filename) end function runners.locate_platform() - runners.report_location(os.currentplatform()) + runners.report_location(os.platform) end function runners.report_location(result) @@ -11170,6 +11300,7 @@ function runners.execute_ctx_script(filename) if logs.verbose then logs.simple("using script: %s\n",fullname) end + environment.ownscript = fullname dofile(fullname) local savename = environment.arguments['save'] if savename and runners.save_list and not table.is_empty(runners.save_list or { }) then @@ -11222,6 +11353,11 @@ function runners.execute_ctx_script(filename) end end +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end function runners.timedrun(filename) -- just for me if filename and filename ~= "" then @@ -11337,7 +11473,7 @@ elseif environment.argument("selfupdate") then elseif environment.argument("ctxlua") or environment.argument("internal") then -- run a script by loading it (using libs) ok = runners.execute_script(filename,true) -elseif environment.argument("script") or environment.argument("s") then +elseif environment.argument("script") or environment.argument("s") or environment.argument("scripts") then -- run a script by loading it (using libs), pass args ok = runners.execute_ctx_script(filename) elseif environment.argument("execute") then @@ -11366,6 +11502,8 @@ elseif environment.argument("locate") then elseif environment.argument("platform")then -- locate platform runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() elseif environment.argument("timedrun") then -- locate platform runners.timedrun(filename) @@ -11375,9 +11513,9 @@ elseif environment.argument("help") or filename=='help' or filename == "" then elseif filename:find("^bin:") then ok = runners.execute_program(filename) else - ok = runners.execute_script(filename) + ok = runners.execute_ctx_script(filename) if not ok then - ok = runners.execute_ctx_script(filename) + ok = runners.execute_script(filename) end end diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua index 6feb7a9c5..06e2a1bfc 100644 --- a/scripts/context/stubs/mswin/luatools.lua +++ b/scripts/context/stubs/mswin/luatools.lua @@ -233,6 +233,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -295,6 +296,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1756,59 +1770,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2343,6 +2352,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -3166,9 +3204,9 @@ function aux.settings_to_hash_strict(str,existing) end end -local seperator = comma * space^0 +local separator = comma * space^0 local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(seperator*value)^0) +local pattern = lpeg.Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored @@ -3187,7 +3225,7 @@ local function set(t,v) end local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(seperator*value)^0 * lpeg.Carg(1) +local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) return pattern:match(str, nil, t) @@ -3238,6 +3276,13 @@ function aux.settings_to_set(str,t) return t end +local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace +local pattern = lpeg.Ct((space + value)^0) + +function aux.arguments_to_table(str) + return pattern:match(str) +end + -- temporary here function aux.getparameters(self,class,parentclass,settings) @@ -4068,7 +4113,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['luat-log'] = { +if not modules then modules = { } end modules ['trac-log'] = { version = 1.001, comment = "companion to trac-log.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4345,8 +4390,12 @@ end logs.simpleline = logs.reportline -function logs.help(message,option) +function logs.reportbanner() -- for scripts too logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() logs.reportline() logs.reportlines(message) local moreinfo = logs.moreinfo or "" @@ -4509,6 +4558,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -5728,9 +5782,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index a1fc6eaf5..c5b0acd04 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -242,6 +242,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -304,6 +305,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1765,59 +1779,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2241,6 +2250,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -7264,6 +7302,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -8483,9 +8526,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end @@ -9473,6 +9516,16 @@ prefixes.full = prefixes.locate prefixes.file = prefixes.filename prefixes.path = prefixes.pathname +function resolvers.allprefixes(separator) + local all = table.sortedkeys(prefixes) + if separator then + for i=1,#all do + all[i] = all[i] .. ":" + end + end + return all +end + local function _resolve_(method,target) if prefixes[method] then return prefixes[method](target) @@ -10130,43 +10183,109 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local gsub = string.gsub -local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -local libpaths = file.split_path(package.path) +local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' +local clibformats = { 'lib' } +local libpaths = file.split_path(package.path) +local clibpaths = file.split_path(package.cpath) + +local function thepath(...) + local t = { ... } t[#t+1] = "?.lua" + local path = file.join(unpack(t)) + if trace_locating then + logs.report("fileio","! appending '%s' to 'package.path'",path) + end + return path +end + +function package.append_libpath(...) + table.insert(libpaths,thepath(...)) +end + +function package.prepend_libpath(...) + table.insert(libpaths,1,thepath(...)) +end + +-- beware, we need to return a loadfile result ! package.loaders[2] = function(name) -- was [#package.loaders+1] ---~ package.loaders[#package.loaders+1] = function(name) -- was + if trace_locating then -- mode detail + logs.report("fileio","! locating '%s'",name) + end for i=1,#libformats do local format = libformats[i] local resolved = resolvers.find_file(name,format) or "" + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'libformat path': '%s'",name,format) + end if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end end - local simple = file.removesuffix(name) + local simple = gsub(name,"%.lua$","") + local simple = gsub(simple,"%.","/") for i=1,#libpaths do -- package.path, might become option - local resolved = gsub(libpaths[i],"?",simple) + local libpath = libpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.path': '%s'",simple,libpath) + end if resolvers.isreadable.file(resolved) then if trace_locating then logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) + end + end + local libname = file.addsuffix(simple,os.libsuffix) + for i=1,#clibformats do + -- better have a dedicated loop + local format = clibformats[i] + local paths = resolvers.expanded_path_list_from_var(format) + for p=1,#paths do + local path = paths[p] + local resolved = file.join(path,libname) + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'clibformat path': '%s'",libname,path) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'clibformat': '%s'",libname,resolved) + end + return package.loadlib(resolved,name) + end + end + end + for i=1,#clibpaths do -- package.path, might become option + local libpath = clibpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.cpath': '%s'",simple,libpath) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.cpath': '%s'",name,resolved) + end + return package.loadlib(resolved,name) end end -- just in case the distribution is messed up + if trace_loading then -- more detail + logs.report("fileio","! checking for '%s' using 'luatexlibs': '%s'",name) + end local resolved = resolvers.find_file(file.basename(name),'luatexlibs') or "" if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located by basename via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end if trace_locating then logs.report("fileio",'? unable to locate lib: %s',name) end - return "unable to locate " .. name +-- return "unable to locate " .. name end resolvers.loadlualib = require @@ -10359,7 +10478,7 @@ if not modules then modules = { } end modules ['data-tmf'] = { function resolvers.check_environment(tree) logs.simpleline() os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.currentplatform())) + os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) logs.simpleline() @@ -10723,10 +10842,11 @@ runners = runners or { } -- global messages = messages or { } messages.help = [[ ---script run an mtx script (--noquotes), no script gives list ---execute run a script or program (--noquotes) +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) --resolve resolve prefixed arguments --ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) --locate locate given filename --autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' @@ -10750,11 +10870,13 @@ messages.help = [[ --edit launch editor with found file --launch (--all) launch files like manuals, assumes os support ---internal run script using built in libraries (same as --ctxlua) --timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) --usekpse use kpse as fallback (when no mkiv and cache installed, often slower) --forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes ]] runners.applications = { @@ -10800,6 +10922,13 @@ runners.launchers = { unix = { } } +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + function runners.prepare() local checkname = environment.argument("ifchanged") if checkname and checkname ~= "" then @@ -10890,6 +11019,7 @@ function runners.execute_script(fullname,internal,nosplit) end if internal then arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result dofile(result) else local binary = runners.applications[file.extname(result)] @@ -10993,7 +11123,7 @@ function runners.locate_file(filename) end function runners.locate_platform() - runners.report_location(os.currentplatform()) + runners.report_location(os.platform) end function runners.report_location(result) @@ -11170,6 +11300,7 @@ function runners.execute_ctx_script(filename) if logs.verbose then logs.simple("using script: %s\n",fullname) end + environment.ownscript = fullname dofile(fullname) local savename = environment.arguments['save'] if savename and runners.save_list and not table.is_empty(runners.save_list or { }) then @@ -11222,6 +11353,11 @@ function runners.execute_ctx_script(filename) end end +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end function runners.timedrun(filename) -- just for me if filename and filename ~= "" then @@ -11337,7 +11473,7 @@ elseif environment.argument("selfupdate") then elseif environment.argument("ctxlua") or environment.argument("internal") then -- run a script by loading it (using libs) ok = runners.execute_script(filename,true) -elseif environment.argument("script") or environment.argument("s") then +elseif environment.argument("script") or environment.argument("s") or environment.argument("scripts") then -- run a script by loading it (using libs), pass args ok = runners.execute_ctx_script(filename) elseif environment.argument("execute") then @@ -11366,6 +11502,8 @@ elseif environment.argument("locate") then elseif environment.argument("platform")then -- locate platform runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() elseif environment.argument("timedrun") then -- locate platform runners.timedrun(filename) @@ -11375,9 +11513,9 @@ elseif environment.argument("help") or filename=='help' or filename == "" then elseif filename:find("^bin:") then ok = runners.execute_program(filename) else - ok = runners.execute_script(filename) + ok = runners.execute_ctx_script(filename) if not ok then - ok = runners.execute_ctx_script(filename) + ok = runners.execute_script(filename) end end diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools index 6feb7a9c5..06e2a1bfc 100755 --- a/scripts/context/stubs/unix/luatools +++ b/scripts/context/stubs/unix/luatools @@ -233,6 +233,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -295,6 +296,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1756,59 +1770,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2343,6 +2352,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -3166,9 +3204,9 @@ function aux.settings_to_hash_strict(str,existing) end end -local seperator = comma * space^0 +local separator = comma * space^0 local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) -local pattern = lpeg.Ct(value*(seperator*value)^0) +local pattern = lpeg.Ct(value*(separator*value)^0) -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored @@ -3187,7 +3225,7 @@ local function set(t,v) end local value = lpeg.P(lpeg.Carg(1)*value) / set -local pattern = value*(seperator*value)^0 * lpeg.Carg(1) +local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) return pattern:match(str, nil, t) @@ -3238,6 +3276,13 @@ function aux.settings_to_set(str,t) return t end +local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace +local pattern = lpeg.Ct((space + value)^0) + +function aux.arguments_to_table(str) + return pattern:match(str) +end + -- temporary here function aux.getparameters(self,class,parentclass,settings) @@ -4068,7 +4113,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['luat-log'] = { +if not modules then modules = { } end modules ['trac-log'] = { version = 1.001, comment = "companion to trac-log.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -4345,8 +4390,12 @@ end logs.simpleline = logs.reportline -function logs.help(message,option) +function logs.reportbanner() -- for scripts too logs.report(banner) +end + +function logs.help(message,option) + logs.reportbanner() logs.reportline() logs.reportlines(message) local moreinfo = logs.moreinfo or "" @@ -4509,6 +4558,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -5728,9 +5782,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index a1fc6eaf5..c5b0acd04 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -242,6 +242,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -304,6 +305,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- of closure @@ -1765,59 +1779,54 @@ os.arch = os.arch or function() return a end -local platform +-- no need for function anymore as we have more clever code and helpers now -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" + else + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed @@ -2241,6 +2250,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -7264,6 +7302,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -8483,9 +8526,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end @@ -9473,6 +9516,16 @@ prefixes.full = prefixes.locate prefixes.file = prefixes.filename prefixes.path = prefixes.pathname +function resolvers.allprefixes(separator) + local all = table.sortedkeys(prefixes) + if separator then + for i=1,#all do + all[i] = all[i] .. ":" + end + end + return all +end + local function _resolve_(method,target) if prefixes[method] then return prefixes[method](target) @@ -10130,43 +10183,109 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local gsub = string.gsub -local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -local libpaths = file.split_path(package.path) +local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' +local clibformats = { 'lib' } +local libpaths = file.split_path(package.path) +local clibpaths = file.split_path(package.cpath) + +local function thepath(...) + local t = { ... } t[#t+1] = "?.lua" + local path = file.join(unpack(t)) + if trace_locating then + logs.report("fileio","! appending '%s' to 'package.path'",path) + end + return path +end + +function package.append_libpath(...) + table.insert(libpaths,thepath(...)) +end + +function package.prepend_libpath(...) + table.insert(libpaths,1,thepath(...)) +end + +-- beware, we need to return a loadfile result ! package.loaders[2] = function(name) -- was [#package.loaders+1] ---~ package.loaders[#package.loaders+1] = function(name) -- was + if trace_locating then -- mode detail + logs.report("fileio","! locating '%s'",name) + end for i=1,#libformats do local format = libformats[i] local resolved = resolvers.find_file(name,format) or "" + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'libformat path': '%s'",name,format) + end if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end end - local simple = file.removesuffix(name) + local simple = gsub(name,"%.lua$","") + local simple = gsub(simple,"%.","/") for i=1,#libpaths do -- package.path, might become option - local resolved = gsub(libpaths[i],"?",simple) + local libpath = libpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.path': '%s'",simple,libpath) + end if resolvers.isreadable.file(resolved) then if trace_locating then logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) + end + end + local libname = file.addsuffix(simple,os.libsuffix) + for i=1,#clibformats do + -- better have a dedicated loop + local format = clibformats[i] + local paths = resolvers.expanded_path_list_from_var(format) + for p=1,#paths do + local path = paths[p] + local resolved = file.join(path,libname) + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'clibformat path': '%s'",libname,path) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'clibformat': '%s'",libname,resolved) + end + return package.loadlib(resolved,name) + end + end + end + for i=1,#clibpaths do -- package.path, might become option + local libpath = clibpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.cpath': '%s'",simple,libpath) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.cpath': '%s'",name,resolved) + end + return package.loadlib(resolved,name) end end -- just in case the distribution is messed up + if trace_loading then -- more detail + logs.report("fileio","! checking for '%s' using 'luatexlibs': '%s'",name) + end local resolved = resolvers.find_file(file.basename(name),'luatexlibs') or "" if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located by basename via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end if trace_locating then logs.report("fileio",'? unable to locate lib: %s',name) end - return "unable to locate " .. name +-- return "unable to locate " .. name end resolvers.loadlualib = require @@ -10359,7 +10478,7 @@ if not modules then modules = { } end modules ['data-tmf'] = { function resolvers.check_environment(tree) logs.simpleline() os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.currentplatform())) + os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) logs.simpleline() @@ -10723,10 +10842,11 @@ runners = runners or { } -- global messages = messages or { } messages.help = [[ ---script run an mtx script (--noquotes), no script gives list ---execute run a script or program (--noquotes) +--script run an mtx script (lua prefered method) (--noquotes), no script gives list +--execute run a script or program (texmfstart method) (--noquotes) --resolve resolve prefixed arguments --ctxlua run internally (using preloaded libs) +--internal run script using built in libraries (same as --ctxlua) --locate locate given filename --autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' @@ -10750,11 +10870,13 @@ messages.help = [[ --edit launch editor with found file --launch (--all) launch files like manuals, assumes os support ---internal run script using built in libraries (same as --ctxlua) --timedrun run a script an time its run +--autogenerate regenerate databases if needed (handy when used to run context in an editor) --usekpse use kpse as fallback (when no mkiv and cache installed, often slower) --forcekpse force using kpse (handy when no mkiv and cache installed but less functionality) + +--prefixes show supported prefixes ]] runners.applications = { @@ -10800,6 +10922,13 @@ runners.launchers = { unix = { } } +-- like runners.libpath("framework"): looks on script's subpath + +function runners.libpath(...) + package.prepend_libpath(file.dirname(environment.ownscript),...) + package.prepend_libpath(file.dirname(environment.ownname) ,...) +end + function runners.prepare() local checkname = environment.argument("ifchanged") if checkname and checkname ~= "" then @@ -10890,6 +11019,7 @@ function runners.execute_script(fullname,internal,nosplit) end if internal then arg = { } for _,v in pairs(environment.arguments_after) do arg[#arg+1] = v end + environment.ownscript = result dofile(result) else local binary = runners.applications[file.extname(result)] @@ -10993,7 +11123,7 @@ function runners.locate_file(filename) end function runners.locate_platform() - runners.report_location(os.currentplatform()) + runners.report_location(os.platform) end function runners.report_location(result) @@ -11170,6 +11300,7 @@ function runners.execute_ctx_script(filename) if logs.verbose then logs.simple("using script: %s\n",fullname) end + environment.ownscript = fullname dofile(fullname) local savename = environment.arguments['save'] if savename and runners.save_list and not table.is_empty(runners.save_list or { }) then @@ -11222,6 +11353,11 @@ function runners.execute_ctx_script(filename) end end +function runners.prefixes() + logs.reportbanner() + logs.reportline() + logs.simple(table.concat(resolvers.allprefixes(true)," ")) +end function runners.timedrun(filename) -- just for me if filename and filename ~= "" then @@ -11337,7 +11473,7 @@ elseif environment.argument("selfupdate") then elseif environment.argument("ctxlua") or environment.argument("internal") then -- run a script by loading it (using libs) ok = runners.execute_script(filename,true) -elseif environment.argument("script") or environment.argument("s") then +elseif environment.argument("script") or environment.argument("s") or environment.argument("scripts") then -- run a script by loading it (using libs), pass args ok = runners.execute_ctx_script(filename) elseif environment.argument("execute") then @@ -11366,6 +11502,8 @@ elseif environment.argument("locate") then elseif environment.argument("platform")then -- locate platform runners.locate_platform() +elseif environment.argument("prefixes") then + runners.prefixes() elseif environment.argument("timedrun") then -- locate platform runners.timedrun(filename) @@ -11375,9 +11513,9 @@ elseif environment.argument("help") or filename=='help' or filename == "" then elseif filename:find("^bin:") then ok = runners.execute_program(filename) else - ok = runners.execute_script(filename) + ok = runners.execute_ctx_script(filename) if not ok then - ok = runners.execute_ctx_script(filename) + ok = runners.execute_script(filename) end end diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv index 49a109e7d..b04282fb8 100644 --- a/tex/context/base/attr-ini.mkiv +++ b/tex/context/base/attr-ini.mkiv @@ -50,6 +50,7 @@ \definesystemattribute[reference] \chardef\referenceattribute \dogetattributeid{reference} \definesystemattribute[destination] \chardef\destinationattribute \dogetattributeid{destination} \definesystemattribute[graphicvadjust] \chardef\graphicvadjustattribute \dogetattributeid{graphicvadjust} +\definesystemattribute[ruled] \chardef\ruledattribute \dogetattributeid{ruled} % \definesystemattribute[ignore] % diff --git a/tex/context/base/bibl-tra.mkiv b/tex/context/base/bibl-tra.mkiv index 9648c068a..29a687025 100644 --- a/tex/context/base/bibl-tra.mkiv +++ b/tex/context/base/bibl-tra.mkiv @@ -288,7 +288,8 @@ {\showmessage\m!publications{1}{bibl-\@@pbalternative}}% \let\@@pbalternative\empty}% \getparameters[\??pb][#1]% as bibl-* can have set things back - \the\everysetuppublications} + \the\everysetuppublications + \ignorespaces} %D We can omit already shown references (\v!global) or use fresh %D lists each time (\v!local). @@ -334,11 +335,25 @@ \def\usepublications[#1]% {\processcommalist[#1]\dousepublications} +% \def\dousepublications#1% +% {\doonlyonce{#1.\f!bibextension} +% {\readfile{#1.\f!bibextension} +% {\showmessage\m!publications{4}{#1.\f!bibextension}} +% {\showmessage\m!publications{2}{#1.\f!bibextension}}}} + \def\dousepublications#1% - {\doonlyonce{#1.\f!bibextension} - {\readfile{#1.\f!bibextension} - {\showmessage\m!publications{4}{#1.\f!bibextension}} - {\showmessage\m!publications{2}{#1.\f!bibextension}}}} + {\doonlyonce{#1.\f!bibextension}{\dodousepublications{#1}}} + +\def\dodousepublications#1% + {\let\@@savedpar\par + \let\par\ignorespaces + \ifhmode\kern\zeropoint\fi + \readfile{#1.\f!bibextension} + {\showmessage\m!publications{4}{#1.\f!bibextension}} + {\showmessage\m!publications{2}{#1.\f!bibextension}}% + \ifhmode\removeunwantedspaces\fi + \let\par\@@savedpar} + %D \macros{setuppublicationlist} %D @@ -740,7 +755,8 @@ \@@pbo\noexpand\or \@@pbu\noexpand\or \normalunexpanded{#2}\noexpand\fi}% - \endgroup} + \endgroup + \ignorespaces} \def\bibgetvark#1{\csname pbd:#1\endcsname\plusone } \def\bibgetvara#1{\csname pbd:#1\endcsname\plustwo } diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv index cde9f5820..68636a23c 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -159,6 +159,25 @@ \let\grey\graycolor +%D Stacking: + +% \colormodelattribute \colorattribute \transparencyattribute + +\newcount\currentcolornesting + +\unexpanded\def\pushcolor[#1]% + {\global\advance\currentcolornesting\plusone + \expandafter\edef\csname\??cl:s:\number\currentcolornesting\endcsname + {\attribute\colormodelattribute \the\colormodelattribute + \attribute\colorattribute \the\colorattribute + \attribute\transparencyattribute\the\transparencyattribute + \space}% stack + \doactivatecolor{#1}} + +\unexpanded\def\popcolor + {\csname\??on:s:\number\currentcolornesting\endcsname + \global\advance\currentcolornesting\minusone} + %D \macros %D {startcurrentcolor,stopcurrentcolor} diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 93a1c17c2..fb5112020 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -29,6 +29,8 @@ \unprotect +\def\immediatemessage#1{\ctxlua{commands.writestatus("message","#1")}} + % % % % % % needs testing but saves runtime \let\checknotes\relax % probably not needed, checking already done diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 67d2d13ac..0ffa84f19 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2009.12.01 17:09} +\newcontextversion{2009.12.13 23:27} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context-base.lmx b/tex/context/base/context-base.lmx index 5c96b4979..e84202cb3 100644 --- a/tex/context/base/context-base.lmx +++ b/tex/context/base/context-base.lmx @@ -14,25 +14,62 @@ <?lua pv('title') ?> + 0) and v('refreshurl') then ?> + + + +
+ -
- -
-
- -
- -
-
-
-
- -
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 347beb0b3..51f5d92d4 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -20,8 +20,8 @@ \loadcorefile{syst-ini} -\ifnum\luatexversion<43 % also change message - \writestatus{!!!!}{Your luatex binary is way too old, you need at least version 0.43!} +\ifnum\luatexversion<47 % also change message + \writestatus{!!!!}{Your luatex binary is too old, you need at least version 0.47!} \expandafter\end \fi diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 9c9b58f83..d6a4d6897 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2009.12.01 17:09} +\edef\contextversion{2009.12.13 23:27} %D For those who want to use this: diff --git a/tex/context/base/core-job.mkiv b/tex/context/base/core-job.mkiv index 4333b3c69..71d4e4d30 100644 --- a/tex/context/base/core-job.mkiv +++ b/tex/context/base/core-job.mkiv @@ -124,7 +124,8 @@ \def\stoptext {\global\advance\textlevel\minusone \ifnum\textlevel>\zerocount \else - \page[\v!last]\page % new, moved from everybye to here; flushes headers, colors etc etc etc + \flushfinallayoutpage % optional + \page % anyway \the\everystoptext %\the\everybye % %\the\everygoodbye % == \end (new) diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua index d7f6fdcf5..3005d5176 100644 --- a/tex/context/base/data-lua.lua +++ b/tex/context/base/data-lua.lua @@ -14,43 +14,109 @@ local trace_locating = false trackers.register("resolvers.locating", function(v local gsub = string.gsub -local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -local libpaths = file.split_path(package.path) +local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs' +local clibformats = { 'lib' } +local libpaths = file.split_path(package.path) +local clibpaths = file.split_path(package.cpath) + +local function thepath(...) + local t = { ... } t[#t+1] = "?.lua" + local path = file.join(unpack(t)) + if trace_locating then + logs.report("fileio","! appending '%s' to 'package.path'",path) + end + return path +end + +function package.append_libpath(...) + table.insert(libpaths,thepath(...)) +end + +function package.prepend_libpath(...) + table.insert(libpaths,1,thepath(...)) +end + +-- beware, we need to return a loadfile result ! package.loaders[2] = function(name) -- was [#package.loaders+1] ---~ package.loaders[#package.loaders+1] = function(name) -- was + if trace_locating then -- mode detail + logs.report("fileio","! locating '%s'",name) + end for i=1,#libformats do local format = libformats[i] local resolved = resolvers.find_file(name,format) or "" + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'libformat path': '%s'",name,format) + end if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end end - local simple = file.removesuffix(name) + local simple = gsub(name,"%.lua$","") + local simple = gsub(simple,"%.","/") for i=1,#libpaths do -- package.path, might become option - local resolved = gsub(libpaths[i],"?",simple) + local libpath = libpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.path': '%s'",simple,libpath) + end if resolvers.isreadable.file(resolved) then if trace_locating then logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) + end + end + local libname = file.addsuffix(simple,os.libsuffix) + for i=1,#clibformats do + -- better have a dedicated loop + local format = clibformats[i] + local paths = resolvers.expanded_path_list_from_var(format) + for p=1,#paths do + local path = paths[p] + local resolved = file.join(path,libname) + if trace_locating then -- mode detail + logs.report("fileio","! checking for '%s' using 'clibformat path': '%s'",libname,path) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'clibformat': '%s'",libname,resolved) + end + return package.loadlib(resolved,name) + end + end + end + for i=1,#clibpaths do -- package.path, might become option + local libpath = clibpaths[i] + local resolved = gsub(libpath,"?",simple) + if trace_locating then -- more detail + logs.report("fileio","! checking for '%s' on 'package.cpath': '%s'",simple,libpath) + end + if resolvers.isreadable.file(resolved) then + if trace_locating then + logs.report("fileio","! lib '%s' located via 'package.cpath': '%s'",name,resolved) + end + return package.loadlib(resolved,name) end end -- just in case the distribution is messed up + if trace_loading then -- more detail + logs.report("fileio","! checking for '%s' using 'luatexlibs': '%s'",name) + end local resolved = resolvers.find_file(file.basename(name),'luatexlibs') or "" if resolved ~= "" then if trace_locating then logs.report("fileio","! lib '%s' located by basename via environment: '%s'",name,resolved) end - return function() return dofile(resolved) end + return loadfile(resolved) end if trace_locating then logs.report("fileio",'? unable to locate lib: %s',name) end - return "unable to locate " .. name +-- return "unable to locate " .. name end resolvers.loadlualib = require diff --git a/tex/context/base/data-pre.lua b/tex/context/base/data-pre.lua index 26843d21c..9936cd508 100644 --- a/tex/context/base/data-pre.lua +++ b/tex/context/base/data-pre.lua @@ -66,6 +66,16 @@ prefixes.full = prefixes.locate prefixes.file = prefixes.filename prefixes.path = prefixes.pathname +function resolvers.allprefixes(separator) + local all = table.sortedkeys(prefixes) + if separator then + for i=1,#all do + all[i] = all[i] .. ":" + end + end + return all +end + local function _resolve_(method,target) if prefixes[method] then return prefixes[method](target) diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index 4305d0bed..d15046e80 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -124,6 +124,11 @@ formats ['sfd'] = 'SFDFONTS' suffixes ['sfd'] = { 'sfd' } alternatives['subfont definition files'] = 'sfd' +-- lib paths + +formats ['lib'] = 'CLUAINPUTS' -- new (needs checking) +suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' } + -- In practice we will work within one tds tree, but i want to keep -- the option open to build tools that look at multiple trees, which is -- why we keep the tree specific data in a table. We used to pass the @@ -1343,9 +1348,9 @@ end function resolvers.expanded_path_list_from_var(str) -- brrr local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$","")) if tmp ~= "" then - return resolvers.expanded_path_list(str) - else return resolvers.expanded_path_list(tmp) + else + return resolvers.expanded_path_list(str) end end diff --git a/tex/context/base/data-tmf.lua b/tex/context/base/data-tmf.lua index 4ba8c388d..e02f7f866 100644 --- a/tex/context/base/data-tmf.lua +++ b/tex/context/base/data-tmf.lua @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['data-tmf'] = { function resolvers.check_environment(tree) logs.simpleline() os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.currentplatform())) + os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) logs.simpleline() diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index b59f1f6e8..c331d6065 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -651,6 +651,29 @@ local function analysefiles() data.statistics.readfiles, data.statistics.skippedfiles = totalnofread, totalnofskipped end +local function rejectclashes() -- just to be sure, so no explicit afm will be found then + local specifications, used, okay = names.data.specifications, { }, { } + for i=1,#specifications do + local s = specifications[i] + local f = s.fontname + if f then + local fnd, fnm = used[f], s.filename + if fnd then + logs.report("fontnames", "fontname '%s' clashes, rejecting '%s' in favor of '%s'",f,fnm,fnd) + else + used[f], okay[#okay+1] = fnm, s + end + else + okay[#okay+1] = s + end + end + local d = #specifications - #okay + if d > 0 then + logs.report("fontnames", "%s files rejected due to clashes",d) + end + names.data.specifications = okay +end + local function resetdata() local mappings, fallbacks = { }, { } for _, k in next, filters.list do @@ -670,12 +693,12 @@ end function names.identify() resetdata() analysefiles() + rejectclashes() collectstatistics() cleanupkeywords() collecthashes() checkduplicates() -- sorthashes() -- will be resorted when saved - --~ logs.report("fontnames", "%s files read, %s normal and %s extra entries added, %s rejected, %s valid",totalread,totalok,added,rejected,totalok+added-rejected) end @@ -838,7 +861,7 @@ local function foundname(name,sub) end end -function names.resolve(askedname,sub) +function names.resolvedspecification(askedname,sub) if askedname and askedname ~= "" and names.enabled then askedname = cleanname(askedname) names.load() @@ -846,9 +869,14 @@ function names.resolve(askedname,sub) if not found and is_reloaded() then found = foundname(askedname,sub) end - if found then - return found.filename, found.subfont and found.rawname - end + return found + end +end + +function names.resolve(askedname,sub) + local found = names.resolvedspecification(askedname,sub) + if found then + return found.filename, found.subfont and found.rawname end end diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index ff8a78f0f..25adcead5 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -666,6 +666,7 @@ function figures.includers.generic(data) end if figure then local n = figures.boxnumber + -- it looks like we have a leak in attributes here .. todo tex.box[n] = node.hpack(img.node(figure)) -- tex.box[n] = img.node(figure) -- img.write(figure) -- assigning img.node directly no longer valid tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua index db0737e5b..7ee565b30 100644 --- a/tex/context/base/l-dir.lua +++ b/tex/context/base/l-dir.lua @@ -41,6 +41,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index afe941e9d..d1e0dfafb 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = { license = "see context related readme files" } +lpeg = require("lpeg") + local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc --~ l-lpeg.lua : diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua index db8795253..dcf8d3e95 100644 --- a/tex/context/base/l-os.lua +++ b/tex/context/base/l-os.lua @@ -70,67 +70,74 @@ end --~ print(os.date("%H:%M:%S",os.gettimeofday())) --~ print(os.date("%H:%M:%S",os.time())) -os.arch = os.arch or function() - local a = os.resultof("uname -m") or "linux" +if os.arch then + -- okay +elseif os.platform == "windows" then os.arch = function() + local a = os.getenv("PROCESSOR_ARCHITECTURE") or "x86" + os.arch = function() + return a + end + return a + end +else + os.arch = function() + local a = os.getenv("PROCESSOR_ARCHITECTURE") or os.resultof("uname -m") or "x86" + os.arch = function() + return a + end return a end - return a end -local platform - -function os.currentplatform(name,default) - if not platform then - local name = os.name or os.platform or name -- os.name is built in, os.platform is mine - if not name then - platform = default or "linux" - elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then - if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then - platform = "mswin-64" - else - platform = "mswin" - end +-- no need for function anymore as we have more clever code and helpers now + +os.platform = os.name +os.libsuffix = 'so' + +local name = os.name + +if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then + if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then + os.platform = "mswin-64" + else + os.platform = "mswin" + end + os.libsuffix = 'dll' +else + local architecture = os.arch() + if name == "linux" then + if find(architecture,"x86_64") then + os.platform = "linux-64" + elseif find(architecture,"ppc") then + os.platform = "linux-ppc" + else + os.platform = "linux" + end + elseif name == "macosx" then + local architecture = os.resultof("echo $HOSTTYPE") + if find(architecture,"i386") then + os.platform = "osx-intel" + elseif find(architecture,"x86_64") then + os.platform = "osx-64" else - local architecture = os.arch() - if name == "linux" then - if find(architecture,"x86_64") then - platform = "linux-64" - elseif find(architecture,"ppc") then - platform = "linux-ppc" - else - platform = "linux" - end - elseif name == "macosx" then - local architecture = os.resultof("echo $HOSTTYPE") - if find(architecture,"i386") then - platform = "osx-intel" - elseif find(architecture,"x86_64") then - platform = "osx-64" - else - platform = "osx-ppc" - end - elseif name == "sunos" then - if find(architecture,"sparc") then - platform = "solaris-sparc" - else -- if architecture == 'i86pc' - platform = "solaris-intel" - end - elseif name == "freebsd" then - if find(architecture,"amd64") then - platform = "freebsd-amd64" - else - platform = "freebsd" - end - else - platform = default or name - end + os.platform = "osx-ppc" end - function os.currentplatform() - return platform + elseif name == "sunos" then + if find(architecture,"sparc") then + os.platform = "solaris-sparc" + else -- if architecture == 'i86pc' + os.platform = "solaris-intel" end + elseif name == "freebsd" then + if find(architecture,"amd64") then + os.platform = "freebsd-amd64" + else + os.platform = "freebsd" + end + else + os.platform = 'linux' end - return platform end -- beware, we set the randomseed diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua index 0ee6d86d1..c27d7098f 100644 --- a/tex/context/base/l-string.lua +++ b/tex/context/base/l-string.lua @@ -194,6 +194,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -255,3 +256,16 @@ function string:striplong() -- strips newlines and leading spaces self = gsub(self,"[\n\r]+ *","\n") return self end + +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua index a3b45028a..290234d56 100644 --- a/tex/context/base/l-unicode.lua +++ b/tex/context/base/l-unicode.lua @@ -6,13 +6,34 @@ if not modules then modules = { } end modules ['l-unicode'] = { license = "see context related readme files" } +if not unicode then + + unicode = { utf8 = { } } + + local floor, char = math.floor, string.char + + function unicode.utf8.utfchar(n) + if n < 0x80 then + return char(n) + elseif n < 0x800 then + return char(0xC0 + floor(n/0x40)) .. char(0x80 + (n % 0x40)) + elseif n < 0x10000 then + return char(0xE0 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + elseif n < 0x40000 then + return char(0xF0 + floor(n/0x40000)) .. char(0x80 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + else -- wrong: + -- return char(0xF1 + floor(n/0x1000000)) .. char(0x80 + floor(n/0x40000)) .. char(0x80 + floor(n/0x1000)) .. char(0x80 + (floor(n/0x40) % 0x40)) .. char(0x80 + (n % 0x40)) + return "?" + end + end + +end + utf = utf or unicode.utf8 local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub local char, byte, find, bytepairs = string.char, string.byte, string.find, string.bytepairs -unicode = unicode or { } - -- 0 EF BB BF UTF-8 -- 1 FF FE UTF-16-little-endian -- 2 FE FF UTF-16-big-endian diff --git a/tex/context/base/l-xml.lua b/tex/context/base/l-xml.lua index 921a4edb1..14e97337b 100644 --- a/tex/context/base/l-xml.lua +++ b/tex/context/base/l-xml.lua @@ -11,13 +11,13 @@ if not modules then modules = { } end modules ['l-xml'] = { -- all is taken care of. if not trackers then - require('trac-tra.lua') + require('trac-tra') end if not xml then - require('lxml-tab.lua') - require('lxml-lpt.lua') - require('lxml-mis.lua') - require('lxml-aux.lua') - require('lxml-xml.lua') + require('lxml-tab') + require('lxml-lpt') + require('lxml-mis') + require('lxml-aux') + require('lxml-xml') end diff --git a/tex/context/base/lpdf-ini.mkiv b/tex/context/base/lpdf-ini.mkiv index cfc416216..bea9a5404 100644 --- a/tex/context/base/lpdf-ini.mkiv +++ b/tex/context/base/lpdf-ini.mkiv @@ -258,4 +258,13 @@ \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox \egroup} +\unexpanded\def\pdfactualtext#1#2% + {\pdfliteral direct{/Span <> BDC}% + #1% + \pdfliteral direct{EMC}} + +% \starttext +% text \pdfactualtext{Meier}{Müller} text +% \stoptext + \protect \endinput diff --git a/tex/context/base/lxml-mis.lua b/tex/context/base/lxml-mis.lua index 74c264d0c..864ab75a1 100644 --- a/tex/context/base/lxml-mis.lua +++ b/tex/context/base/lxml-mis.lua @@ -11,7 +11,7 @@ local type, next, tonumber, tostring, setmetatable, loadstring = type, next, ton local format, gsub = string.format, string.gsub --[[ldx-- -

The following helper functions best belong to the lmxl-ini +

The following helper functions best belong to the lxml-ini module. Some are here because we need then in the mk document and other manuals, others came up when playing with this module. Since this module is also used in we've diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index 0305b889e..f5ff3b9c8 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -43,8 +43,6 @@ local trace_comments = false trackers.register("lxml.comments", function(v) tra lxml = lxml or { } lxml.loaded = lxml.loaded or { } -lxml.noffiles = 0 -lxml.nofconverted = 0 local loaded = lxml.loaded @@ -325,8 +323,7 @@ xml.originalload = xml.originalload or xml.load local noffiles, nofconverted = 0, 0 function xml.load(filename) - noffiles = noffiles + 1 - nofconverted = nofconverted + 1 + noffiles, nofconverted = noffiles + 1, nofconverted + 1 starttiming(xml) local ok, data = resolvers.loadbinfile(filename) local xmltable = xml.convert((ok and data) or "") @@ -357,6 +354,7 @@ function lxml.load(id,filename,compress,entities) if trace_loading then commands.writestatus("lxml","loading file '%s' as '%s'",filename,id) end + noffiles, nofconverted = noffiles + 1, nofconverted + 1 -- local xmltable = xml.load(filename) local ok, data = resolvers.loadbinfile(filename) local xmltable = lxml.convert(id,(ok and data) or "",compress,entities) @@ -1301,9 +1299,10 @@ statistics.register("xml load time", function() end) statistics.register("lxml preparation time", function() - if noffiles > 0 or nofconverted > 0 then + local calls, cached = xml.lpathcalls(), xml.lpathcached() + if calls > 0 or cached > 0 then return format("%s seconds, %s nodes, %s lpath calls, %s cached calls", - statistics.elapsedtime(lxml), nofindices, xml.lpathcalls(), xml.lpathcached()) + statistics.elapsedtime(lxml), nofindices, calls, cached) else return nil end diff --git a/tex/context/base/math-dim.lua b/tex/context/base/math-dim.lua index b1e9635ae..754ca8314 100644 --- a/tex/context/base/math-dim.lua +++ b/tex/context/base/math-dim.lua @@ -260,9 +260,8 @@ function mathematics.dimensions(dimens) FractionNumeratorGapMin = t . fraction_num_vgap . text_style, FractionNumeratorShiftUp = t . fraction_num_up . text_style, FractionRuleThickness = t . fraction_rule . text_style, ---~ not yet in my bin : ---~ FractionDelimiterSize = t . fraction_del_size . text_style, ---~ FractionDelimiterDisplayStyleSize = t . fraction_del_size . display_style, + FractionDelimiterSize = t . fraction_del_size . text_style, + FractionDelimiterDisplayStyleSize = t . fraction_del_size . display_style, LowerLimitBaselineDropMin = t . limit_below_bgap . text_style, LowerLimitGapMin = t . limit_below_vgap . text_style, OverbarExtraAscender = t . overbar_kern . text_style, diff --git a/tex/context/base/node-rul.mkiv b/tex/context/base/node-rul.mkiv index ba2f0aed3..0beae198c 100644 --- a/tex/context/base/node-rul.mkiv +++ b/tex/context/base/node-rul.mkiv @@ -1,5 +1,5 @@ %D \module -%D [ file=node-bar, +%D [ file=node-rul, %D version=2009.11.03, % 1995.10.10, %D title=\CONTEXT\ Core Macros, %D subtitle=Bars, @@ -57,8 +57,8 @@ \unprotect -\definesystemattribute[ruled] -\definesystemattribute[shifted] +%definesystemattribute[ruled] +%definesystemattribute[shifted] \registerctxluafile{node-rul}{1.001} @@ -137,15 +137,16 @@ \unexpanded\def\stopbar {\endgroup} -\newcount\currentbarnesting +\newcount\currentbarnesting % todo: same as colors \unexpanded\def\pushbar[#1]% {\global\advance\currentbarnesting\plusone - \setevalue{\??on:s:\number\currentbarnesting}{\dogetattribute{ruled}}% stack + \expandafter\edef\csname\??on:s:\number\currentbarnesting\endcsname + {\attribute\ruledattribute\the\ruledattribute}% stack \dodoruled{#1}} \unexpanded\def\popbar - {\dosetattribute{ruled}{\getvalue{\??on:s:\number\currentbarnesting}}% + {\csname\??on:s:\number\currentbarnesting\endcsname \global\advance\currentbarnesting\minusone} \def\setupbars diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index f243c9cd0..f709a8a6a 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -137,11 +137,12 @@ function nodes.tracers.characters.start() end function nodes.tracers.characters.stop() tracers.list['characters'] = list - lmx.set('title', 'ConTeXt Character Processing Information') - lmx.set('color-background-one', lmx.get('color-background-yellow')) - lmx.set('color-background-two', lmx.get('color-background-purple')) - lmx.show('context-characters.lmx') - lmx.restore() + local variables = { + ['title'] = 'ConTeXt Character Processing Information', + ['color-background-one'] = lmx.get('color-background-yellow'), + ['color-background-two'] = lmx.get('color-background-purple'), + } + lmx.show('context-characters.lmx',variables) nodes.process_characters = npc tasks.restart("processors", "characters") end diff --git a/tex/context/base/page-set.mkii b/tex/context/base/page-set.mkii index 6724ca979..eb01799ae 100644 --- a/tex/context/base/page-set.mkii +++ b/tex/context/base/page-set.mkii @@ -2277,6 +2277,7 @@ \v!right=>\doglobal\addtocommalist{#1}\columnrightareas]% \getparameters[\??mt#1#2] [\c!x=1,\c!y=1,\c!nx=1,\c!ny=1,\c!clipoffset=2\lineheight, + \c!leftoffset=\zeropoint,\c!rightoffset=\zeropoint, \c!offset=\v!overlay,\c!strut=\v!no,\c!frame=\v!off, \c!type=#2,\c!page=1,\c!state=\v!stop,#3]}}% \else @@ -2427,7 +2428,8 @@ %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!leftoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% - \c!rightoffset=\zeropoint,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!rightoffset=\columntextareaparameter\c!rightoffset,% \c!width=\!!widthb,% \c!height=\!!heighta]% {\copy\scratchbox}% @@ -2444,7 +2446,8 @@ %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!rightoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% - \c!leftoffset=\zeropoint,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!leftoffset=\columntextareaparameter\c!leftoffset,% \c!width=\!!widtha,% \c!height=\!!heighta,% \c!hoffset=\!!widthb]% diff --git a/tex/context/base/page-set.mkiv b/tex/context/base/page-set.mkiv index 7e825d76d..ca256d97c 100644 --- a/tex/context/base/page-set.mkiv +++ b/tex/context/base/page-set.mkiv @@ -2183,6 +2183,7 @@ \v!right=>\doglobal\addtocommalist{#1}\columnrightareas]% \getparameters[\??mt#1#2] [\c!x=1,\c!y=1,\c!nx=1,\c!ny=1,\c!clipoffset=2\lineheight, + \c!leftoffset=\zeropoint,\c!rightoffset=\zeropoint, \c!offset=\v!overlay,\c!strut=\v!no,\c!frame=\v!off, \c!type=#2,\c!page=1,\c!state=\v!stop,#3]}}% \else @@ -2333,7 +2334,8 @@ %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!leftoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% - \c!rightoffset=\zeropoint,% + \c!offset=\columntextareaparameter\c!clipoffset,% + \c!rightoffset=\columntextareaparameter\c!rightoffset,% \c!width=\!!widthb,% \c!height=\!!heighta]% {\copy\scratchbox}% @@ -2350,7 +2352,7 @@ %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!rightoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% - \c!leftoffset=\zeropoint,% + \c!leftoffset=\columntextareaparameter\c!leftoffset,% \c!width=\!!widtha,% \c!height=\!!heighta,% \c!hoffset=\!!widthb]% diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv index fb3a9e794..fca5624ec 100644 --- a/tex/context/base/spac-hor.mkiv +++ b/tex/context/base/spac-hor.mkiv @@ -156,7 +156,7 @@ \noindent\hskip\parindent \fi \fi} -\def\toggleindentation +\def\toggleindentation % does not play well with noindentation {\ifcase\indentingtoggle % nothing \or diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv index b21ae8bc4..4bcee80ea 100644 --- a/tex/context/base/strc-pag.mkiv +++ b/tex/context/base/strc-pag.mkiv @@ -317,6 +317,9 @@ \ifdefined \recalculatebackgrounds \recalculatebackgrounds \fi \to \everysetuppagenumbering +\def\flushfinallayoutpage + {\doifsomething\@@nmpage{\doifnot\@@nmpage\v!no{\page[\@@nmpage]}}} + % The numbered location handler is there because we need to be downward % compatible. So, in fact there can be multiple handlers active at the % same time, but only the current one does something. @@ -441,6 +444,7 @@ \c!width=, % in geval van \v!marginedge \c!left=, \c!right=, + \c!page=\v!last, \c!textseparator=\tfskip, \c!state=\v!start, \c!command=, diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 42118436e..8cc63d50e 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -198,7 +198,7 @@ local function register_from_lists(collected,derived) local t = { kind, i } for s in gmatch(reference,"%s*([^,]+)") do if trace_referencing then - logs.report("referencing","list entry %s provides %s reference '%s' on realpage %s)",i,kind,s,realpage) + logs.report("referencing","list entry %s provides %s reference '%s' on realpage %s",i,kind,s,realpage) end d[s] = t -- share them end @@ -860,15 +860,17 @@ function jobreferences.filter(name,...) -- number page title ... local filter = filters[kind] or filters.generic filter = filter and (filter[name] or filter.unknown or filters.generic[name] or filters.generic.unknown) if filter then + logs.report("referencing","name '%s', kind '%s', using dedicated filter",name,kind) +--~ print(table.serialize {...}) filter(data,name,...) elseif trace_referencing then - logs.report("referencing","no (generic) filter.name for '%s'",name) + logs.report("referencing","name '%s', kind '%s', using generic filter",name,kind) end elseif trace_referencing then - logs.report("referencing","no metadata.kind for '%s'",name) + logs.report("referencing","name '%s', unknown kind",name) end elseif trace_referencing then - logs.report("referencing","no current reference for '%s'",name) + logs.report("referencing","name '%s', no reference",name) end end @@ -892,12 +894,13 @@ function filters.generic.text(data) end end -function filters.generic.number(data,what,...) -- todo: spec and then no stopper +function filters.generic.number(data,what,prefixspec) -- todo: spec and then no stopper if data then local numberdata = data.numberdata if numberdata then - helpers.prefix(data,...) - sections.typesetnumber(numberdata,"number",numberdata or false) +--~ print(table.serialize(prefixspec)) + helpers.prefix(data,prefixspec) + sections.typesetnumber(numberdata,"number",numberdata) else local useddata = data.useddata if useddata and useddsta.number then @@ -964,11 +967,11 @@ end filters.section = { } -function filters.section.number(data) -- todo: spec and then no stopper +function filters.section.number(data,what,prefixspec) if data then local numberdata = data.numberdata if numberdata then - sections.typesetnumber(numberdata,"number",numberdata or false) + sections.typesetnumber(numberdata,"number",prefixspec,numberdata) else local useddata = data.useddata if useddata and useddata.number then diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv index d54d75207..cbed71d68 100644 --- a/tex/context/base/strc-ref.mkiv +++ b/tex/context/base/strc-ref.mkiv @@ -13,14 +13,17 @@ % todo: (1) configure references, (2) rendering => with presets % -% \starttext -% \definestructureconversionset[default][Character,number,Romannumerals,Character][number] -% \definestructureseparatorset [default][.,.,--][.] -% \setupstructurehead[subsection][sectionstopper=),sectionsegments=4:4] - -% \setupreferencing[sectionsegments=3:4] -% \section {One} \subsection[sec:test]{Two} See \in[sec:test] -% \stoptext +% \definestructureconversionset[default][Character,number,Romannumerals,Character][number] +% \definestructureseparatorset [default][.,.,--][.] +% \setupstructurehead[subsection][sectionstopper=),sectionsegments=4:4] +% \setupreferencestructureprefix[default][prefixsegments=2:4] +% \setupreferencestructureprefix[figure][default][prefixsegments=3:4] +% \chapter {One} +% \section {One} +% \subsection[sec:test]{Two} +% See \in[sec:test] and \in[fig:xx] and \in[fig:yy] +% \placefigure[here][fig:xx]{}{} +% \placefigure[here][fig:yy]{}{} \writestatus{loading}{ConTeXt Structure Macros / Cross Referencing} @@ -1780,7 +1783,7 @@ % {\ctxlua{jobreferences.get_current_metadata("name")}} % {#1}} % \def\currentreferencedefault -% {\ctxlua{jobreferences.filter("default",\referencestructureprefixspec\v!default)}} +% {\ctxlua{jobreferences.filter("default",\getreferencestructureprefixspec\v!default)}} % % this is shortcut for: diff --git a/tex/context/base/syst-ini.tex b/tex/context/base/syst-ini.tex index 0c3770294..51e78e67b 100644 --- a/tex/context/base/syst-ini.tex +++ b/tex/context/base/syst-ini.tex @@ -805,8 +805,8 @@ \ifdefined\pdfgentounicode \else \newcount\pdfgentounicode \fi \pdfgentounicode\plusone \def\nopdfcompression {\pdfobjcompresslevel\zerocount \pdfcompresslevel\zerocount} - \def\maximumpdfcompression{\pdfobjcompresslevel\plusone \pdfcompresslevel\plusnine } - \def\normalpdfcompression {\pdfobjcompresslevel\plusone \pdfcompresslevel\plusthree} + \def\maximumpdfcompression{\pdfobjcompresslevel\plusnine \pdfcompresslevel\plusnine } + \def\normalpdfcompression {\pdfobjcompresslevel\plusthree \pdfcompresslevel\plusthree} \normalpdfcompression diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 4cd324922..08252c6c9 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -9,19 +9,6 @@ if not modules then modules = { } end modules ['trac-deb'] = { if not lmx then lmx = { } end if not lmx.variables then lmx.variables = { } end -lmx.variables['color-background-green'] = '#4F6F6F' -lmx.variables['color-background-blue'] = '#6F6F8F' -lmx.variables['color-background-yellow'] = '#8F8F6F' -lmx.variables['color-background-purple'] = '#8F6F8F' - -lmx.variables['color-background-body'] = '#808080' -lmx.variables['color-background-main'] = '#3F3F3F' -lmx.variables['color-background-one'] = lmx.variables['color-background-green'] -lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - -lmx.variables['title-default'] = 'ConTeXt Status Information' -lmx.variables['title'] = lmx.variables['title-default'] - lmx.htmfile = function(name) return environment.jobname .. "-status.html" end lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end @@ -82,30 +69,30 @@ function tracers.knownlist(name) end function tracers.showdebuginfo() - lmx.set('title', 'ConTeXt Debug Information') - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - lmx.show('context-debug.lmx') - lmx.restore() + local variables = { + ['title'] = 'ConTeXt Debug Information', + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + } + lmx.show('context-debug.lmx',variables) end function tracers.showerror() - lmx.set('title', 'ConTeXt Error Information') - lmx.set('errormessage', status.lasterrorstring) - lmx.set('linenumber', status.linenumber) - lmx.set('color-background-one', lmx.get('color-background-yellow')) - lmx.set('color-background-two', lmx.get('color-background-purple')) local filename = status.filename local linenumber = tonumber(status.linenumber or "0") + local variables = { + ['title'] = 'ConTeXt Error Information', + ['errormessage'] = status.lasterrorstring, + ['linenumber'] = status.linenumber, + ['color-background-one'] = lmx.get('color-background-yellow'), + ['color-background-two'] = lmx.get('color-background-purple'), + } if not filename then - lmx.set('filename', 'unknown') - lmx.set('errorcontext', 'error in filename') + variables.filename, variables.errorcontext = 'unknown', 'error in filename' elseif type(filename) == "number" then - lmx.set('filename', "") - lmx.set('errorcontext', 'unknown error') + variables.filename, variables.errorcontext = "", 'unknown error' elseif io.exists(filename) then -- todo: use an input opener so that we also catch utf16 an reencoding - lmx.set('filename', filename) lines = io.lines(filename) if lines then local context = { } @@ -124,16 +111,14 @@ function tracers.showerror() end n = n + 1 end - lmx.set('errorcontext', table.concat(context,"\n")) + variables.filename, variables.errorcontext = filename, table.concat(context,"\n") else - lmx.set('errorcontext', "") + variables.filename, variables.errorcontext = filename, "" end else - lmx.set('filename', filename) - lmx.set('errorcontext', 'file not found') + variables.filename, variables.errorcontext = filename, 'file not found' end - lmx.show('context-error.lmx') - lmx.restore() + lmx.show('context-error.lmx',variables) end function tracers.overloaderror() diff --git a/tex/context/base/trac-lmx.lua b/tex/context/base/trac-lmx.lua index a39e3fe4e..a272564de 100644 --- a/tex/context/base/trac-lmx.lua +++ b/tex/context/base/trac-lmx.lua @@ -1,72 +1,128 @@ if not modules then modules = { } end modules ['trac-lmx'] = { - version = 1.001, + version = 1.002, comment = "companion to trac-lmx.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -local gsub, format, concat = string.gsub, string.format, table.concat +-- todo: use lpeg instead (although not really needed) --- we can now use l-xml, and we can also use lpeg +local gsub, format, concat, byte = string.gsub, string.format, table.concat, string.byte lmx = lmx or { } -lmx.escapes = { +local escapes = { ['&'] = '&', ['<'] = '<', ['>'] = '>', ['"'] = '"' } --- local function p -> ends up in lmx.p, so we need to cast - -lmx.variables = { } - -lmx.variables['title-default'] = 'LMX File' -lmx.variables['title'] = lmx.variables['title-default'] - --- demonstrates: local, *all, gsub using tables, nil or value, loadstring - -function lmx.loadedfile(filename) - return io.loaddata(resolvers.find_file(filename)) -end - -lmx.converting = false - -local templates = { } - -function lmx.convert(template,result) -- todo: use lpeg instead - if not lmx.converting then -- else, if error then again tex error and loop - local data = templates[template] - if not data then - data = lmx.loadedfile(template) - templates[template] = data - end - local text = { } - function lmx.print(...) - text[#text+1] = concat({...}) - end - function lmx.variable(str) - return lmx.variables[str] or "" - end - function lmx.escape(str) - str = tostring(str) - str = gsub(str,'&','&') - str = gsub(str,'[<>"]',lmx.escapes) - return str - end - function lmx.type(str) - if str then lmx.print("" .. lmx.escape(str) .. "") end - end - function lmx.pv(str) - lmx.print(lmx.variable(str)) - end - function lmx.tv(str) - lmx.type(lmx.variable(str)) - end +-- variables + +lmx.variables = { } -- global, shared + +local lmxvariables = lmx.variables + +lmxvariables['title-default'] = 'ConTeXt LMX File' +lmxvariables['title'] = lmx.variables['title-default'] +lmxvariables['color-background-green'] = '#4F6F6F' +lmxvariables['color-background-blue'] = '#6F6F8F' +lmxvariables['color-background-yellow'] = '#8F8F6F' +lmxvariables['color-background-purple'] = '#8F6F8F' +lmxvariables['color-background-body'] = '#808080' +lmxvariables['color-background-main'] = '#3F3F3F' +lmxvariables['color-background-one'] = lmxvariables['color-background-green'] +lmxvariables['color-background-two'] = lmxvariables['color-background-blue'] + +function lmx.set(key, value) + lmxvariables[key] = value +end + +function lmx.get(key) + return lmxvariables[key] or "" +end + +-- helpers + +local variables, result = { } -- we assume no nesting + +local function do_print(one,two,...) + if two then + result[#result+1] = concat { one, two, ... } + else + result[#result+1] = one + end +end + +local function do_escape(str) + str = tostring(str) + str = gsub(str,'&','&') + str = gsub(str,'[<>"]',escapes) + return str +end + +local function do_urlescaped(str) + return (gsub(str,"[^%a%d]",format("%%0x",byte("%1")))) +end + +function do_type(str) + if str then do_print("" .. do_escape(str) .. "") end +end + +local function do_variable(str) + return variables[str] or lmxvariables[str] -- or format("",str or "?") +end + +function lmx.loadedfile(name) + name = (resolvers and resolvers.find_file and resolvers.find_file(name)) or name + return io.loaddata(name) +end + +local function do_include(filename) + local stylepath = do_variable('includepath') + local data = lmx.loadedfile(filename) + if (not data or data == "") and stylepath ~= "" then + data = lmx.loadedfile(file.join(stylepath,filename)) + end + if not data or data == "" then + data = format("",filename) + end + return data +end + +lmx.print = do_print +lmx.type = do_type +lmx.escape = do_escape +lmx.urlescape = do_escape +lmx.variable = do_variable +lmx.include = do_include + +function lmx.pv(str) + do_print(do_variable(str) or "") +end + +function lmx.tv(str) + lmx.type(do_variable(str) or "") +end + +local template = [[ + local definitions = { } + local p, v, e, t, pv, tv = lmx.print, lmx.variable, lmx.escape, lmx.type, lmx.pv, lmx.tv + %s +]] + +local cache = { } + +local trace = false + +function lmx.new(data,variables) + local known = cache[data] + if not known then + local definitions = { } data = gsub(data,"<%?lmx%-include%s+(.-)%s-%?>", function(filename) - return lmx.loadedfile(filename) + return lmx.include(filename) end) local definitions = { } data = gsub(data,"<%?lmx%-define%-begin%s+(%S-)%s-%?>(.-)<%?lmx%-define%-end%s-%?>", function(tag,content) @@ -76,33 +132,60 @@ function lmx.convert(template,result) -- todo: use lpeg instead data = gsub(data,"<%?lmx%-resolve%s+(%S-)%s-%?>", function(tag) return definitions[tag] or "" end) - data = gsub(data,"%c%s-(<%?lua .-%?>)%s-%c", function(lua) - return "\n" .. lua .. " " - end) - data = gsub(data .. "","(.-)<%?lua%s+(.-)%?>", function(txt, lua) - txt = gsub(txt,"%c+", "\\n") - txt = gsub(txt,'"' , '\\"') - txt = gsub(txt,"'" , "\\'") - -- txt = gsub(txt,"([\'\"])", { ["'"] = '\\"', ['"'] = "\\'" } ) - return "p(\"" .. txt .. "\")\n" .. lua .. "\n" + data = gsub(data .. "","(.-)<%?lua%s+(.-)%s*%?>", function(txt,lua) + txt = gsub(txt,"%c+","\n") + return format("p(%q)%s ",txt,lua) -- nb! space end) - lmx.converting = true - data = "local p,v,e,t,pv,tv = lmx.print,lmx.variable,lmx.escape,lmx.type,lmx.pv,lmx.tv " .. data - assert(loadstring(data))() - lmx.converting = false - text = concat(text) - if result then - io.savedata(result,text) - else - return text - end + data = format(template,data) + known = { + data = trace and data, + variables = variables or { }, + converter = loadstring(data), + } + elseif variables then + known.variables = variables + end + return known, known.variables +end + +function lmx.reset(self) + self.variables = { } +end + +function lmx.result(self) + if trace then + return self.data + else + variables, result = self.variables, { } + self.converter() + return concat(result) + end +end + +-- file converter + +local loaded = { } + +function lmx.convert(templatefile,resultfile,variables) + local data = loaded[templatefile] + if not data then + data = lmx.new(lmx.loadedfile(templatefile),variables) + loaded[template] = data + elseif variables then + data.variables = variables + end + local result = lmx.result(data) + if resultfile then + io.savedata(resultfile,result) + else + return lmx.result(data,result) end end -- these can be overloaded; we assume that the os handles filename associations -lmx.lmxfile = function(filename) return filename end -lmx.htmfile = function(filename) return filename end +lmx.lmxfile = function(filename) return filename end -- beware, these can be set! +lmx.htmfile = function(filename) return filename end -- beware, these can be set! if os.platform == "windows" then lmx.popupfile = function(filename) os.execute("start " .. filename) end @@ -110,44 +193,25 @@ else lmx.popupfile = function(filename) os.execute(filename) end end -function lmx.make(name) +function lmx.make(name,variables) local lmxfile = lmx.lmxfile(name) local htmfile = lmx.htmfile(name) if lmxfile == htmfile then htmfile = gsub(lmxfile, "%.%a+$", "html") end - lmx.convert(lmxfile, htmfile) + lmx.convert(lmxfile,htmfile,variables) return htmfile end -function lmx.show(name) - local htmfile = lmx.make(name) +function lmx.show(name,variables) + local htmfile = lmx.make(name,variables) lmx.popupfile(htmfile) return htmfile end --- kind of private - -lmx.restorables = { } - -function lmx.set(key, value) - if not lmx.restorables[key] then - table.insert(lmx.restorables, key) - lmx.variables['@@' .. key] = lmx.variables[key] - end - lmx.variables[key] = value -end - -function lmx.get(key) - return lmx.variables[key] or "" -end +-- test -function lmx.restore() - for _,key in pairs(lmx.restorables) do - lmx.variables[key] = lmx.variables['@@' .. key] - end - lmx.restorables = { } -end +--~ print(lmx.result(lmx.new(io.loaddata("t:/sources/context-timing.lmx")))) -- command line diff --git a/tex/context/base/trac-tim.lua b/tex/context/base/trac-tim.lua index 82c03f4c7..a896d767f 100644 --- a/tex/context/base/trac-tim.lua +++ b/tex/context/base/trac-tim.lua @@ -26,7 +26,7 @@ local params = { "pdf_mem_ptr", "pdf_mem_size", "pdf_os_cntr", - "pool_ptr", +-- "pool_ptr", -- obsolete "str_ptr", } @@ -36,12 +36,8 @@ local last = os.clock() local data = { } function progress.save() - local f = io.open((name or progress.defaultfilename) .. ".lut","w") - if f then - f:write(table.serialize(data,true)) - f:close() - data = { } - end + io.savedata((name or progress.defaultfilename) .. ".lut",table.serialize(data,true)) + data = { } end function progress.store() @@ -61,32 +57,7 @@ end local processed = { } -function progress.bot(name,tag) - local d = progress.convert(name) - return d.bot[tag] or 0 -end -function progress.top(name,tag) - local d = progress.convert(name) - return d.top[tag] or 0 -end -function progress.pages(name,tag) - local d = progress.convert(name) - return d.pages or 0 -end -function progress.path(name,tag) - local d = progress.convert(name) - return d.paths[tag] or "origin" -end -function progress.nodes(name) - local d = progress.convert(name) - return d.names or { } -end -function progress.parameters(name) - local d = progress.convert(name) - return params -- shared -end - -function progress.convert(name) +local function convert(name) name = ((name ~= "") and name) or progress.defaultfilename if not processed[name] then local names, top, bot, pages, paths, keys = { }, { }, { }, 0, { }, { } @@ -161,3 +132,24 @@ function progress.convert(name) end return processed[name] end + +progress.convert = convert + +function progress.bot(name,tag) + return convert(name).bot[tag] or 0 +end +function progress.top(name,tag) + return convert(name).top[tag] or 0 +end +function progress.pages(name,tag) + return convert(name).pages or 0 +end +function progress.path(name,tag) + return convert(name).paths[tag] or "origin" +end +function progress.nodes(name) + return convert(name).names or { } +end +function progress.parameters(name) + return params -- shared +end diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua index 56ce36a05..d9ded1cfa 100644 --- a/tex/context/base/typo-spa.lua +++ b/tex/context/base/typo-spa.lua @@ -56,7 +56,7 @@ function spacings.process(namespace,attribute,head) local map = mapping[attr] if map then map = map[start.char] - unset_attribute(start,attribute) + unset_attribute(start,attribute) -- needed? if map then local left, right, alternative = map.left, map.right, map.alternative local quad = fontdata[start.font].parameters.quad diff --git a/tex/context/base/verb-eif.mkii b/tex/context/base/verb-eif.mkii index 5904abc6e..68c84d4be 100644 --- a/tex/context/base/verb-eif.mkii +++ b/tex/context/base/verb-eif.mkii @@ -64,7 +64,7 @@ %D We borrow most of the macros from the \PERL\ driver. -\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \unprotect diff --git a/tex/context/base/verb-ini.mkii b/tex/context/base/verb-ini.mkii index 4726d0eac..829e10fd8 100644 --- a/tex/context/base/verb-ini.mkii +++ b/tex/context/base/verb-ini.mkii @@ -1455,11 +1455,8 @@ \ifCONTEXT \else - \input verb-tex - \input verb-mp - \input verb-pl - \input verb-jv - \input verb-sql + \input verb-tex.mkii + \input verb-mp.mkii \def\startTEX {\bgroup \everypar{}% @@ -1471,26 +1468,8 @@ \let\obeycharacters\setupprettyMPtype \processdisplayverbatim{\stopMP}} - \def\startPL - {\bgroup \everypar{}% - \let\obeycharacters\setupprettyPLtype - \processdisplayverbatim{\stopPL}} - - \def\startJV - {\bgroup \everypar{}% - \let\obeycharacters\setupprettyJVtype - \processdisplayverbatim{\stopJV}} - - \def\startSQL - {\bgroup \everypar{}% - \let\obeycharacters\setupprettySQLtype - \processdisplayverbatim{\stopSQL}} - \let\stopTEX=\egroup \let\stopMP =\egroup - \let\stopPL =\egroup - \let\stopJV =\egroup - \let\stopSQL=\egroup \fi diff --git a/tex/context/base/verb-js.mkii b/tex/context/base/verb-js.mkii index 3d1b69f8b..e497e475b 100644 --- a/tex/context/base/verb-js.mkii +++ b/tex/context/base/verb-js.mkii @@ -32,7 +32,7 @@ %D a slightly adapted \PERL\ visualization. First we load the %D \PERL\ module: -\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \unprotect diff --git a/tex/context/base/verb-jv.mkii b/tex/context/base/verb-jv.mkii index 197b37ee7..ee79e5c03 100644 --- a/tex/context/base/verb-jv.mkii +++ b/tex/context/base/verb-jv.mkii @@ -22,7 +22,7 @@ %D driver looks much like the \JAVASCRIPT\ one, we don't %D comment it extensively. -\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \unprotect diff --git a/tex/context/base/verb-pas.mkii b/tex/context/base/verb-pas.mkii index 0c9850abf..71c0b5a12 100644 --- a/tex/context/base/verb-pas.mkii +++ b/tex/context/base/verb-pas.mkii @@ -36,7 +36,7 @@ %D [palet=,icommand=\bf,vcommand=,ccommand=\it] %D \stopbuffer -\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \unprotect diff --git a/tex/context/base/verb-raw.mkii b/tex/context/base/verb-raw.mkii index 32903db77..43a0891a0 100644 --- a/tex/context/base/verb-raw.mkii +++ b/tex/context/base/verb-raw.mkii @@ -1,7 +1,7 @@ -\ifx\undefined\setupprettyTEXtype \input verb-tex \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \gdef\setupprettyRAWtype% {\setupprettyTEXtype \def\prettyidentifier{RAW}} - -\endinput + +\endinput diff --git a/tex/context/base/verb-sql.mkii b/tex/context/base/verb-sql.mkii index a00841d73..f145607f8 100644 --- a/tex/context/base/verb-sql.mkii +++ b/tex/context/base/verb-sql.mkii @@ -49,7 +49,7 @@ %D Like we did with the \JAVASCRIPT\ driver, we will borrow %D most of the macros from the \PERL\ driver. -\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi +\ifdefined\setupprettyPLtype \else \loadmarkfile{verb-pl} \fi \unprotect diff --git a/tex/context/base/x-dir-05.mkii b/tex/context/base/x-dir-05.mkii new file mode 100644 index 000000000..0d0edd832 --- /dev/null +++ b/tex/context/base/x-dir-05.mkii @@ -0,0 +1,51 @@ +%D \module +%D [ file=x-dir-05, +%D version=2003.05.10, % around that time -) +%D title=\CONTEXT\ Directory Handling, +%D subtitle=Access, +%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. + +\setvariables + [filestate] + [name=,base=,type=,size=,permissions=,date=] + +\def\savefilestate + {\dodoubleargument\dosavefilestate} + +\def\dosavefilestate[#1][#2]% + {\startnointerference + \setxvariables + [#1] + [name=#2,base=,type=,size=,permissions=,date=] + \executesystemcommand{texmfstart xmltools.rb --dir --pattern=\getvariable{#1}{name} --output=xmldir.tmp} + \defineXMLprocess [files] + \defineXMLprocess [directory] + \defineXMLenvironment [file] + {\defineXMLsave [base] + \defineXMLsave [type] + \defineXMLsave [size] + \defineXMLsave [permissions] + \defineXMLsave [date]} + {\setxvariables + [#1] + [name=\XMLop{name}, + base=\XMLflush{base}, + type=\XMLflush{type}, + size=\XMLflush{size}, + permissions=\XMLflush{permissions}, + date=\XMLflush{date}]} + \startXMLignore + \processXMLfile{xmldir.tmp} + \stopXMLignore + \stopnointerference} + +\def\getfilestate#1% old one + {\savefilestate[filestate][#1]} + +\endinput diff --git a/tex/context/base/x-dir-05.mkiv b/tex/context/base/x-dir-05.mkiv new file mode 100644 index 000000000..c29c9ea2a --- /dev/null +++ b/tex/context/base/x-dir-05.mkiv @@ -0,0 +1,72 @@ +%D \module +%D [ file=x-dir-05, +%D version=2003.05.10, % around that time -) +%D title=\CONTEXT\ Directory Handling, +%D subtitle=Access, +%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. + +\setvariables + [filestate] + [name=, + base=, + type=, + size=, + permissions=, + date=] + +% \savefilestate[zip-latest][context/latest/cont-#2.zip]% + +\startluacode + local filestates = { } + function commands.savefilestate(tag,name) + if not filestates[tag] then + local attr = lfs.attributes(name) + if attr then attr.name = name end + filestates[tag] = attr + end + end + function commands.getfilestatevariable(tag,name) + local fs = filestates[tag] + if fs then + local value + if name == "base" then + value = file.basename(fs.name) + elseif name == "type" then + value = file.extname(fs.name) + elseif name == "date" then + value = os.date("%Y-%m-%d %H:%M",fs.modification) + else + value = fs[name] or "" + end + tex.sprint(tex.vrbcatcodes,value) + end + end +\stopluacode + +\def\getfilestatevariable#1#2% + {\ctxlua{commands.getfilestatevariable("#1","#2")}} + +\def\savefilestate + {\dodoubleargument\dosavefilestate} + +\def\dosavefilestate[#1][#2]% + {\ctxlua{commands.savefilestate("#1","#2")}% + \setxvariables + [#1] + [name={#2}, + base=\getfilestatevariable{#1}{base}, + type=\getfilestatevariable{#1}{type}, + size=\getfilestatevariable{#1}{size}, + date=\getfilestatevariable{#1}{date}, + permissions=\getfilestatevariable{#1}{permissions}]} + +\def\getfilestate#1% old one + {\savefilestate[filestate][#1]} + +\endinput diff --git a/tex/context/interface/cont-cs.xml b/tex/context/interface/cont-cs.xml index c50d3c5d5..98e0111e0 100644 --- a/tex/context/interface/cont-cs.xml +++ b/tex/context/interface/cont-cs.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-de.xml b/tex/context/interface/cont-de.xml index 2aa738ed1..5b39c628a 100644 --- a/tex/context/interface/cont-de.xml +++ b/tex/context/interface/cont-de.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-en.xml b/tex/context/interface/cont-en.xml index f2cf7f7b8..cf1a59085 100644 --- a/tex/context/interface/cont-en.xml +++ b/tex/context/interface/cont-en.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-fr.xml b/tex/context/interface/cont-fr.xml index 81baacff3..be4a19280 100644 --- a/tex/context/interface/cont-fr.xml +++ b/tex/context/interface/cont-fr.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-it.xml b/tex/context/interface/cont-it.xml index 058e71735..e167f22f2 100644 --- a/tex/context/interface/cont-it.xml +++ b/tex/context/interface/cont-it.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-nl.xml b/tex/context/interface/cont-nl.xml index ebb29402f..dff677cd2 100644 --- a/tex/context/interface/cont-nl.xml +++ b/tex/context/interface/cont-nl.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-pe.xml b/tex/context/interface/cont-pe.xml index 5a86933a8..228cae2e8 100644 --- a/tex/context/interface/cont-pe.xml +++ b/tex/context/interface/cont-pe.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/context/interface/cont-ro.xml b/tex/context/interface/cont-ro.xml index 17e914725..74003dd5c 100644 --- a/tex/context/interface/cont-ro.xml +++ b/tex/context/interface/cont-ro.xml @@ -4209,6 +4209,11 @@ + + + + + diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index e9a57d93b..c03196d1b 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua --- merge date : 12/01/09 17:16:42 +-- merge date : 12/13/09 23:30:54 do -- begin closure to overcome local limits and interference @@ -200,6 +200,7 @@ end local simple_escapes = { ["-"] = "%-", ["."] = "%.", + ["?"] = ".", ["*"] = ".*", } @@ -262,6 +263,19 @@ function string:striplong() -- strips newlines and leading spaces return self end +function string:topattern(lowercase,strict) + if lowercase then + self = self:lower() + end + self = gsub(self,".",simple_escapes) + if self == "" then + self = ".*" + elseif strict then + self = "^" .. self .. "$" + end + return self +end + end -- closure do -- begin closure to overcome local limits and interference @@ -274,6 +288,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = { license = "see context related readme files" } +lpeg = require("lpeg") + local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc --~ l-lpeg.lua : -- cgit v1.2.3