diff options
72 files changed, 2216 insertions, 1074 deletions
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-<name> 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 = [[ +<tr> + <th>safe name </th> + <th>family name </th> + <th>style-variant-weight-width </th> + <th>font name </th> + <th>weight </th> + <th>filename</th> +</tr>]] + +local template_d = [[ +<tr> + <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a> </td> + <td>%s </td> + <td>%s-%s-%s-%s </td> + <td>%s </td> + <td>%s </td> + <td>%s</td> +</tr>]] + 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] = "<table>" - listoffonts[#listoffonts+1] = "<tr><th>safe name</th><th>font name</th><th>filename</th><th>sub font </th><th>type</th></tr>" - 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("<tr><td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",id,id,name,file,sub,type) - end + listoffonts[#listoffonts+1] = "<table>" + 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] = "</table>" - return concat(listoffonts,"\n") end + listoffonts[#listoffonts+1] = "</table>" + return concat(listoffonts,"\n") end return "<b>no fonts</b>" 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("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' checked='checked'/> <span id='t-s-%s'>%s</span>",s,v,v,v,v) - else - scripts[#scripts+1] = format("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' /> <span id='t-s-%s'>%s</span>",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("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' checked='checked'/> <span id='t-s-%s'>%s</span>",s,v,v,v,v) + else + scripts[#scripts+1] = format("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' /> <span id='t-s-%s'>%s</span>",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("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' checked='checked'/> <span id='t-l-%s'>%s</span>",l,v,v,v,v) - else - languages[#languages+1] = format("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' /> <span id='t-l-%s'>%s</span>",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("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' checked='checked'/> <span id='t-l-%s'>%s</span>",l,v,v,v,v) + else + languages[#languages+1] = format("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' /> <span id='t-l-%s'>%s</span>",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("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' checked='checked'/> <span id='t-f-%s'>%s</span>",f,v,v,v,v) - else - features[#features+1] = format("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' /> <span id='t-f-%s'>%s</span>",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("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' checked='checked'/> <span id='t-f-%s'>%s</span>",f,v,v,v,v) + else + features[#features+1] = format("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' /> <span id='t-f-%s'>%s</span>",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("<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/> %s",v,v,v) + for k, v in ipairs { "trace", "basemode" } do + if detail and detail["o-"..v] then + options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/> %s",v,v,v) + else + options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s'/> %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("<input id='o-%s' type='checkbox' name='o-%s'/> %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("<h1>names</h1>",what) result[#result+1] = "<table>" - result[#result+1] = format("<tr><td class='tc'>fontname:</td><td>%s</td></tr>",currentfont) - result[#result+1] = format("<tr><td class='tc'>fullname:</td><td>%s</td></tr>",fontname) - result[#result+1] = format("<tr><td class='tc'>filename:</td><td>%s</td></tr>",fontfile) + result[#result+1] = format("<tr><td class='tc'>fontname: </td><td>%s</td></tr>",currentfont) + result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fontname or "-") + result[#result+1] = format("<tr><td class='tc'>filename: </td><td>%s</td></tr>",specification.fontfile or "-") + result[#result+1] = format("<tr><td class='tc'>familyname: </td><td>%s</td></tr>",specification.familyname or "-") + result[#result+1] = format("<tr><td class='tc'>fontweight: </td><td>%s</td></tr>",specification.fontweight or "-") + result[#result+1] = format("<tr><td class='tc'>format: </td><td>%s</td></tr>",specification.format or "-") + result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fullname or "-") + result[#result+1] = format("<tr><td class='tc'>subfamily: </td><td>%s</td></tr>",specification.subfamily or "-") + result[#result+1] = format("<tr><td class='tc'>rawname: </td><td>%s</td></tr>",specification.rawname or "-") + result[#result+1] = format("<tr><td class='tc'>designsize: </td><td>%s</td></tr>",specification.designsize or "-") + result[#result+1] = format("<tr><td class='tc'>minimumsize:</td><td>%s</td></tr>",specification.minsize or "-") + result[#result+1] = format("<tr><td class='tc'>maximumsize:</td><td>%s</td></tr>",specification.maxsize or "-") + result[#result+1] = format("<tr><td class='tc'>style: </td><td>%s</td></tr>",specification.style ~= "" and specification.style or "normal") + result[#result+1] = format("<tr><td class='tc'>variant: </td><td>%s</td></tr>",specification.variant ~= "" and specification.variant or "normal") + result[#result+1] = format("<tr><td class='tc'>weight: </td><td>%s</td></tr>",specification.weight ~= "" and specification.weight or "normal") + result[#result+1] = format("<tr><td class='tc'>width: </td><td>%s</td></tr>",specification.width ~= "" and specification.width or "normal") result[#result+1] = "</table>" 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("<tr><th>del </th><th>name </th><th>font </th><th>fontname </th><th>script </th><th>language </th><th>features </th><th>title </th><th>sampletext </th></tr>") 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("<tr><td><a href='mtx-server-ctx-fonttest.lua?deletename=%s'>x</a> </td><td><a href='mtx-server-ctx-fonttest.lua?loadname=%s'>%s</a> </td><td>%s </td<td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td></tr>", 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 = [[ <input type="hidden" name="currentfont" value="%s" /> ]] +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("<button name='action' value='%s' type='submit'>%s</button>",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,"<br/>") local i = concat(ints,"<br/><br/>") 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<file name='%s'>",d,(longname and path and join(path,name)) or name) + result[#result+1] = format("%s <base>%s</base>",d,removesuffix(name)) + result[#result+1] = format("%s <type>%s</type>",d,extname(name)) + result[#result+1] = format("%s <size>%s</size>",d,attr.size) + result[#result+1] = format("%s <permissions>%s</permissions>",d,sub(attr.permissions,7,9)) + result[#result+1] = format("%s <date>%s</date>",d,date(timestamp,attr.modification)) + result[#result+1] = format("%s</file>",d) + elseif mode == "directory" then + result[#result+1] = format("%s<directory name='%s'>",d,name) + flush(attr.list,result,n+1,(path and join(path,name)) or name) + result[#result+1] = format("%s</directory>",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 = { "<?xml version='1.0'?>" } + result[#result+1] = format("<files url=%q root=%q pattern=%q luapattern=%q xmlns='%s' timestamp='%s'>",url,root,pattern,luapattern,xmlns,date(timestamp)) + flush(list,result) + result[#result+1] = "</files>" + + 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] = "<?xml version='1.0' standalone='yes'?>\n" - t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>" - if joblog.values then - for k, v in pairs(joblog.values) do - t[#t+1] = string.format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v)) - end - else - t[#t+1] = "<!-- no modes -->" +function scripts.watch.save_exa_modes(joblog,ctmname) + local t= { } + if joblog then + t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n" + t[#t+1] = "<exa:variables xmlns:exa='htpp://www.pragma-ade.com/schemas/exa-variables.rng'>" + if joblog.values then + for k, v in pairs(joblog.values) do + t[#t+1] = string.format("\t<exa:variable label='%s'>%s</exa:variable>", k, tostring(v)) end - t[#t+1] = "</exa:variables>" + else + t[#t+1] = "<!-- no modes -->" end - os.remove(ctmname) - io.savedata(ctmname,table.concat(t,"\n")) + t[#t+1] = "</exa:variables>" 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 @@ <head> <title><?lua pv('title') ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + <?lua if (v('refreshtime') and (tonumber(v('refreshtime')) or 0) > 0) and v('refreshurl') then ?> + <meta http-equiv='refresh' content="<?lua pv('refreshtime') ?>; <?lua pv('refreshurl') ?>"/> + <?lua end ?> <style type="text/css"> <?lmx-include context.css ?> </style> </head> + <?lua if v('action') then ?> + <form action="<?lua pv(action) ?>" enctype="multi-part/form-data" method="post"> + <?lua end ?> <body> - <div id="top"><div id="top-one"><div id="top-two"> - <?lua pv('title') ?> - </div></div></div> - <div id="left"><div id="left-one"><div id="left-two"> - <?lua pv('lefttext') ?> - </div></div></div> - <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five"> - <?lua pv('righttext') ?> - </div></div></div></div></div></div></div> - <div id="main"><div id='main-settings'> - <div class='title'><?lua pv('maintext') ?></div> - </div></div> - <div id="bottom"><div id="bottom-one"><div id="bottom-two"> - <?lua pv('bottomtext') ?> - </div></div></div> + <div id="top"> + <div id="top-one"> + <div id="top-two"> + <?lua pv('title') ?> + </div> + </div> + </div> + <div id="bottom"> + <div id="bottom-one"> + <div id="bottom-two"> + <?lua pv('bottomtext') ?> + </div> + </div> + </div> + <div id="left"> + <div id="left-one"> + <div id="left-two"> + <?lua pv('lefttext') ?> + </div> + </div> + </div> + <div id="right"> + <div id="right-safari"> + <div id="right-one"> + <div id="right-two"> + <div id="right-three"> + <div id="right-four"> + <div id="right-five"> + <?lua pv('righttext') ?> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <div id="main"> + <div id='main-settings'> + <div class='title'> + <?lua pv('maintext') ?> + </div> + </div> + </div> </body> + <?lua if v('action') then ?> + </form> + <?lua end ?> </html> 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 <</ActualText \ctxlua{tex.write(lpdf.tosixteen("#2"))} >> BDC}% + #1% + \pdfliteral direct{EMC}} + +% \starttext +% text \pdfactualtext{Meier}{Müller} text +% \stoptext + \protect \endinput diff --git a/tex/context/base/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-- -<p>The following helper functions best belong to the <t>lmxl-ini</t> +<p>The following helper functions best belong to the <t>lxml-ini</t> module. Some are here because we need then in the <t>mk</t> document and other manuals, others came up when playing with this module. Since this module is also used in <l n='mtxrun'/> 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', "<read " .. filename .. ">") - lmx.set('errorcontext', 'unknown error') + variables.filename, variables.errorcontext = "<read " .. filename .. ">", '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("<tt>" .. lmx.escape(str) .. "</tt>") 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("<tt>" .. do_escape(str) .. "</tt>") end +end + +local function do_variable(str) + return variables[str] or lmxvariables[str] -- or format("<!-- unset lmx instance variable: %s -->",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("<!-- unknown lmx include file: %s -->",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 ?>","(.-)<%?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 ?>","(.-)<%?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 @@ <cd:parameter name="prikaz"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="stranka"> + <cd:constant type="posledni"/> + <cd:constant type="ano"/> + <cd:constant type="ne"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="befehl"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="seite"> + <cd:constant type="letzte"/> + <cd:constant type="ja"/> + <cd:constant type="nein"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="command"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="last"/> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="commande"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="dernier"/> + <cd:constant type="oui"/> + <cd:constant type="non"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="comando"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="pagina"> + <cd:constant type="ultimo"/> + <cd:constant type="si"/> + <cd:constant type="no"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="commando"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="pagina"> + <cd:constant type="laatste"/> + <cd:constant type="ja"/> + <cd:constant type="nee"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="فرمان"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="صفحه"> + <cd:constant type="آخرین"/> + <cd:constant type="بله"/> + <cd:constant type="نه"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 @@ <cd:parameter name="comanda"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="pagina"> + <cd:constant type="ultim"/> + <cd:constant type="da"/> + <cd:constant type="nu"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> 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 : |