diff options
author | Hans Hagen <pragma@wxs.nl> | 2012-12-28 20:30:00 +0100 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2012-12-28 20:30:00 +0100 |
commit | 58f3f55b58d34d4a4b70a6099a81296b862e6d9f (patch) | |
tree | 6c2b139494f1af844a911bff3d510ccffcc9991f | |
parent | 4c30ec7a1d7f8a2ba19eb9a918723ca4369a8b7f (diff) | |
download | context-58f3f55b58d34d4a4b70a6099a81296b862e6d9f.tar.gz |
beta 2012.12.28 20:30
40 files changed, 2590 insertions, 601 deletions
diff --git a/context/data/scite/scite-ctx.lua b/context/data/scite/scite-ctx.lua index 3557994f3..be3718043 100644 --- a/context/data/scite/scite-ctx.lua +++ b/context/data/scite/scite-ctx.lua @@ -80,7 +80,7 @@ function traceln(str) io.flush() end -function string.grab(str,delimiter) +local function grab(str,delimiter) local list = { } for snippet in gmatch(str,delimiter) do list[#list+1] = snippet @@ -88,15 +88,15 @@ function string.grab(str,delimiter) return list end -function string.expand(str) +local function expand(str) return (gsub(str,"ENV%((%w+)%)", os.envvar)) end -function string.strip(str) +local function strip(str) return (gsub(str,"^%s*(.-)%s*$", "%1")) end -function table.alphasort(list,i) +local function alphasort(list,i) if i and i > 0 then local function alphacmp(a,b) return lower(gsub(sub(a,i),'0',' ')) < lower(gsub(sub(b,i),'0',' ')) @@ -181,6 +181,9 @@ function extend_to_end() -- editor:LineEndExtend() does not work while line == editor:LineFromPosition(selectionend+1) do selectionend = selectionend + 1 editor:SetSel(selectionstart,selectionend) + if selectionend ~= editor.SelectionEnd then + break -- no progress + end end editor:SetSel(selectionstart,selectionend) return selectionend @@ -238,12 +241,12 @@ do else print("- 'ctxspellpath is not set") end - print("- ctx.spellcheck.wordpath expands to " .. string.expand(props['ctx.spellcheck.wordpath'])) + print("- ctx.spellcheck.wordpath expands to " .. expand(props['ctx.spellcheck.wordpath'])) end print("\n- ctx.wraptext.length is set to " .. props['ctx.wraptext.length']) if props['ctx.helpinfo'] ~= '' then print("\n- key bindings:\n") - print((gsub(string.strip(props['ctx.helpinfo']),"%s*\|%s*","\n"))) + print((gsub(strip(props['ctx.helpinfo']),"%s*\|%s*","\n"))) end print("\n- recognized first lines:\n") print("xml <?xml version='1.0' language='nl'") @@ -371,13 +374,13 @@ function sort_text() local startcolumn = props['SelectionStartColumn'] - 1 local endcolumn = props['SelectionEndColumn'] - 1 + startposition = extend_to_start() endposition = extend_to_end() local selection = gsub(editor:GetSelText(), "%s*$", '') - - list = string.grab(selection,"[^\n\r]+") - table.alphasort(list, startcolumn) + list = grab(selection,"[^\n\r]+") + alphasort(list, startcolumn) local replacement = concat(list, "\n") editor:GotoPos(startposition) @@ -570,7 +573,7 @@ function check_text() -- obsolete, replaced by lexer wordfile, worddone, wordlist = fname, 0, {} for filename in gmatch(wordfile,"[^%,]+") do if wordpath ~= '' then - filename = string.expand(wordpath) .. '/' .. filename + filename = expand(wordpath) .. '/' .. filename end if io.exists(filename) then traceln("loading " .. filename) @@ -651,7 +654,7 @@ local menufunctions = {} function UserListShow(menutrigger, menulist) local menuentries = {} - local list = string.grab(menulist,"[^%|]+") + local list = grab(menulist,"[^%|]+") menuactions = {} for i=1, #list do if list[i] ~= '' then diff --git a/metapost/context/base/mp-chem.mpiv b/metapost/context/base/mp-chem.mpiv index 954174f0d..6739dcaf7 100644 --- a/metapost/context/base/mp-chem.mpiv +++ b/metapost/context/base/mp-chem.mpiv @@ -66,7 +66,7 @@ chem_setting_axis := false ; chem_axis_rulethickness := 1pt ; chem_emwidth := 10pt ; % EmWidth or \the\emwidth does not work... chem_b_length := 3 chem_emwidth ; -chem_text_offset := -.71chem_emwidth ; % 1/sqrt(2) +chem_text_offset := -.3chem_emwidth ; % -.71chem_emwidth ; % 1/sqrt(2) chem_center_offset := .5 chem_emwidth ; chem_picture_offset := chem_emwidth ; chem_dbl_offset := .05 ; @@ -1404,10 +1404,8 @@ vardef chem_midz@#(suffix $) (expr p) (text t) = % MIDZ enddef ; vardef chem_rz@#(suffix $) (expr p) (text t) = % RZ -% draw chem_text@# -% (t, chem_do((point p-1 of chem_r_path[$]) chem_transformed($))) ; -% freedotlabel(t,chem_do((point p-1 of chem_r_path[$]) chem_transformed($)),center chem_r_path[$] chem_transformed($)) - freelabel(t,chem_do((point p-1 of chem_r_path[$]) chem_transformed($)),center chem_r_path[$] chem_transformed($)) + draw chem_text@# + (t, chem_do((point p-1 of chem_r_path[$]) chem_transformed($))) ; enddef ; vardef chem_lrz@#(suffix $) (expr p) (text t) = % LRZ @@ -1485,32 +1483,41 @@ enddef ; vardef chem_symbol(expr t) = draw textext(t) ; enddef ; -vardef chem_align@#(expr pic,off) = +vardef chem_align@#(expr pic) = pic if (mfun_labtype@# >= 10) : shifted (0,ypart center pic) fi - shifted (chem_text_offset*mfun_laboff@# - (mfun_labxf@#*lrcorner pic + mfun_labyf@#*ulcorner pic + (1-mfun_labxf@#-mfun_labyf@#)*llcorner pic)) -enddef ; - -vardef chem_text@#(expr txt, z) = % adapted copy of thelabel@ - save off ; numeric off ; off := chem_text_offset ; - - chem_pic := textext(txt) rotated -chem_setting_rotation ; - chem_pic := - if (length(str @#) > 0) and ((str @#) = "auto") : - if (abs z)>.71chem_emwidth : chem_align.autoalign(angle(z)) - else : chem_align fi + shifted (-(mfun_labxf@#*lrcorner pic + mfun_labyf@#*ulcorner pic + (1-mfun_labxf@#-mfun_labyf@#)*llcorner pic)) +enddef ; + +vardef chem_text@#(expr txt, z) = + chem_pic := textext(txt) ; + if length(str @#)=0 : + chem_pic := chem_align(chem_pic) ; + elseif (str @#) = "auto" : + if z<>origin : + chem_num0 := abs(angle(z rotated chem_setting_rotation)) ; + if chem_num0<=60 : + chem_pic := chem_align.rt (chem_pic) xshifted chem_text_offset ; + elseif chem_num0>=120 : + chem_pic := chem_align.lft(chem_pic) xshifted -chem_text_offset ; + else : + chem_pic := chem_align (chem_pic) ; + fi else : - chem_align@# + chem_pic := chem_align (chem_pic) ; fi - (chem_pic,off) ; - chem_pic := chem_pic shifted z ; + else : + chem_pic := chem_align@#(chem_pic) shifted (chem_text_offset*mfun_laboff@#) ; + fi + chem_pic := (chem_pic rotated -chem_setting_rotation) shifted z ; if chem_text_trace : - draw z withpen pencircle scaled 2pt withcolor red ; + draw z withpen pencircle scaled 2pt withcolor red ; draw boundingbox chem_pic withpen pencircle scaled 1pt withcolor red ; - fi ; + fi + chem_pic enddef ; diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 3a02ad582..83944d791 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -2257,7 +2257,7 @@ io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') +-- local data = f:read('*all') local data = readall(f) f:close() if #data > 0 then @@ -2286,29 +2286,29 @@ end function io.loadlines(filename,n) -- return nil if empty local f = io.open(filename,'r') - if f then - if n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break - end - end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - assert(f:close()) - if #line > 0 then - return line + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[#lines+1] = line + else + break end end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end @@ -2328,7 +2328,7 @@ function io.exists(filename) if f == nil then return false else - assert(f:close()) + f:close() return true end end @@ -2339,7 +2339,7 @@ function io.size(filename) return 0 else local s = f:seek("end") - assert(f:close()) + f:close() return s end end @@ -2347,9 +2347,13 @@ end function io.noflines(f) if type(f) == "string" then local f = io.open(filename) - local n = f and io.noflines(f) or 0 - assert(f:close()) - return n + if f then + local n = f and io.noflines(f) or 0 + f:close() + return n + else + return 0 + end else local n = 0 for _ in f:lines() do @@ -5800,6 +5804,58 @@ local function fastserialize(t,r,outer) -- no mixes return r end +-- local f_hashed_string = formatters["[%q]=%q,"] +-- local f_hashed_number = formatters["[%q]=%s,"] +-- local f_hashed_table = formatters["[%q]="] +-- local f_hashed_true = formatters["[%q]=true,"] +-- local f_hashed_false = formatters["[%q]=false,"] +-- +-- local f_indexed_string = formatters["%q,"] +-- local f_indexed_number = formatters["%s,"] +-- ----- f_indexed_true = formatters["true,"] +-- ----- f_indexed_false = formatters["false,"] +-- +-- local function fastserialize(t,r,outer) -- no mixes +-- r[#r+1] = "{" +-- local n = #t +-- if n > 0 then +-- for i=1,n do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_indexed_string(v) +-- elseif tv == "number" then +-- r[#r+1] = f_indexed_number(v) +-- elseif tv == "table" then +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k) +-- r[#r+1] = v and "true," or "false," +-- end +-- end +-- else +-- for k, v in next, t do +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_hashed_string(k,v) +-- elseif tv == "number" then +-- r[#r+1] = f_hashed_number(k,v) +-- elseif tv == "table" then +-- r[#r+1] = f_hashed_table(k) +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k) +-- end +-- end +-- end +-- if outer then +-- r[#r+1] = "}" +-- else +-- r[#r+1] = "}," +-- end +-- return r +-- end + function table.fastserialize(t,prefix) -- so prefix should contain the = return concat(fastserialize(t,{ prefix or "return" },true)) end @@ -6076,6 +6132,430 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util-str'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.strings = utilities.strings or { } +local strings = utilities.strings + +local load = load +local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub +local concat = table.concat +local P, V, C, S, R, Ct, Cs, Cp, Carg = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg +local patterns, lpegmatch = lpeg.patterns, lpeg.match +local utfchar, utfbyte = utf.char, utf.byte +local setmetatableindex = table.setmetatableindex +-- + +local stripper = patterns.stripzeros + +local function points(n) + return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +end + +local function basepoints(n) + return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) +end + +number.points = points +number.basepoints = basepoints + +-- str = " \n \ntest \n test\ntest " +-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]") + +local rubish = patterns.spaceortab^0 * patterns.newline +local anyrubish = patterns.spaceortab + patterns.newline +local anything = patterns.anything +local stripped = (patterns.spaceortab^1 / "") * patterns.newline +local leading = rubish^0 / "" +local trailing = (anyrubish^1 * patterns.endofstring) / "" +local redundant = rubish^3 / "\n" + +local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0) + +function strings.collapsecrlf(str) + return lpegmatch(pattern,str) +end + +-- The following functions might end up in another namespace. + +local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator + +function strings.newrepeater(str,offset) + offset = offset or 0 + local s = repeaters[str] + if not s then + s = { } + repeaters[str] = s + end + local t = s[offset] + if t then + return t + end + t = { } + setmetatableindex(t, function(t,k) + if not k then + return "" + end + local n = k + offset + local s = n > 0 and rep(str,n) or "" + t[k] = s + return s + end) + s[offset] = t + return t +end + +-- local dashes = strings.newrepeater("--",-1) +-- print(dashes[2],dashes[3],dashes[1]) + +local extra, tab, start = 0, 0, 4, 0 + +local nspaces = strings.newrepeater(" ") + +local pattern = + Carg(1) / function(t) + extra, tab, start = 0, t or 7, 1 + end + * Cs(( + Cp() * patterns.tab / function(position) + local current = (position - start + 1) + extra + local spaces = tab-(current-1) % tab + if spaces > 0 then + extra = extra + spaces - 1 + return nspaces[spaces] -- rep(" ",spaces) + else + return "" + end + end + + patterns.newline * Cp() / function(position) + extra, start = 0, position + end + + patterns.anything + )^1) + +function strings.tabtospace(str,tab) + return lpegmatch(pattern,str,1,tab or 7) +end + +-- local t = { +-- "1234567123456712345671234567", +-- "\tb\tc", +-- "a\tb\tc", +-- "aa\tbb\tcc", +-- "aaa\tbbb\tccc", +-- "aaaa\tbbbb\tcccc", +-- "aaaaa\tbbbbb\tccccc", +-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc", +-- "one\n two\nxxx three\nxx four\nx five\nsix", +-- } +-- for k=1,#t do +-- print(strings.tabtospace(t[k])) +-- end + +function strings.striplong(str) -- strips all leading spaces + str = gsub(str,"^%s*","") + str = gsub(str,"[\n\r]+ *","\n") + return str +end + +-- local template = string.striplong([[ +-- aaaa +-- bb +-- cccccc +-- ]]) + +function strings.nice(str) + str = gsub(str,"[:%-+_]+"," ") -- maybe more + return str +end + +-- Work in progress. Interesting is that compared to the built-in this +-- is faster in luatex than in luajittex where we have a comparable speed. + +local n = 0 + +-- we are somewhat sloppy in parsing prefixes as it's not that critical +-- +-- this does not work out ok: +-- +-- function fnc(...) -- 1,2,3 +-- print(...,...,...) -- 1,1,1,2,3 +-- end + +local prefix_any = C((S("+- .") + R("09"))^0) +local prefix_tab = C((1-R("az","AZ","09","%%"))^0) + +-- we've split all cases as then we can optimize them (let's omit the fuzzy u) + +local format_s = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%ss',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_q = function() + n = n + 1 + return format("format('%%q',(select(%s,...)))",n) -- maybe an own lpeg +end + +local format_i = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%si',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_d = format_i + +local format_f = function(f) + n = n + 1 + return format("format('%%%sf',(select(%s,...)))",f,n) +end + +local format_g = function(f) + n = n + 1 + return format("format('%%%sg',(select(%s,...)))",f,n) +end + +local format_G = function(f) + n = n + 1 + return format("format('%%%sG',(select(%s,...)))",f,n) +end + +local format_e = function(f) + n = n + 1 + return format("format('%%%se',(select(%s,...)))",f,n) +end + +local format_E = function(f) + n = n + 1 + return format("format('%%%sE',(select(%s,...)))",f,n) +end + +local format_x = function(f) + n = n + 1 + return format("format('%%%sx',(select(%s,...)))",f,n) +end + +local format_X = function(f) + n = n + 1 + return format("format('%%%sX',(select(%s,...)))",f,n) +end + +local format_o = function(f) + n = n + 1 + return format("format('%%%so',(select(%s,...)))",f,n) +end + +local format_c = function() + n = n + 1 + return format("utfchar((select(%s,...)))",n) +end + +local format_r = function(f) + n = n + 1 + return format("format('%%%s.0f',(select(%s,...)))",f,n) +end + +local format_v = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_V = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_u = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('u+%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_U = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('U+%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_p = function() + n = n + 1 + return format("points((select(%s,...)))",n) +end + +local format_b = function() + n = n + 1 + return format("basepoints((select(%s,...)))",n) +end + +local format_t = function(f) + n = n + 1 + if f and f ~= "" then + return format("concat((select(%s,...)),%q)",n,f) + else + return format("concat((select(%s,...)))",n) + end +end + +local format_l = function() + n = n + 1 + return format("(select(%s,...) and 'true' or 'false')",n) +end + +local format_a = function(s) + return format("%q",s) +end + +local builder = Ct { "start", + start = (P("%") * ( + V("s") + V("q") + + V("i") + V("d") + + V("f") + V("g") + V("G") + V("e") + V("E") + + V("x") + V("X") + V("o") + -- + + V("c") + -- + + V("r") + + V("v") + V("V") + V("u") + V("U") + + V("p") + V("b") + + V("t") + + V("l") + ) + + V("a") + )^0, + -- + ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string) + ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string) + ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer) + ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer) + ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float) + ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float) + ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float) + ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float) + ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float) + ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal) + ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL) + ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal) + -- + ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) + -- + ["r"] = (prefix_any * P("r")) / format_r, -- %r => round + ["v"] = (prefix_any * P("v")) / format_v, -- %v => 0x0a1b2 (when - no 0x) + ["V"] = (prefix_any * P("V")) / format_V, -- %V => 0x0A1B2 (when - no 0x) + ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+) + ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+) + ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units) + ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units) + ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat + ["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean + -- + ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_a, -- %a => text (including %%) +} + +-- we can be clever and only alias what is needed + +local template = [[ +local format = string.format +local concat = table.concat +local points = number.points +local basepoints = number.basepoints +local utfchar = utf.char +local utfbyte = utf.byte +return function(...) + return %s +end +]] + +local function make(t,str) + n = 0 + local p = lpegmatch(builder,str) +-- inspect(p) + local c = format(template,concat(p,"..")) +-- inspect(c) + formatter = load(c)() + t[str] = formatter + return formatter +end + +local formatters = string.formatters or { } +string.formatters = formatters + +setmetatableindex(formatters,make) + +function string.makeformatter(str) + return formatters[str] +end + +function string.formatter(str,...) + return formatters[str](...) +end + +-- local p1 = "%s test %f done %p and %c and %V or %+t or %%" +-- local p2 = "%s test %f done %s and %s and 0x%05X or %s or %%" +-- +-- local t = { 1,2,3,4 } +-- local r = "" +-- +-- local format, formatter, formatters = string.format, string.formatter, string.formatters +-- local utfchar, utfbyte, concat, points = utf.char, utf.byte, table.concat, number.points +-- +-- local c = os.clock() +-- local f = formatters[p1] +-- for i=1,500000 do +-- -- r = formatters[p1]("hans",123.45,123.45,123,"a",t) +-- r = formatter(p1,"hans",123.45,123.45,123,"a",t) +-- -- r = f("hans",123.45,123.45,123,"a",t) +-- end +-- print(os.clock()-c,r) +-- +-- local c = os.clock() +-- for i=1,500000 do +-- r = format(p2,"hans",123.45,points(123.45),utfchar(123),utfbyte("a"),concat(t,"+")) +-- end +-- print(os.clock()-c,r) + +-- local f = format +-- function string.format(fmt,...) +-- print(fmt,...) +-- return f(fmt,...) +-- end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", @@ -7875,6 +8355,7 @@ local texcount = tex and tex.count local next, type, select = next, type, select local setmetatableindex = table.setmetatableindex +local formatters = string.formatters @@ -7918,61 +8399,76 @@ if tex and (tex.jobname or tex.formatname) then write_nl(target,"\n") end + local f_one = formatters["%-15s > %s\n"] + local f_two = formatters["%-15s >\n"] + report = function(a,b,c,...) if c then - write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s >\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s"] + local f_two = formatters["%-15s >"] + direct = function(a,b,c,...) if c then - return format("%-15s > %s",translations[a],format(formats[b],c,...)) + return f_one(translations[a],format(formats[b],c,...)) elseif b then - return format("%-15s > %s",translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return format("%-15s >", translations[a]) + return f_two(translations[a]) else return "" end end + local f_one = formatters["%-15s > %s > %s\n"] + local f_two = formatters["%-15s > %s >\n"] + subreport = function(a,s,b,c,...) if c then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],translations[s],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,format("%-15s > %s >\n", translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s > %s"] + local f_two = formatters["%-15s > %s >"] + subdirect = function(a,s,b,c,...) if c then - return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...)) + return f_one(translations[a],translations[s],format(formats[b],c,...)) elseif b then - return format("%-15s > %s > %s",translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return format("%-15s > %s >", translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) if c then - write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s : %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s :\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -8027,37 +8523,46 @@ else write_nl("\n") end + local f_one = formatters["%-15s | %s"] + local f_two = formatters["%-15s |"] + report = function(a,b,c,...) if c then - write_nl(format("%-15s | %s",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s",a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(format("%-15s |", a)) + write_nl(f_two(a)) else write_nl("") end end + local f_one = formatters["%-15s | %s | %s"] + local f_two = formatters["%-15s | %s |"] + subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s | %s | %s",a,sub,format(b,c,...))) + write_nl(f_one(a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s | %s",a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(format("%-15s | %s |", a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) -- not to be used in lua anyway if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + write_nl(f_one(a,b)) -- b can have %'s elseif a then - write_nl(format("%-15s :\n", a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -18212,6 +18717,7 @@ own.libs = { -- order can be made better 'util-tab.lua', 'util-sto.lua', + 'util-str.lua', -- code might move to l-string 'util-mrg.lua', 'util-lua.lua', 'util-prs.lua', diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 3a02ad582..83944d791 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -2257,7 +2257,7 @@ io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') +-- local data = f:read('*all') local data = readall(f) f:close() if #data > 0 then @@ -2286,29 +2286,29 @@ end function io.loadlines(filename,n) -- return nil if empty local f = io.open(filename,'r') - if f then - if n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break - end - end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - assert(f:close()) - if #line > 0 then - return line + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[#lines+1] = line + else + break end end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end @@ -2328,7 +2328,7 @@ function io.exists(filename) if f == nil then return false else - assert(f:close()) + f:close() return true end end @@ -2339,7 +2339,7 @@ function io.size(filename) return 0 else local s = f:seek("end") - assert(f:close()) + f:close() return s end end @@ -2347,9 +2347,13 @@ end function io.noflines(f) if type(f) == "string" then local f = io.open(filename) - local n = f and io.noflines(f) or 0 - assert(f:close()) - return n + if f then + local n = f and io.noflines(f) or 0 + f:close() + return n + else + return 0 + end else local n = 0 for _ in f:lines() do @@ -5800,6 +5804,58 @@ local function fastserialize(t,r,outer) -- no mixes return r end +-- local f_hashed_string = formatters["[%q]=%q,"] +-- local f_hashed_number = formatters["[%q]=%s,"] +-- local f_hashed_table = formatters["[%q]="] +-- local f_hashed_true = formatters["[%q]=true,"] +-- local f_hashed_false = formatters["[%q]=false,"] +-- +-- local f_indexed_string = formatters["%q,"] +-- local f_indexed_number = formatters["%s,"] +-- ----- f_indexed_true = formatters["true,"] +-- ----- f_indexed_false = formatters["false,"] +-- +-- local function fastserialize(t,r,outer) -- no mixes +-- r[#r+1] = "{" +-- local n = #t +-- if n > 0 then +-- for i=1,n do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_indexed_string(v) +-- elseif tv == "number" then +-- r[#r+1] = f_indexed_number(v) +-- elseif tv == "table" then +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k) +-- r[#r+1] = v and "true," or "false," +-- end +-- end +-- else +-- for k, v in next, t do +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_hashed_string(k,v) +-- elseif tv == "number" then +-- r[#r+1] = f_hashed_number(k,v) +-- elseif tv == "table" then +-- r[#r+1] = f_hashed_table(k) +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k) +-- end +-- end +-- end +-- if outer then +-- r[#r+1] = "}" +-- else +-- r[#r+1] = "}," +-- end +-- return r +-- end + function table.fastserialize(t,prefix) -- so prefix should contain the = return concat(fastserialize(t,{ prefix or "return" },true)) end @@ -6076,6 +6132,430 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util-str'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.strings = utilities.strings or { } +local strings = utilities.strings + +local load = load +local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub +local concat = table.concat +local P, V, C, S, R, Ct, Cs, Cp, Carg = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg +local patterns, lpegmatch = lpeg.patterns, lpeg.match +local utfchar, utfbyte = utf.char, utf.byte +local setmetatableindex = table.setmetatableindex +-- + +local stripper = patterns.stripzeros + +local function points(n) + return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +end + +local function basepoints(n) + return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) +end + +number.points = points +number.basepoints = basepoints + +-- str = " \n \ntest \n test\ntest " +-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]") + +local rubish = patterns.spaceortab^0 * patterns.newline +local anyrubish = patterns.spaceortab + patterns.newline +local anything = patterns.anything +local stripped = (patterns.spaceortab^1 / "") * patterns.newline +local leading = rubish^0 / "" +local trailing = (anyrubish^1 * patterns.endofstring) / "" +local redundant = rubish^3 / "\n" + +local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0) + +function strings.collapsecrlf(str) + return lpegmatch(pattern,str) +end + +-- The following functions might end up in another namespace. + +local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator + +function strings.newrepeater(str,offset) + offset = offset or 0 + local s = repeaters[str] + if not s then + s = { } + repeaters[str] = s + end + local t = s[offset] + if t then + return t + end + t = { } + setmetatableindex(t, function(t,k) + if not k then + return "" + end + local n = k + offset + local s = n > 0 and rep(str,n) or "" + t[k] = s + return s + end) + s[offset] = t + return t +end + +-- local dashes = strings.newrepeater("--",-1) +-- print(dashes[2],dashes[3],dashes[1]) + +local extra, tab, start = 0, 0, 4, 0 + +local nspaces = strings.newrepeater(" ") + +local pattern = + Carg(1) / function(t) + extra, tab, start = 0, t or 7, 1 + end + * Cs(( + Cp() * patterns.tab / function(position) + local current = (position - start + 1) + extra + local spaces = tab-(current-1) % tab + if spaces > 0 then + extra = extra + spaces - 1 + return nspaces[spaces] -- rep(" ",spaces) + else + return "" + end + end + + patterns.newline * Cp() / function(position) + extra, start = 0, position + end + + patterns.anything + )^1) + +function strings.tabtospace(str,tab) + return lpegmatch(pattern,str,1,tab or 7) +end + +-- local t = { +-- "1234567123456712345671234567", +-- "\tb\tc", +-- "a\tb\tc", +-- "aa\tbb\tcc", +-- "aaa\tbbb\tccc", +-- "aaaa\tbbbb\tcccc", +-- "aaaaa\tbbbbb\tccccc", +-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc", +-- "one\n two\nxxx three\nxx four\nx five\nsix", +-- } +-- for k=1,#t do +-- print(strings.tabtospace(t[k])) +-- end + +function strings.striplong(str) -- strips all leading spaces + str = gsub(str,"^%s*","") + str = gsub(str,"[\n\r]+ *","\n") + return str +end + +-- local template = string.striplong([[ +-- aaaa +-- bb +-- cccccc +-- ]]) + +function strings.nice(str) + str = gsub(str,"[:%-+_]+"," ") -- maybe more + return str +end + +-- Work in progress. Interesting is that compared to the built-in this +-- is faster in luatex than in luajittex where we have a comparable speed. + +local n = 0 + +-- we are somewhat sloppy in parsing prefixes as it's not that critical +-- +-- this does not work out ok: +-- +-- function fnc(...) -- 1,2,3 +-- print(...,...,...) -- 1,1,1,2,3 +-- end + +local prefix_any = C((S("+- .") + R("09"))^0) +local prefix_tab = C((1-R("az","AZ","09","%%"))^0) + +-- we've split all cases as then we can optimize them (let's omit the fuzzy u) + +local format_s = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%ss',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_q = function() + n = n + 1 + return format("format('%%q',(select(%s,...)))",n) -- maybe an own lpeg +end + +local format_i = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%si',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_d = format_i + +local format_f = function(f) + n = n + 1 + return format("format('%%%sf',(select(%s,...)))",f,n) +end + +local format_g = function(f) + n = n + 1 + return format("format('%%%sg',(select(%s,...)))",f,n) +end + +local format_G = function(f) + n = n + 1 + return format("format('%%%sG',(select(%s,...)))",f,n) +end + +local format_e = function(f) + n = n + 1 + return format("format('%%%se',(select(%s,...)))",f,n) +end + +local format_E = function(f) + n = n + 1 + return format("format('%%%sE',(select(%s,...)))",f,n) +end + +local format_x = function(f) + n = n + 1 + return format("format('%%%sx',(select(%s,...)))",f,n) +end + +local format_X = function(f) + n = n + 1 + return format("format('%%%sX',(select(%s,...)))",f,n) +end + +local format_o = function(f) + n = n + 1 + return format("format('%%%so',(select(%s,...)))",f,n) +end + +local format_c = function() + n = n + 1 + return format("utfchar((select(%s,...)))",n) +end + +local format_r = function(f) + n = n + 1 + return format("format('%%%s.0f',(select(%s,...)))",f,n) +end + +local format_v = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_V = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_u = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('u+%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_U = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('U+%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_p = function() + n = n + 1 + return format("points((select(%s,...)))",n) +end + +local format_b = function() + n = n + 1 + return format("basepoints((select(%s,...)))",n) +end + +local format_t = function(f) + n = n + 1 + if f and f ~= "" then + return format("concat((select(%s,...)),%q)",n,f) + else + return format("concat((select(%s,...)))",n) + end +end + +local format_l = function() + n = n + 1 + return format("(select(%s,...) and 'true' or 'false')",n) +end + +local format_a = function(s) + return format("%q",s) +end + +local builder = Ct { "start", + start = (P("%") * ( + V("s") + V("q") + + V("i") + V("d") + + V("f") + V("g") + V("G") + V("e") + V("E") + + V("x") + V("X") + V("o") + -- + + V("c") + -- + + V("r") + + V("v") + V("V") + V("u") + V("U") + + V("p") + V("b") + + V("t") + + V("l") + ) + + V("a") + )^0, + -- + ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string) + ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string) + ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer) + ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer) + ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float) + ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float) + ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float) + ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float) + ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float) + ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal) + ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL) + ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal) + -- + ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) + -- + ["r"] = (prefix_any * P("r")) / format_r, -- %r => round + ["v"] = (prefix_any * P("v")) / format_v, -- %v => 0x0a1b2 (when - no 0x) + ["V"] = (prefix_any * P("V")) / format_V, -- %V => 0x0A1B2 (when - no 0x) + ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+) + ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+) + ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units) + ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units) + ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat + ["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean + -- + ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_a, -- %a => text (including %%) +} + +-- we can be clever and only alias what is needed + +local template = [[ +local format = string.format +local concat = table.concat +local points = number.points +local basepoints = number.basepoints +local utfchar = utf.char +local utfbyte = utf.byte +return function(...) + return %s +end +]] + +local function make(t,str) + n = 0 + local p = lpegmatch(builder,str) +-- inspect(p) + local c = format(template,concat(p,"..")) +-- inspect(c) + formatter = load(c)() + t[str] = formatter + return formatter +end + +local formatters = string.formatters or { } +string.formatters = formatters + +setmetatableindex(formatters,make) + +function string.makeformatter(str) + return formatters[str] +end + +function string.formatter(str,...) + return formatters[str](...) +end + +-- local p1 = "%s test %f done %p and %c and %V or %+t or %%" +-- local p2 = "%s test %f done %s and %s and 0x%05X or %s or %%" +-- +-- local t = { 1,2,3,4 } +-- local r = "" +-- +-- local format, formatter, formatters = string.format, string.formatter, string.formatters +-- local utfchar, utfbyte, concat, points = utf.char, utf.byte, table.concat, number.points +-- +-- local c = os.clock() +-- local f = formatters[p1] +-- for i=1,500000 do +-- -- r = formatters[p1]("hans",123.45,123.45,123,"a",t) +-- r = formatter(p1,"hans",123.45,123.45,123,"a",t) +-- -- r = f("hans",123.45,123.45,123,"a",t) +-- end +-- print(os.clock()-c,r) +-- +-- local c = os.clock() +-- for i=1,500000 do +-- r = format(p2,"hans",123.45,points(123.45),utfchar(123),utfbyte("a"),concat(t,"+")) +-- end +-- print(os.clock()-c,r) + +-- local f = format +-- function string.format(fmt,...) +-- print(fmt,...) +-- return f(fmt,...) +-- end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", @@ -7875,6 +8355,7 @@ local texcount = tex and tex.count local next, type, select = next, type, select local setmetatableindex = table.setmetatableindex +local formatters = string.formatters @@ -7918,61 +8399,76 @@ if tex and (tex.jobname or tex.formatname) then write_nl(target,"\n") end + local f_one = formatters["%-15s > %s\n"] + local f_two = formatters["%-15s >\n"] + report = function(a,b,c,...) if c then - write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s >\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s"] + local f_two = formatters["%-15s >"] + direct = function(a,b,c,...) if c then - return format("%-15s > %s",translations[a],format(formats[b],c,...)) + return f_one(translations[a],format(formats[b],c,...)) elseif b then - return format("%-15s > %s",translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return format("%-15s >", translations[a]) + return f_two(translations[a]) else return "" end end + local f_one = formatters["%-15s > %s > %s\n"] + local f_two = formatters["%-15s > %s >\n"] + subreport = function(a,s,b,c,...) if c then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],translations[s],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,format("%-15s > %s >\n", translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s > %s"] + local f_two = formatters["%-15s > %s >"] + subdirect = function(a,s,b,c,...) if c then - return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...)) + return f_one(translations[a],translations[s],format(formats[b],c,...)) elseif b then - return format("%-15s > %s > %s",translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return format("%-15s > %s >", translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) if c then - write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s : %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s :\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -8027,37 +8523,46 @@ else write_nl("\n") end + local f_one = formatters["%-15s | %s"] + local f_two = formatters["%-15s |"] + report = function(a,b,c,...) if c then - write_nl(format("%-15s | %s",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s",a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(format("%-15s |", a)) + write_nl(f_two(a)) else write_nl("") end end + local f_one = formatters["%-15s | %s | %s"] + local f_two = formatters["%-15s | %s |"] + subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s | %s | %s",a,sub,format(b,c,...))) + write_nl(f_one(a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s | %s",a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(format("%-15s | %s |", a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) -- not to be used in lua anyway if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + write_nl(f_one(a,b)) -- b can have %'s elseif a then - write_nl(format("%-15s :\n", a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -18212,6 +18717,7 @@ own.libs = { -- order can be made better 'util-tab.lua', 'util-sto.lua', + 'util-str.lua', -- code might move to l-string 'util-mrg.lua', 'util-lua.lua', 'util-prs.lua', diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 3a02ad582..83944d791 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -2257,7 +2257,7 @@ io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') +-- local data = f:read('*all') local data = readall(f) f:close() if #data > 0 then @@ -2286,29 +2286,29 @@ end function io.loadlines(filename,n) -- return nil if empty local f = io.open(filename,'r') - if f then - if n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break - end - end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - assert(f:close()) - if #line > 0 then - return line + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[#lines+1] = line + else + break end end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end @@ -2328,7 +2328,7 @@ function io.exists(filename) if f == nil then return false else - assert(f:close()) + f:close() return true end end @@ -2339,7 +2339,7 @@ function io.size(filename) return 0 else local s = f:seek("end") - assert(f:close()) + f:close() return s end end @@ -2347,9 +2347,13 @@ end function io.noflines(f) if type(f) == "string" then local f = io.open(filename) - local n = f and io.noflines(f) or 0 - assert(f:close()) - return n + if f then + local n = f and io.noflines(f) or 0 + f:close() + return n + else + return 0 + end else local n = 0 for _ in f:lines() do @@ -5800,6 +5804,58 @@ local function fastserialize(t,r,outer) -- no mixes return r end +-- local f_hashed_string = formatters["[%q]=%q,"] +-- local f_hashed_number = formatters["[%q]=%s,"] +-- local f_hashed_table = formatters["[%q]="] +-- local f_hashed_true = formatters["[%q]=true,"] +-- local f_hashed_false = formatters["[%q]=false,"] +-- +-- local f_indexed_string = formatters["%q,"] +-- local f_indexed_number = formatters["%s,"] +-- ----- f_indexed_true = formatters["true,"] +-- ----- f_indexed_false = formatters["false,"] +-- +-- local function fastserialize(t,r,outer) -- no mixes +-- r[#r+1] = "{" +-- local n = #t +-- if n > 0 then +-- for i=1,n do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_indexed_string(v) +-- elseif tv == "number" then +-- r[#r+1] = f_indexed_number(v) +-- elseif tv == "table" then +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k) +-- r[#r+1] = v and "true," or "false," +-- end +-- end +-- else +-- for k, v in next, t do +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_hashed_string(k,v) +-- elseif tv == "number" then +-- r[#r+1] = f_hashed_number(k,v) +-- elseif tv == "table" then +-- r[#r+1] = f_hashed_table(k) +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k) +-- end +-- end +-- end +-- if outer then +-- r[#r+1] = "}" +-- else +-- r[#r+1] = "}," +-- end +-- return r +-- end + function table.fastserialize(t,prefix) -- so prefix should contain the = return concat(fastserialize(t,{ prefix or "return" },true)) end @@ -6076,6 +6132,430 @@ end -- of closure do -- create closure to overcome 200 locals limit +if not modules then modules = { } end modules ['util-str'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +utilities = utilities or {} +utilities.strings = utilities.strings or { } +local strings = utilities.strings + +local load = load +local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub +local concat = table.concat +local P, V, C, S, R, Ct, Cs, Cp, Carg = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg +local patterns, lpegmatch = lpeg.patterns, lpeg.match +local utfchar, utfbyte = utf.char, utf.byte +local setmetatableindex = table.setmetatableindex +-- + +local stripper = patterns.stripzeros + +local function points(n) + return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +end + +local function basepoints(n) + return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) +end + +number.points = points +number.basepoints = basepoints + +-- str = " \n \ntest \n test\ntest " +-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]") + +local rubish = patterns.spaceortab^0 * patterns.newline +local anyrubish = patterns.spaceortab + patterns.newline +local anything = patterns.anything +local stripped = (patterns.spaceortab^1 / "") * patterns.newline +local leading = rubish^0 / "" +local trailing = (anyrubish^1 * patterns.endofstring) / "" +local redundant = rubish^3 / "\n" + +local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0) + +function strings.collapsecrlf(str) + return lpegmatch(pattern,str) +end + +-- The following functions might end up in another namespace. + +local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator + +function strings.newrepeater(str,offset) + offset = offset or 0 + local s = repeaters[str] + if not s then + s = { } + repeaters[str] = s + end + local t = s[offset] + if t then + return t + end + t = { } + setmetatableindex(t, function(t,k) + if not k then + return "" + end + local n = k + offset + local s = n > 0 and rep(str,n) or "" + t[k] = s + return s + end) + s[offset] = t + return t +end + +-- local dashes = strings.newrepeater("--",-1) +-- print(dashes[2],dashes[3],dashes[1]) + +local extra, tab, start = 0, 0, 4, 0 + +local nspaces = strings.newrepeater(" ") + +local pattern = + Carg(1) / function(t) + extra, tab, start = 0, t or 7, 1 + end + * Cs(( + Cp() * patterns.tab / function(position) + local current = (position - start + 1) + extra + local spaces = tab-(current-1) % tab + if spaces > 0 then + extra = extra + spaces - 1 + return nspaces[spaces] -- rep(" ",spaces) + else + return "" + end + end + + patterns.newline * Cp() / function(position) + extra, start = 0, position + end + + patterns.anything + )^1) + +function strings.tabtospace(str,tab) + return lpegmatch(pattern,str,1,tab or 7) +end + +-- local t = { +-- "1234567123456712345671234567", +-- "\tb\tc", +-- "a\tb\tc", +-- "aa\tbb\tcc", +-- "aaa\tbbb\tccc", +-- "aaaa\tbbbb\tcccc", +-- "aaaaa\tbbbbb\tccccc", +-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc", +-- "one\n two\nxxx three\nxx four\nx five\nsix", +-- } +-- for k=1,#t do +-- print(strings.tabtospace(t[k])) +-- end + +function strings.striplong(str) -- strips all leading spaces + str = gsub(str,"^%s*","") + str = gsub(str,"[\n\r]+ *","\n") + return str +end + +-- local template = string.striplong([[ +-- aaaa +-- bb +-- cccccc +-- ]]) + +function strings.nice(str) + str = gsub(str,"[:%-+_]+"," ") -- maybe more + return str +end + +-- Work in progress. Interesting is that compared to the built-in this +-- is faster in luatex than in luajittex where we have a comparable speed. + +local n = 0 + +-- we are somewhat sloppy in parsing prefixes as it's not that critical +-- +-- this does not work out ok: +-- +-- function fnc(...) -- 1,2,3 +-- print(...,...,...) -- 1,1,1,2,3 +-- end + +local prefix_any = C((S("+- .") + R("09"))^0) +local prefix_tab = C((1-R("az","AZ","09","%%"))^0) + +-- we've split all cases as then we can optimize them (let's omit the fuzzy u) + +local format_s = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%ss',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_q = function() + n = n + 1 + return format("format('%%q',(select(%s,...)))",n) -- maybe an own lpeg +end + +local format_i = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%si',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_d = format_i + +local format_f = function(f) + n = n + 1 + return format("format('%%%sf',(select(%s,...)))",f,n) +end + +local format_g = function(f) + n = n + 1 + return format("format('%%%sg',(select(%s,...)))",f,n) +end + +local format_G = function(f) + n = n + 1 + return format("format('%%%sG',(select(%s,...)))",f,n) +end + +local format_e = function(f) + n = n + 1 + return format("format('%%%se',(select(%s,...)))",f,n) +end + +local format_E = function(f) + n = n + 1 + return format("format('%%%sE',(select(%s,...)))",f,n) +end + +local format_x = function(f) + n = n + 1 + return format("format('%%%sx',(select(%s,...)))",f,n) +end + +local format_X = function(f) + n = n + 1 + return format("format('%%%sX',(select(%s,...)))",f,n) +end + +local format_o = function(f) + n = n + 1 + return format("format('%%%so',(select(%s,...)))",f,n) +end + +local format_c = function() + n = n + 1 + return format("utfchar((select(%s,...)))",n) +end + +local format_r = function(f) + n = n + 1 + return format("format('%%%s.0f',(select(%s,...)))",f,n) +end + +local format_v = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_V = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_u = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('u+%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_U = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('U+%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_p = function() + n = n + 1 + return format("points((select(%s,...)))",n) +end + +local format_b = function() + n = n + 1 + return format("basepoints((select(%s,...)))",n) +end + +local format_t = function(f) + n = n + 1 + if f and f ~= "" then + return format("concat((select(%s,...)),%q)",n,f) + else + return format("concat((select(%s,...)))",n) + end +end + +local format_l = function() + n = n + 1 + return format("(select(%s,...) and 'true' or 'false')",n) +end + +local format_a = function(s) + return format("%q",s) +end + +local builder = Ct { "start", + start = (P("%") * ( + V("s") + V("q") + + V("i") + V("d") + + V("f") + V("g") + V("G") + V("e") + V("E") + + V("x") + V("X") + V("o") + -- + + V("c") + -- + + V("r") + + V("v") + V("V") + V("u") + V("U") + + V("p") + V("b") + + V("t") + + V("l") + ) + + V("a") + )^0, + -- + ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string) + ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string) + ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer) + ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer) + ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float) + ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float) + ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float) + ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float) + ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float) + ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal) + ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL) + ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal) + -- + ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) + -- + ["r"] = (prefix_any * P("r")) / format_r, -- %r => round + ["v"] = (prefix_any * P("v")) / format_v, -- %v => 0x0a1b2 (when - no 0x) + ["V"] = (prefix_any * P("V")) / format_V, -- %V => 0x0A1B2 (when - no 0x) + ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+) + ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+) + ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units) + ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units) + ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat + ["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean + -- + ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_a, -- %a => text (including %%) +} + +-- we can be clever and only alias what is needed + +local template = [[ +local format = string.format +local concat = table.concat +local points = number.points +local basepoints = number.basepoints +local utfchar = utf.char +local utfbyte = utf.byte +return function(...) + return %s +end +]] + +local function make(t,str) + n = 0 + local p = lpegmatch(builder,str) +-- inspect(p) + local c = format(template,concat(p,"..")) +-- inspect(c) + formatter = load(c)() + t[str] = formatter + return formatter +end + +local formatters = string.formatters or { } +string.formatters = formatters + +setmetatableindex(formatters,make) + +function string.makeformatter(str) + return formatters[str] +end + +function string.formatter(str,...) + return formatters[str](...) +end + +-- local p1 = "%s test %f done %p and %c and %V or %+t or %%" +-- local p2 = "%s test %f done %s and %s and 0x%05X or %s or %%" +-- +-- local t = { 1,2,3,4 } +-- local r = "" +-- +-- local format, formatter, formatters = string.format, string.formatter, string.formatters +-- local utfchar, utfbyte, concat, points = utf.char, utf.byte, table.concat, number.points +-- +-- local c = os.clock() +-- local f = formatters[p1] +-- for i=1,500000 do +-- -- r = formatters[p1]("hans",123.45,123.45,123,"a",t) +-- r = formatter(p1,"hans",123.45,123.45,123,"a",t) +-- -- r = f("hans",123.45,123.45,123,"a",t) +-- end +-- print(os.clock()-c,r) +-- +-- local c = os.clock() +-- for i=1,500000 do +-- r = format(p2,"hans",123.45,points(123.45),utfchar(123),utfbyte("a"),concat(t,"+")) +-- end +-- print(os.clock()-c,r) + +-- local f = format +-- function string.format(fmt,...) +-- print(fmt,...) +-- return f(fmt,...) +-- end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + if not modules then modules = { } end modules ['util-mrg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", @@ -7875,6 +8355,7 @@ local texcount = tex and tex.count local next, type, select = next, type, select local setmetatableindex = table.setmetatableindex +local formatters = string.formatters @@ -7918,61 +8399,76 @@ if tex and (tex.jobname or tex.formatname) then write_nl(target,"\n") end + local f_one = formatters["%-15s > %s\n"] + local f_two = formatters["%-15s >\n"] + report = function(a,b,c,...) if c then - write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s >\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s"] + local f_two = formatters["%-15s >"] + direct = function(a,b,c,...) if c then - return format("%-15s > %s",translations[a],format(formats[b],c,...)) + return f_one(translations[a],format(formats[b],c,...)) elseif b then - return format("%-15s > %s",translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return format("%-15s >", translations[a]) + return f_two(translations[a]) else return "" end end + local f_one = formatters["%-15s > %s > %s\n"] + local f_two = formatters["%-15s > %s >\n"] + subreport = function(a,s,b,c,...) if c then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],translations[s],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,format("%-15s > %s >\n", translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s > %s"] + local f_two = formatters["%-15s > %s >"] + subdirect = function(a,s,b,c,...) if c then - return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...)) + return f_one(translations[a],translations[s],format(formats[b],c,...)) elseif b then - return format("%-15s > %s > %s",translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return format("%-15s > %s >", translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) if c then - write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s : %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s :\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -8027,37 +8523,46 @@ else write_nl("\n") end + local f_one = formatters["%-15s | %s"] + local f_two = formatters["%-15s |"] + report = function(a,b,c,...) if c then - write_nl(format("%-15s | %s",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s",a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(format("%-15s |", a)) + write_nl(f_two(a)) else write_nl("") end end + local f_one = formatters["%-15s | %s | %s"] + local f_two = formatters["%-15s | %s |"] + subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s | %s | %s",a,sub,format(b,c,...))) + write_nl(f_one(a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s | %s",a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(format("%-15s | %s |", a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) -- not to be used in lua anyway if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + write_nl(f_one(a,b)) -- b can have %'s elseif a then - write_nl(format("%-15s :\n", a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -18212,6 +18717,7 @@ own.libs = { -- order can be made better 'util-tab.lua', 'util-sto.lua', + 'util-str.lua', -- code might move to l-string 'util-mrg.lua', 'util-lua.lua', 'util-prs.lua', diff --git a/tex/context/base/anch-pgr.lua b/tex/context/base/anch-pgr.lua index aba61794b..7f53ef2e0 100644 --- a/tex/context/base/anch-pgr.lua +++ b/tex/context/base/anch-pgr.lua @@ -17,20 +17,19 @@ local splitter = lpeg.splitat(":") local lpegmatch = lpeg.match local jobpositions = job.positions +local formatters = string.formatters local report_graphics = logs.reporter("graphics") -local function point(n) - return format("%.5fpt",n/65536) -end +local f_b_tag = formatters["b:%s"] +local f_e_tag = formatters["e:%s"] +local f_p_tag = formatters["p:%s"] -local function pair(x,y) - return format("(%.5fpt,%.5fpt)",x/65536,y/65536) -end +local f_tag_two = formatters["%s:%s"] -local function path(t) - return concat(t,"--") .. "--cycle" -end +local f_point = formatters["%p"] +local f_pair = formatters["(%p,%p)"] +local f_path = formatters["%--t--cycle"] local function regionarea(r) local rx, ry = r.x, r.y @@ -38,10 +37,10 @@ local function regionarea(r) local rh = ry + r.h local rd = ry - r.d return { - pair(rx, rh - ry), - pair(rw, rh - ry), - pair(rw, rd - ry), - pair(rx, rd - ry), + f_pair(rx, rh - ry), + f_pair(rw, rh - ry), + f_pair(rw, rd - ry), + f_pair(rx, rd - ry), } end @@ -245,10 +244,10 @@ local function singlepart(b,e,r,left,right,obeyhang) local area if by == ey then area = { - pair(bx,bh-ry), - pair(ex,eh-ry), - pair(ex,ed-ry), - pair(bx,bd-ry), + f_pair(bx,bh-ry), + f_pair(ex,eh-ry), + f_pair(ex,ed-ry), + f_pair(bx,bd-ry), } else area = { } @@ -269,7 +268,7 @@ local function singlepart(b,e,r,left,right,obeyhang) finish(area) for i=1,#area do local a = area[i] - area[i] = pair(a[1],a[2]) + area[i] = f_pair(a[1],a[2]) end end return { @@ -307,7 +306,7 @@ local function firstpart(b,r,left,right,obeyhang) finish(area) for i=1,#area do local a = area[i] - area[i] = pair(a[1],a[2]) + area[i] = f_pair(a[1],a[2]) end return { location = "first", @@ -338,7 +337,7 @@ local function middlepart(r,left,right,obeyhang) finish(area) for i=1,#area do local a = area[i] - area[i] = pair(a[1],a[2]) + area[i] = f_pair(a[1],a[2]) end return { location = "middle", @@ -375,7 +374,7 @@ local function lastpart(e,r,left,right,obeyhang) finish(area) for i=1,#area do local a = area[i] - area[i] = pair(a[1],a[2]) + area[i] = f_pair(a[1],a[2]) end return { location = "last", @@ -391,8 +390,8 @@ graphics.backgrounds = backgrounds local function calculatemultipar(tag,obeyhang) local collected = jobpositions.collected - local b = collected[format("b:%s",tag)] - local e = collected[format("e:%s",tag)] + local b = collected[f_b_tag(tag)] + local e = collected[f_e_tag(tag)] if not b or not e then report_graphics("invalid tag '%s'",tag) return { } @@ -434,7 +433,7 @@ local function calculatemultipar(tag,obeyhang) -- local bn = b.n if bn then - local bp = collected[format("p:%s",bn)] + local bp = collected[f_p_tag(bn)] if bp then left = left + bp.ls right = right + bp.rs @@ -452,7 +451,7 @@ local function calculatemultipar(tag,obeyhang) [b.p] = { firstpart(b,collected[br],left,right,obeyhang) }, } for i=bindex+1,eindex-1 do - br = format("%s:%s",btag,i) + br = f_tag_two(btag,i) local r = collected[br] if not r then report_graphics("invalid middle for '%s'",br) @@ -525,32 +524,37 @@ local multilocs = { -- if unknown context_abck : input mp-abck.mpiv ; fi ; -local template_a = [[ +local f_template_a = [[ path multiregs[], multipars[], multibox ; string multikind[] ; numeric multilocs[], nofmultipars ; nofmultipars := %s ; -multibox := unitsquare xyscaled %s ; +multibox := unitsquare xyscaled (%p,%p) ; numeric par_strut_height, par_strut_depth, par_line_height ; -par_strut_height := %s ; -par_strut_depth := %s ; -par_line_height := %s ; +par_strut_height := %p ; +par_strut_depth := %p ; +par_line_height := %p ; ]] -local template_b = [[ +local f_template_b = [[ multilocs[%s] := %s ; multikind[%s] := "%s" ; -multipars[%s] := (%s) shifted - %s ; +multipars[%s] := (%--t--cycle) shifted - (%p,%p) ; ]] -local template_c = [[ -multiregs[%s] := (%s) shifted - %s ; +local f_template_c = [[ +multiregs[%s] := (%--t--cycle) shifted - %s ; ]] -local template_d = [[ +local f_template_d = [[ setbounds currentpicture to multibox ; ]] +f_template_a = formatters[f_template_a] +f_template_b = formatters[f_template_b] +f_template_c = formatters[f_template_c] +f_template_d = formatters[f_template_d] + function backgrounds.fetchmultipar(n,anchor,page,obeyhang) local data = pbg[n] if not data then @@ -573,32 +577,31 @@ function backgrounds.fetchmultipar(n,anchor,page,obeyhang) local x, y, w, h, d = a.x, a.y, a.w, a.h, a.d local bpos = data.bpos local bh, bd = bpos.h, bpos.d - local result = { format(template_a,nofmultipars,pair(w,h+d),point(bh),point(bd),point(bh+bd)) } + local result = { f_template_a(nofmultipars,w,h+d,bh,bd,bh+bd) } for i=1,nofmultipars do local region = pagedata[i] - result[#result+1] = format(template_b, + result[#result+1] = f_template_b( i, multilocs[region.location], i, region.location, - i, path(region.area), pair(x,y-region.region.y)) + i, region.area, x, y-region.region.y) if trace then - result[#result+1] = format(template_c, - i, path(regionarea(region.region)), offset) + result[#result+1] = f_template_c(i, regionarea(region.region), offset) end end data[page] = nil - result[#result+1] = template_d + result[#result+1] = f_template_d() result = concat(result,"\n") return result end end end end - return format(template_a,0,"origin",0,0,0) + return f_template_a(0,"origin",0,0,0) end -backgrounds.point = point -backgrounds.pair = pair -backgrounds.path = path +backgrounds.point = f_point +backgrounds.pair = f_pair +backgrounds.path = f_path function commands.fetchmultipar(n,anchor,page) context(backgrounds.fetchmultipar(n,anchor,page)) @@ -608,20 +611,23 @@ function commands.fetchmultishape(n,anchor,page) context(backgrounds.fetchmultipar(n,anchor,page,true)) end -local template_a = [[ +local f_template_a = [[ path posboxes[], posregions[] ; numeric pospages[] ; numeric nofposboxes ; nofposboxes := %s ; -%s ; +%t ; ]] -local template_b = [[ +local f_template_b = [[ pospages[%s] := %s ; -posboxes[%s] := %s--%s--%s--%s--cycle ; -posregions[%s] := %s--%s--%s--%s--cycle ; +posboxes[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; +posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; ]] +f_template_a = formatters[f_template_a] +f_template_b = formatters[f_template_b] + function commands.fetchposboxes(tags,anchor,page) -- no caching (yet) / todo: anchor, page local collected = jobpositions.collected if type(tags) == "string" then @@ -643,10 +649,10 @@ function commands.fetchposboxes(tags,anchor,page) -- no caching (yet) / todo: an local ch = cy + c.h local cd = cy - c.d nofboxes = nofboxes + 1 - list[nofboxes] = format(template_b, + list[nofboxes] = f_template_b( nofboxes,c.p, - nofboxes,pair(cx,ch),pair(cw,ch),pair(cw,cd),pair(cx,cd), - nofboxes,pair(0,rh),pair(rw,rh),pair(rw,rd),pair(0,rd) + nofboxes,cx,ch,cw,ch,cw,cd,cx,cd, + nofboxes,0,rh,rw,rh,rw,rd,0,rd ) end end @@ -654,8 +660,7 @@ function commands.fetchposboxes(tags,anchor,page) -- no caching (yet) / todo: an print("\n missing",tag) end end - -- print(format(template_a,nofboxes,concat(list))) - context(template_a,nofboxes,concat(list)) + context(f_template_a(nofboxes,list)) end local doifelse = commands.doifelse diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua index eda0ba37a..2697cecf4 100644 --- a/tex/context/base/anch-pos.lua +++ b/tex/context/base/anch-pos.lua @@ -41,6 +41,7 @@ local v_column = variables.column local pt = number.dimenfactors.pt local pts = number.pts +local formatters = string.formatters local collected = allocate() local tobesaved = allocate() @@ -73,6 +74,23 @@ local default = { -- not r and paragraphs etc } } +local f_b_tag = formatters["b:%s"] +local f_e_tag = formatters["e:%s"] +local f_p_tag = formatters["p:%s"] +local f_w_tag = formatters["w:%s"] + +local f_b_column = formatters["_plib_.b_col(%q)"] +local f_e_column = formatters["_plib_.e_col()"] + +local f_enhance = formatters["_plib_.enhance(%q)"] +local f_region = formatters["region:%s"] + +local f_b_region = formatters["_plib_.b_region(%q)"] +local f_e_region = formatters["_plib_.e_region(%s)"] + +local f_tag_three = formatters["%s:%s:%s"] +local f_tag_two = formatters["%s:%s"] + local function sorter(a,b) return a.y > b.y end @@ -277,13 +295,13 @@ function commands.bcolumn(tag,register) insert(columns,tag) column = tag if register then - context(new_latelua(format("_plib_.b_col(%q)",tag))) + context(new_latelua(f_b_column(tag))) end end function commands.ecolumn(register) if register then - context(new_latelua("_plib_.e_col()")) + context(new_latelua(f_e_column())) end remove(columns) column = columns[#columns] @@ -313,7 +331,7 @@ end function jobpositions.markregionbox(n,tag,correct) if not tag or tag == "" then nofregions = nofregions + 1 - tag = format("region:%s",nofregions) + tag = f_region(nofregions) end local box = texbox[n] local w = box.width @@ -327,8 +345,8 @@ function jobpositions.markregionbox(n,tag,correct) h = h ~= 0 and h or nil, d = d ~= 0 and d or nil, } - local push = new_latelua(format("_plib_.b_region(%q)",tag)) - local pop = new_latelua(format("_plib_.e_region(%s)",tostring(correct))) + local push = new_latelua(f_b_region(tag)) + local pop = new_latelua(f_e_region(tostring(correct))) -- todo: check if tostring is needed with formatter -- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end local head = box.list if head then @@ -350,7 +368,7 @@ end function commands.pos(name,t) tobesaved[name] = t - context(new_latelua(format("_plib_.enhance(%q)",name))) + context(new_latelua(f_enhance(name))) end local nofparagraphs = 0 @@ -393,9 +411,9 @@ function commands.parpos() -- todo: relate to localpar (so this is an intermedia if parshape and #parshape > 0 then t.ps = parshape end - local tag = format("p:%s",nofparagraphs) + local tag = f_p_tag(nofparagraphs) tobesaved[tag] = t - context(new_latelua(format("_plib_.enhance(%q)",tag))) + context(new_latelua(f_enhance(tag))) end function commands.posxy(name) -- can node.write be used here? @@ -407,7 +425,7 @@ function commands.posxy(name) -- can node.write be used here? y = true, n = nofparagraphs > 0 and nofparagraphs or nil, } - context(new_latelua(format("_plib_.enhance(%q)",name))) + context(new_latelua(f_enhance(name))) end function commands.poswhd(name,w,h,d) @@ -422,7 +440,7 @@ function commands.poswhd(name,w,h,d) d = d, n = nofparagraphs > 0 and nofparagraphs or nil, } - context(new_latelua(format("_plib_.enhance(%q)",name))) + context(new_latelua(f_enhance(name))) end function commands.posplus(name,w,h,d,extra) @@ -438,7 +456,7 @@ function commands.posplus(name,w,h,d,extra) n = nofparagraphs > 0 and nofparagraphs or nil, e = extra, } - context(new_latelua(format("_plib_.enhance(%q)",name))) + context(new_latelua(f_enhance(name))) end function commands.posstrut(name,w,h,d) @@ -453,12 +471,12 @@ function commands.posstrut(name,w,h,d) d = strutbox.depth, n = nofparagraphs > 0 and nofparagraphs or nil, } - context(new_latelua(format("_plib_.enhance(%q)",name))) + context(new_latelua(f_enhance(name))) end function jobpositions.getreserved(tag,n) if tag == v_column then - local fulltag = format("%s:%s:%s",tag,texcount.realpageno,n or 1) + local fulltag = f_tag_three(tag,texcount.realpageno,n or 1) local data = collected[fulltag] if data then return data, fulltag @@ -466,7 +484,7 @@ function jobpositions.getreserved(tag,n) tag = v_text end if tag == v_text then - local fulltag = format("%s:%s",tag,texcount.realpageno) + local fulltag = f_tag_two(tag,texcount.realpageno) return collected[fulltag] or false, fulltag end return collected[tag] or false, tag @@ -887,7 +905,7 @@ end local function MPpardata(n) local t = collected[n] if not t then - local tag = format("p:%s",n) + local tag = f_p_tag(n) t = collected[tag] end if t then @@ -907,10 +925,10 @@ end commands.MPpardata = MPpardata function commands.MPposset(id) -- special helper, used in backgrounds - local b = format("b:%s",id) - local e = format("e:%s",id) - local w = format("w:%s",id) - local p = format("p:%s",jobpositions.n(b)) + local b = f_b_tag(id) + local e = f_e_tag(id) + local w = f_w_tag(id) + local p = f_p_tag(jobpositions.n(b)) MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p) end diff --git a/tex/context/base/attr-col.lua b/tex/context/base/attr-col.lua index 18182ba85..d4139daf7 100644 --- a/tex/context/base/attr-col.lua +++ b/tex/context/base/attr-col.lua @@ -41,6 +41,7 @@ local registrations = backends.registrations local unsetvalue = attributes.unsetvalue local registerstorage = storage.register +local formatters = string.formatters -- We can distinguish between rules and glyphs but it's not worth the trouble. A -- first implementation did that and while it saves a bit for glyphs and rules, it @@ -100,11 +101,11 @@ local list = attributes.list registerstorage("attributes/colors/values", values, "attributes.colors.values") registerstorage("attributes/colors/registered", registered, "attributes.colors.registered") -local templates = { - rgb = "r:%s:%s:%s", - cmyk = "c:%s:%s:%s:%s", - gray = "s:%s", - spot = "p:%s:%s:%s:%s" +local f_colors = { + rgb = formatters["r:%s:%s:%s"], + cmyk = formatters["c:%s:%s:%s:%s"], + gray = formatters["s:%s"], + spot = formatters["p:%s:%s:%s:%s"], } local models = { @@ -322,7 +323,7 @@ function colors.setmodel(name,weightgray) end function colors.register(name, colorspace, ...) -- passing 9 vars is faster (but not called that often) - local stamp = format(templates[colorspace],...) + local stamp = f_colors[colorspace](...) local color = registered[stamp] if not color then color = #values + 1 @@ -379,7 +380,7 @@ transparencies.supported = true local registered = transparencies.registered -- we could use a 2 dimensional table instead local data = transparencies.data local values = transparencies.values -local template = "%s:%s" +local f_transparency = formatters["%s:%s"] registerstorage("attributes/transparencies/registered", registered, "attributes.transparencies.registered") registerstorage("attributes/transparencies/values", values, "attributes.transparencies.values") @@ -399,7 +400,7 @@ function transparencies.register(name,a,t,force) -- name is irrelevant here (can -- but then we'd end up with transparencies resources even if we -- would not use transparencies (but define them only). This is -- somewhat messy. - local stamp = format(template,a,t) + local stamp = f_transparency(a,t) local n = registered[stamp] if not n then n = #values + 1 diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv index 7e910f07f..e0966ef52 100644 --- a/tex/context/base/back-pdf.mkiv +++ b/tex/context/base/back-pdf.mkiv @@ -141,7 +141,7 @@ % % function lpdf.rotationcm(a) % local s, c = sind(a), cosd(a) -% return format("%s %s %s %s 0 0 cm",c,s,-s,c) +% return format("%f %f %f %f 0 0 cm",c,s,-s,c) % end % % \def\dostartmirroring{\pdfliteral{-1 0 0 1 0 0 cm}} diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua index 3ab2e53b6..1967948de 100644 --- a/tex/context/base/chem-str.lua +++ b/tex/context/base/chem-str.lua @@ -40,8 +40,9 @@ local settings_to_array_with_repeat = utilities.parsers.settings_to_array_with_r local lpegmatch = lpeg.match local P, R, S, C, Cs, Ct, Cc, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Cmt -local variables = interfaces and interfaces.variables -local context = context +local variables = interfaces and interfaces.variables +local context = context +local formatters = string.formatters local v_default = variables.default local v_small = variables.small @@ -311,18 +312,18 @@ local pattern = -- print(lpegmatch(pattern,"RZ1..3=x")) -- 1 RZ 1 3 false x -- print(lpegmatch(pattern,"RZ13=x")) -- 1 RZ false false table x -local t_initialize = 'if unknown context_chem : input mp-chem.mpiv ; fi ;' -local t_start_structure = 'chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);' -local t_stop_structure = 'chem_stop_structure;' -local t_start_component = 'chem_start_component;' -local t_stop_component = 'chem_stop_component;' -local t_line = 'chem_%s%s(%s,%s,%s,%s,%s);' -local t_set = 'chem_set(%s);' -local t_number = 'chem_%s%s(%s,%s,"\\chemicaltext{%s}");' -local t_text = t_number -local t_empty_normal = 'chem_%s(%s,%s,"");' -local t_empty_center = 'chem_c%s(%s,%s,"");' -local t_transform = 'chem_%s(%s,%s,%s);' +local f_initialize = formatters['if unknown context_chem : input mp-chem.mpiv ; fi ;'] +local f_start_structure = formatters['chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);'] +local f_stop_structure = formatters['chem_stop_structure;'] +local f_start_component = formatters['chem_start_component;'] +local f_stop_component = formatters['chem_stop_component;'] +local f_line = formatters['chem_%s%s(%s,%s,%s,%s,%s);'] +local f_set = formatters['chem_set(%s);'] +local f_number = formatters['chem_%s%s(%s,%s,"\\chemicaltext{%s}");'] +local f_text = f_number +local f_empty_normal = formatters['chem_%s(%s,%s,"");'] +local f_empty_center = formatters['chem_c%s(%s,%s,"");'] +local f_transform = formatters['chem_%s(%s,%s,%s);'] local prepareMPvariable = commands and commands.prepareMPvariable @@ -398,9 +399,9 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ m = m + 1 ; metacode[m] = syntax.pb.direct if keys[special] == "text" and index then if keys["c"..special] == "text" then -- can be option: auto ... - m = m + 1 ; metacode[m] = format(t_empty_center,special,variant,index) + m = m + 1 ; metacode[m] = f_empty_center(special,variant,index) else - m = m + 1 ; metacode[m] = format(t_empty_normal,special,variant,index) + m = m + 1 ; metacode[m] = f_empty_normal(special,variant,index) end end elseif operation == "pe" then @@ -408,7 +409,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ local ss = syntax[variant] keys, max = ss.keys, ss.max m = m + 1 ; metacode[m] = syntax[operation].direct - m = m + 1 ; metacode[m] = format(t_set,variant) + m = m + 1 ; metacode[m] = f_set(variant) current_variant = variant elseif operation == "save" then insert(sstack,variant) @@ -418,7 +419,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ local ss = syntax[variant] keys, max = ss.keys, ss.max m = m + 1 ; metacode[m] = syntax[operation].direct - m = m + 1 ; metacode[m] = format(t_set,variant) + m = m + 1 ; metacode[m] = f_set(variant) current_variant = variant elseif operation then local ss = syntax[operation] @@ -481,7 +482,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ end elseif ss.keys then variant, keys, max = s, ss.keys, ss.max - m = m + 1 ; metacode[m] = format(t_set,variant) + m = m + 1 ; metacode[m] = f_set(variant) current_variant = variant end elseif what == "line" then @@ -494,35 +495,35 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ local sf, st = set[1] for i=1,ns do if i > 1 and set[i] ~= set[i-1]+1 then - m = m + 1 ; metacode[m] = format(t_line,operation,s,variant,sf,st,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_line(operation,s,variant,sf,st,rulethickness,rulecolor) sf = set[i] end st = set[i] end - m = m + 1 ; metacode[m] = format(t_line,operation,s,variant,sf,st,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_line(operation,s,variant,sf,st,rulethickness,rulecolor) elseif upto then - m = m + 1 ; metacode[m] = format(t_line,operation,s,variant,index,upto,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_line(operation,s,variant,index,upto,rulethickness,rulecolor) elseif index then - m = m + 1 ; metacode[m] = format(t_line,operation,s,variant,index,index,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_line(operation,s,variant,index,index,rulethickness,rulecolor) else - m = m + 1 ; metacode[m] = format(t_line,operation,s,variant,1,max,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_line(operation,s,variant,1,max,rulethickness,rulecolor) end elseif what == "number" then if set then for i=1,ns do local si = set[i] - m = m + 1 ; metacode[m] = format(t_number,operation,align,variant,si,si) + m = m + 1 ; metacode[m] = f_number(operation,align,variant,si,si) end elseif upto then for i=index,upto do local si = set[i] - m = m + 1 ; metacode[m] = format(t_number,operation,align,variant,si,si) + m = m + 1 ; metacode[m] = f_number(operation,align,variant,si,si) end elseif index then - m = m + 1 ; metacode[m] = format(t_number,operation,align,variant,index,index) + m = m + 1 ; metacode[m] = f_number(operation,align,variant,index,index) else for i=1,max do - m = m + 1 ; metacode[m] = format(t_number,operation,align,variant,i,i) + m = m + 1 ; metacode[m] = f_number(operation,align,variant,i,i) end end elseif what == "text" then @@ -533,7 +534,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if not t then txt, t = fetch(txt) end if t then t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = format(t_text,operation,align,variant,si,t) + m = m + 1 ; metacode[m] = f_text(operation,align,variant,si,t) end end elseif upto then @@ -542,7 +543,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if not t then txt, t = fetch(txt) end if t then t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = format(t_text,operation,align,variant,i,t) + m = m + 1 ; metacode[m] = f_text(operation,align,variant,i,t) end end elseif index == 0 then @@ -550,14 +551,14 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if not t then txt, t = fetch(txt) end if t then t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = format(t_text,operation,align,variant,index,t) + m = m + 1 ; metacode[m] = f_text(operation,align,variant,index,t) end elseif index then local t = text if not t then txt, t = fetch(txt) end if t then t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = format(t_text,operation,align,variant,index,t) + m = m + 1 ; metacode[m] = f_text(operation,align,variant,index,t) end else for i=1,max do @@ -565,7 +566,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if not t then txt, t = fetch(txt) end if t then t = molecule(processor_tostring(t)) - m = m + 1 ; metacode[m] = format(t_text,operation,align,variant,i,t) + m = m + 1 ; metacode[m] = f_text(operation,align,variant,i,t) end end end @@ -576,17 +577,17 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if set then for i=1,ns do local si = set[i] - m = m + 1 ; metacode[m] = format(t_transform,operation,variant,si,factor) + m = m + 1 ; metacode[m] = f_transform(operation,variant,si,factor) end elseif upto then for i=index,upto do - m = m + 1 ; metacode[m] = format(t_transform,operation,variant,i,factor) + m = m + 1 ; metacode[m] = f_transform(operation,variant,i,factor) end else - m = m + 1 ; metacode[m] = format(t_transform,operation,variant,index or 1,factor) + m = m + 1 ; metacode[m] = f_transform(operation,variant,index or 1,factor) end elseif what == "fixed" then - m = m + 1 ; metacode[m] = format(t_transform,operation,variant,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_transform(operation,variant,rulethickness,rulecolor) elseif trace_structure then report_chemistry("%s > warning: undefined operation %s ignored here", level, operation or "") @@ -685,7 +686,7 @@ function chemistry.start(settings) end rotation = tonumber(rotation) or 0 -- - metacode[#metacode+1] = format(t_start_structure, + metacode[#metacode+1] = f_start_structure( chemistry.structures, l, r, t, b, scale, rotation, tostring(width), tostring(height), tostring(emwidth), tostring(offset), @@ -696,19 +697,19 @@ function chemistry.start(settings) end function chemistry.stop() - metacode[#metacode+1] = t_stop_structure + metacode[#metacode+1] = f_stop_structure() local mpcode = concat(metacode,"\n") if trace_metapost then report_chemistry("metapost code:\n%s", mpcode) end if metapost.instance(chemistry.instance) then - t_initialize = "" + f_initialize = nil end metapost.graphic { instance = chemistry.instance, format = chemistry.format, data = mpcode, - definitions = t_initialize, + definitions = f_initialize and f_initialize(), } t_initialize = "" metacode = nil @@ -719,9 +720,9 @@ function chemistry.component(spec,text,settings) local spec = settings_to_array_with_repeat(spec,true) -- no lower? local text = settings_to_array_with_repeat(text,true) -- inspect(spec) - metacode[#metacode+1] = t_start_component + metacode[#metacode+1] = f_start_component() process(1,spec,text,1,rulethickness,rulecolor) -- offset? - metacode[#metacode+1] = t_stop_component + metacode[#metacode+1] = f_stop_component() end statistics.register("chemical formulas", function() diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua index b045282b1..c943dcb51 100644 --- a/tex/context/base/cldf-ini.lua +++ b/tex/context/base/cldf-ini.lua @@ -609,7 +609,7 @@ function context.fprint(catcodes,fmt,first,...) end else if fmt then - flush(format(catodes,fmt,first,...)) + flush(format(catcodes,fmt,first,...)) else flush(catcodes) end @@ -624,6 +624,24 @@ function tex.fprint(fmt,first,...) -- goodie end end +local formatters = string.formatters + +function context.formatted(catcodes,fmt,first,...) + if type(catcodes) == "number" then + if first then + flush(catcodes,formatters[fmt](first,...)) + else + flush(catcodes,fmt) + end + else + if fmt then + flush(formatters[catcodes](fmt,first,...)) + else + flush(catcodes) + end + end +end + -- logging local trace_stack = { } diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 988b0384d..9e36f1a86 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png Binary files differindex b588b612d..db588f664 100644 --- a/tex/context/base/context-version.png +++ b/tex/context/base/context-version.png diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index 5f00d6fff..b1b830c31 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -35,7 +35,7 @@ local report_passes = logs.reporter("job","passes") job = job or { } local job = job -job.version = "1.20" +job.version = "1.21" -- some day we will implement loading of other jobs and then we need -- job.jobs diff --git a/tex/context/base/data-tex.lua b/tex/context/base/data-tex.lua index f19b53407..6ba742cce 100644 --- a/tex/context/base/data-tex.lua +++ b/tex/context/base/data-tex.lua @@ -67,6 +67,7 @@ function helpers.textopener(tag,filename,filehandle,coding) lines = filehandle else lines = filehandle:read("*a") -- io.readall(filehandle) ... but never that large files anyway + -- lines = io.readall(filehandle) filehandle:close() end if type(lines) == "string" then diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index ee59de508..d58221fe7 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -43,6 +43,7 @@ local contains = table.contains local concat, insert, remove = table.concat, table.insert, table.remove local todimen = string.todimen local collapsepath = file.collapsepath +local formatters = string.formatters local P, lpegmatch = lpeg.P, lpeg.match @@ -65,6 +66,9 @@ local report_inclusion = logs.reporter("graphics","inclusion") local context, img = context, img +local f_hash_part = formatters["%s->%s->%s"] +local f_hash_full = formatters["%s->%s->%s->%s->%s->%s->%s"] + local maxdimen = 2^30-1 function img.check(figure) @@ -635,7 +639,7 @@ local function register(askedname,specification) end end specification.foundname = specification.foundname or specification.fullname - local askedhash = format("%s->%s->%s",askedname,specification.conversion or "default",specification.resolution or "default") + local askedhash = f_hash_part(askedname,specification.conversion or "default",specification.resolution or "default") figures_found[askedhash] = specification return specification end @@ -646,7 +650,7 @@ local function locate(request) -- name, format, cache -- not resolvers.cleanpath(request.name) as it fails on a!b.pdf and b~c.pdf -- todo: more restricted cleanpath local askedname = request.name - local askedhash = format("%s->%s->%s",askedname,request.conversion or "default",request.resolution or "default") + local askedhash = f_hash_part(askedname,request.conversion or "default",request.resolution or "default") local foundname = figures_found[askedhash] if foundname then return foundname @@ -980,7 +984,7 @@ function checkers.generic(data) if not resolution or resolution == "" then resolution = "unknown" end - local hash = format("%s->%s->%s->%s->%s->%s->%s",name,page,size,color,conversion,resolution,mask) + local hash = f_hash_full(name,page,size,color,conversion,resolution,mask) local figure = figures_loaded[hash] if figure == nil then figure = img.new { diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua index e7bc23642..e48b448c5 100644 --- a/tex/context/base/l-io.lua +++ b/tex/context/base/l-io.lua @@ -59,7 +59,7 @@ io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') +-- local data = f:read('*all') local data = readall(f) f:close() if #data > 0 then @@ -88,29 +88,29 @@ end function io.loadlines(filename,n) -- return nil if empty local f = io.open(filename,'r') - if f then - if n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break - end - end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - assert(f:close()) - if #line > 0 then - return line + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[#lines+1] = line + else + break end end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end @@ -130,7 +130,7 @@ function io.exists(filename) if f == nil then return false else - assert(f:close()) + f:close() return true end end @@ -141,7 +141,7 @@ function io.size(filename) return 0 else local s = f:seek("end") - assert(f:close()) + f:close() return s end end @@ -149,9 +149,13 @@ end function io.noflines(f) if type(f) == "string" then local f = io.open(filename) - local n = f and io.noflines(f) or 0 - assert(f:close()) - return n + if f then + local n = f and io.noflines(f) or 0 + f:close() + return n + else + return 0 + end else local n = 0 for _ in f:lines() do diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua index db9d3268b..4936b37c9 100644 --- a/tex/context/base/lpdf-col.lua +++ b/tex/context/base/lpdf-col.lua @@ -14,6 +14,7 @@ local round = math.round local backends, lpdf, nodes = backends, lpdf, nodes local allocate = utilities.storage.allocate +local formatters = string.formatters local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections @@ -42,6 +43,11 @@ local forcedmodel = colors.forcedmodel local c_transparency = pdfconstant("Transparency") +local f_gray = formatters["%.3f g %.3f G"] +local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"] +local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"] +local f_cm = formatters["q %f %f %f %f %f %f cm"] + local report_color = logs.reporter("colors","backend") -- page groups (might move to lpdf-ini.lua) @@ -99,15 +105,15 @@ commands.synchronizecolormodel = synchronizecolormodel -- color injection function nodeinjections.rgbcolor(r,g,b) - return register(pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))) + return register(pdfliteral(f_rgb(r,g,b,r,g,b))) end function nodeinjections.cmykcolor(c,m,y,k) - return register(pdfliteral(format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k))) + return register(pdfliteral(f_cmyk(c,m,y,k,c,m,y,k))) end function nodeinjections.graycolor(s) -- caching 0/1 does not pay off - return register(pdfliteral(format("%s g %s G",s,s))) + return register(pdfliteral(f_gray(s,s))) end function nodeinjections.spotcolor(n,f,d,p) @@ -154,9 +160,9 @@ local pdf_rbg_range = pdfarray { 0, 1, 0, 1, 0, 1 } local pdf_cmyk_range = pdfarray { 0, 1, 0, 1, 0, 1, 0, 1 } local pdf_gray_range = pdfarray { 0, 1 } -local rgb_function = "dup %s mul exch dup %s mul exch %s mul" -local cmyk_function = "dup %s mul exch dup %s mul exch dup %s mul exch %s mul" -local gray_function = "%s mul" +local f_rgb_function = formatters["dup %s mul exch dup %s mul exch %s mul"] +local f_cmyk_function = formatters["dup %s mul exch dup %s mul exch dup %s mul exch %s mul"] +local f_gray_function = formatters["%s mul"] local documentcolorspaces = pdfdictionary() @@ -345,47 +351,47 @@ end function registrations.rgbspotcolor(name,noffractions,names,p,r,g,b) if noffractions == 1 then - registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,format(rgb_function,r,g,b)) + registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,f_rgb_function(r,g,b)) else registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,format("%s %s %s",r,g,b)) end delayindexcolor(name,names,function() - return registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,format(rgb_function,r,g,b)) + return registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,f_rgb_function(r,g,b)) end) end function registrations.cmykspotcolor(name,noffractions,names,p,c,m,y,k) if noffractions == 1 then - registersomespotcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) + registersomespotcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,f_cmyk_function(c,m,y,k)) else registersomespotcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format("%s %s %s %s",c,m,y,k)) end delayindexcolor(name,names,function() - return registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) + return registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,f_cmyk_function(c,m,y,k)) end) end function registrations.grayspotcolor(name,noffractions,names,p,s) if noffractions == 1 then - registersomespotcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,format(gray_function,s)) + registersomespotcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,f_gray_function(s)) else registersomespotcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,s) end delayindexcolor(name,names,function() - return registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,format(gray_function,s)) + return registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,f_gray_function(s)) end) end function registrations.rgbindexcolor(name,noffractions,names,p,r,g,b) - registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,format(rgb_function,r,g,b)) + registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,f_rgb_function(r,g,b)) end function registrations.cmykindexcolor(name,noffractions,names,p,c,m,y,k) - registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,format(cmyk_function,c,m,y,k)) + registersomeindexcolor(name,noffractions,names,p,pdf_device_cmyk,pdf_cmyk_range,f_cmyk_function(c,m,y,k)) end function registrations.grayindexcolor(name,noffractions,names,p,s) - registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,gray_function) + registersomeindexcolor(name,noffractions,names,p,pdf_device_gray,pdf_gray_range,f_gray_function(s)) end function codeinjections.setfigurecolorspace(data,figure) @@ -461,11 +467,10 @@ end statistics.register("page group warning", function() if done and not transparencygroups[currentgroupcolormodel] then - return format("transparencies are used but no pagecolormodel is set") + return "transparencies are used but no pagecolormodel is set" end end) - -- Literals needed to inject code in the mp stream, we cannot use attributes there -- since literals may have qQ's, much may go away once we have mplib code in place. -- @@ -482,13 +487,13 @@ local function lpdfcolor(model,ca,default) -- todo: use gray when no color model = forcedmodel(model) if model == 2 then local s = cv[2] - return format("%s g %s G",s,s) + return f_gray(s,s) elseif model == 3 then local r, g, b = cv[3], cv[4], cv[5] - return format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b) + return f_rgb(r,g,b,r,g,b) elseif model == 4 then local c, m, y, k = cv[6],cv[7],cv[8],cv[9] - return format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k) + return f_cmyk(c,m,y,k,c,m,y,k) else local n,f,d,p = cv[10],cv[11],cv[12],cv[13] if type(p) == "string" then @@ -497,7 +502,7 @@ local function lpdfcolor(model,ca,default) -- todo: use gray when no color return format("/%s cs /%s CS %s SCN %s scn",n,n,p,p) end else - return format("%s g %s G",default or 0,default or 0) + return f_gray(default or 0,default or 0) end else return "" @@ -716,7 +721,7 @@ backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph a palegray = { "special", 'pdf: .75 g' }, }, - startslant = function(a) return { "special", format("pdf: q 1 0 %s 1 0 0 cm",a) } end, + startslant = function(a) return { "special", format("pdf: q 1 0 %f 1 0 0 cm",a) } end, stopslant = { "special", "pdf: Q" }, } diff --git a/tex/context/base/lpdf-grp.lua b/tex/context/base/lpdf-grp.lua index aba5771fd..fed5e6a46 100644 --- a/tex/context/base/lpdf-grp.lua +++ b/tex/context/base/lpdf-grp.lua @@ -236,7 +236,7 @@ function img.package(image) -- see lpdf-u3d ** local height = boundingbox[4] local xform = img.scan { attr = resources(), - stream = format("%s 0 0 %s 0 0 cm /%s Do",width,height,imagetag), + stream = format("%f 0 0 %f 0 0 cm /%s Do",width,height,imagetag), bbox = { 0, 0, width/factor, height/factor }, } img.immediatewrite(xform) diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index c1b742949..bdecf63c2 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -11,6 +11,7 @@ local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string local utfchar, utfvalues = utf.char, utf.values local sind, cosd = math.sind, math.cosd local lpegmatch, P, C, R, S, Cc, Cs = lpeg.match, lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs +local formatters = string.formatters local pdfreserveobject = pdf.reserveobj local pdfimmediateobject = pdf.immediateobj @@ -38,7 +39,7 @@ backends.pdf = backends.pdf or { lpdf = lpdf or { } local lpdf = lpdf -local function tosixteen(str) -- an lpeg might be faster +local function tosixteen(str) -- an lpeg might be faster (no table) if not str or str == "" then return "<feff>" -- not () as we want an indication that it's unicode else @@ -104,6 +105,12 @@ local function merge_t(a,b) return setmetatable(t,getmetatable(a)) end +local f_key_value = formatters["/%s %s"] +local f_key_dictionary = formatters["/%s << % t >>"] +local f_dictionary = formatters["<< % t >>"] +local f_key_array = formatters["/%s [ % t ]"] +local f_array = formatters["[ % t ]"] + local tostring_a, tostring_d tostring_d = function(t,contentonly,key) @@ -119,28 +126,28 @@ tostring_d = function(t,contentonly,key) rn = rn + 1 local tv = type(v) if tv == "string" then - r[rn] = format("/%s %s",k,toeight(v)) + r[rn] = f_key_value(k,toeight(v)) elseif tv == "unicode" then - r[rn] = format("/%s %s",k,tosixteen(v)) + r[rn] = f_key_value(k,tosixteen(v)) elseif tv == "table" then local mv = getmetatable(v) if mv and mv.__lpdftype then - r[rn] = format("/%s %s",k,tostring(v)) + r[rn] = f_key_value(k,tostring(v)) elseif v[1] then - r[rn] = format("/%s %s",k,tostring_a(v)) + r[rn] = f_key_value(k,tostring_a(v)) else - r[rn] = format("/%s %s",k,tostring_d(v)) + r[rn] = f_key_value(k,tostring_d(v)) end else - r[rn] = format("/%s %s",k,tostring(v)) + r[rn] = f_key_value(k,tostring(v)) end end if contentonly then - return concat(r, " ") + return concat(r," ") elseif key then - return format("/%s << %s >>", key, concat(r, " ")) + return f_key_dictionary(key,r) else - return format("<< %s >>", concat(r, " ")) + return f_dictionary(r) end end end @@ -179,9 +186,9 @@ tostring_a = function(t,contentonly,key) if contentonly then return concat(r, " ") elseif key then - return format("/%s [ %s ]", key, concat(r, " ")) + return f_key_array(key,r) else - return format("[ %s ]", concat(r, " ")) + return f_array(r) end end end diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua index f5f66a487..33269486c 100644 --- a/tex/context/base/lpdf-u3d.lua +++ b/tex/context/base/lpdf-u3d.lua @@ -462,7 +462,7 @@ local function insert3d(spec) -- width, height, factor, display, controls, label }, ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") }, } - local pwd = pdfflushstreamobject(format("q /GS gs %s 0 0 %s 0 0 cm /IM Do Q",factor*width,factor*height),pw) + local pwd = pdfflushstreamobject(format("q /GS gs %f 0 0 %f 0 0 cm /IM Do Q",factor*width,factor*height),pw) annot.AP = pdfdictionary { N = pdfreference(pwd) } diff --git a/tex/context/base/luat-fio.lua b/tex/context/base/luat-fio.lua index 0af9cb6fc..d194928dd 100644 --- a/tex/context/base/luat-fio.lua +++ b/tex/context/base/luat-fio.lua @@ -43,47 +43,46 @@ if not resolvers.instance then register('find_read_file' , function(id,name) return findtexfile(name) end, true) register('open_read_file' , function( name) return opentexfile(name) end, true) - register('find_data_file' , function(name) return findbinfile(name,"tex") end, true) - register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true) - register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true) - register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true) - register('find_image_file' , function(name) return findbinfile(name,"tex") end, true) - register('find_map_file' , function(name) return findbinfile(name,"map") end, true) - register('find_opentype_file' , function(name) return findbinfile(name,"otf") end, true) - register('find_output_file' , function(name) return name end, true) - register('find_pk_file' , function(name) return findbinfile(name,"pk") end, true) - register('find_sfd_file' , function(name) return findbinfile(name,"sfd") end, true) - register('find_truetype_file' , function(name) return findbinfile(name,"ttf") end, true) - register('find_type1_file' , function(name) return findbinfile(name,"pfb") end, true) - register('find_vf_file' , function(name) return findbinfile(name,"vf") end, true) - - register('read_data_file' , function(file) return loadbinfile(file,"tex") end, true) - register('read_enc_file' , function(file) return loadbinfile(file,"enc") end, true) - register('read_font_file' , function(file) return loadbinfile(file,"tfm") end, true) + register('find_data_file' , function(name) return findbinfile(name,"tex") end, true) + register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true) + register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true) + register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true) + register('find_image_file' , function(name) return findbinfile(name,"tex") end, true) + register('find_map_file' , function(name) return findbinfile(name,"map") end, true) + register('find_opentype_file' , function(name) return findbinfile(name,"otf") end, true) + register('find_output_file' , function(name) return name end, true) + register('find_pk_file' , function(name) return findbinfile(name,"pk") end, true) + register('find_sfd_file' , function(name) return findbinfile(name,"sfd") end, true) + register('find_truetype_file' , function(name) return findbinfile(name,"ttf") end, true) + register('find_type1_file' , function(name) return findbinfile(name,"pfb") end, true) + register('find_vf_file' , function(name) return findbinfile(name,"vf") end, true) + register('find_cidmap_file' , function(name) return findbinfile(name,"cidmap") end, true) + + register('read_data_file' , function(file) return loadbinfile(file,"tex") end, true) + register('read_enc_file' , function(file) return loadbinfile(file,"enc") end, true) + register('read_font_file' , function(file) return loadbinfile(file,"tfm") end, true) -- format -- image - register('read_map_file' , function(file) return loadbinfile(file,"map") end, true) + register('read_map_file' , function(file) return loadbinfile(file,"map") end, true) -- output - register('read_pk_file' , function(file) return loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk - register('read_sfd_file' , function(file) return loadbinfile(file,"sfd") end, true) - register('read_vf_file' , function(file) return loadbinfile(file,"vf" ) end, true) + register('read_pk_file' , function(file) return loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk + register('read_sfd_file' , function(file) return loadbinfile(file,"sfd") end, true) + register('read_vf_file' , function(file) return loadbinfile(file,"vf" ) end, true) - register('find_font_file' , function(name) return findbinfile(name,"ofm") end, true) - register('find_vf_file' , function(name) return findbinfile(name,"ovf") end, true) + register('find_font_file' , function(name) return findbinfile(name,"ofm") end, true) + register('find_vf_file' , function(name) return findbinfile(name,"ovf") end, true) - register('read_font_file' , function(file) return loadbinfile(file,"ofm") end, true) - register('read_vf_file' , function(file) return loadbinfile(file,"ovf") end, true) + register('read_font_file' , function(file) return loadbinfile(file,"ofm") end, true) + register('read_vf_file' , function(file) return loadbinfile(file,"ovf") end, true) - -- register('read_opentype_file' , function(file) return loadbinfile(file,"otf") end, true) - -- register('read_truetype_file' , function(file) return loadbinfile(file,"ttf") end, true) - -- register('read_type1_file' , function(file) return loadbinfile(file,"pfb") end, true) + -- register('read_opentype_file' , function(file) return loadbinfile(file,"otf") end, true) + -- register('read_truetype_file' , function(file) return loadbinfile(file,"ttf") end, true) + -- register('read_type1_file' , function(file) return loadbinfile(file,"pfb") end, true) + -- register('read_cidmap_file' , function(file) return loadbinfile(file,"cidmap") end, true) register('find_write_file' , function(id,name) return name end, true) register('find_format_file' , function(name) return name end, true) - register('find_cidmap_file' , function(name) return findbinfile(name,"cidmap") end, true) - -- register('read_cidmap_file' , function(file) return loadbinfile(file,"cidmap") end, true) - end end diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv index 6ca0ac05a..283ed8998 100644 --- a/tex/context/base/luat-lib.mkiv +++ b/tex/context/base/luat-lib.mkiv @@ -13,10 +13,10 @@ \writestatus{loading}{ConTeXt Lua Macros / Libraries} -\registerctxluafile{util-str}{1.001} \registerctxluafile{util-tab}{1.001} -\registerctxluafile{util-pck}{1.001} \registerctxluafile{util-sto}{1.001} % could also be done in trac-deb.mkiv +\registerctxluafile{util-str}{1.001} % uses util-sto +\registerctxluafile{util-pck}{1.001} \registerctxluafile{util-seq}{1.001} %registerctxluafile{util-mrg}{1.001} % not needed in context itself, only mtxrun \registerctxluafile{util-lua}{1.001} diff --git a/tex/context/base/m-chart.mkvi b/tex/context/base/m-chart.mkvi index cb6a1e8c8..2b1a7447c 100644 --- a/tex/context/base/m-chart.mkvi +++ b/tex/context/base/m-chart.mkvi @@ -30,20 +30,6 @@ % todo: figure out a nice way to define the lot: share current and % support current as name (nb: we need to set parent then) -% \def\??flch{@@flch} % chart -% \def\??flln{@@flln} % line -% \def\??flsh{@@flsh} % shape -% \def\??flfc{@@flfc} % focus -% \def\??flst{@@flst} % sets -% \def\??flsp{@@flsp} % split - -% \installsimplecommandhandler \??flch {FLOWchart} \??flch -% \installsimplecommandhandler \??flln {FLOWline} \??flln -% \installsimplecommandhandler \??flsh {FLOWshape} \??flsh -% \installsimplecommandhandler \??flfc {FLOWfocus} \??flfc -% \installsimplecommandhandler \??flst {FLOWsets} \??flst -% \installsimplecommandhandler \??flsp {FLOWsplit} \??flsp - \installcorenamespace {flowchart} % \def\??flch{@@flch} % chart \installcorenamespace {flowline} % \def\??flln{@@flln} % line \installcorenamespace {flowshape} % \def\??flsh{@@flsh} % shape @@ -97,7 +83,7 @@ \c!radius=.375\bodyfontsize, \c!color=FLOWlinecolor, \c!rulethickness=.15\bodyfontsize, - \c!offset=\v!none] + \c!offset=\zeropoint] \setupFLOWshapes [\c!default=action, diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua index 307779b16..7046f5311 100644 --- a/tex/context/base/meta-pdf.lua +++ b/tex/context/base/meta-pdf.lua @@ -13,7 +13,8 @@ if not modules then modules = { } end modules ['meta-pdf'] = { -- We can make it even more efficient if needed, but as we don't use this -- code often in \MKIV\ it makes no sense. -local concat, format, gsub, find, byte, gmatch, match = table.concat, string.format, string.gsub, string.find, string.byte, string.gmatch, string.match +local concat, unpack = table.concat, table.unpack +local format, gsub, find, byte, gmatch, match = string.format, string.gsub, string.find, string.byte, string.gmatch, string.match local lpegmatch = lpeg.match local round = math.round @@ -79,7 +80,7 @@ end local function flushconcat() if m_stack_concat then - mpscode(concat(m_stack_concat," ") .. " cm") + mpscode("%f %f %f %f %f %f cm",unpack(m_stack_concat)) -- no %s due to 1e-035 issues m_stack_concat = nil end end diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua index 21b6657de..4756690be 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -15,6 +15,8 @@ local insert, concat = table.insert, table.concat local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg local lpegmatch = lpeg.match +local formatters = string.formatters + local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context local texbox = tex.box @@ -80,14 +82,21 @@ function metapost.setoutercolor(mode,colormodel,colorattribute,transparencyattri innertransparency = outertransparency -- not yet used end -local function checked_color_pair(color) +local f_gray = formatters["%.3f g %.3f G"] +local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"] +local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"] +local f_cm = formatters["q %f %f %f %f %f %f cm"] +local f_shade = formatters["MpSh%s"] + +local function checked_color_pair(color,...) if not color then return innercolor, outercolor - elseif outercolormode == 3 then - innercolor = color + end + if outercolormode == 3 then + innercolor = color(...) return innercolor, innercolor else - return color, outercolor + return color(...), outercolor end end @@ -142,7 +151,7 @@ local commasplitter = lpeg.tsplitat(",") local function checkandconvertspot(n_a,f_a,c_a,v_a,n_b,f_b,c_b,v_b) -- must be the same but we don't check - local name = format("MpSh%s",nofshades) + local name = f_shade(nofshades) local ca = lpegmatch(commasplitter,v_a) local cb = lpegmatch(commasplitter,v_b) if #ca == 0 or #cb == 0 then @@ -156,7 +165,7 @@ local function checkandconvertspot(n_a,f_a,c_a,v_a,n_b,f_b,c_b,v_b) end local function checkandconvert(ca,cb) - local name = format("MpSh%s",nofshades) + local name = f_shade(nofshades) if not ca or not cb or type(ca) == "string" then return { 0 }, { 1 }, "DeviceGray", name else @@ -257,32 +266,32 @@ function models.all(cr) elseif metapost.reducetogray then if n == 1 then local s = cr[1] - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) elseif n == 3 then local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then - return checked_color_pair(format("%.3f g %.3f G",r,r)) + return checked_color_pair(f_gray,r,r) else - return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + return checked_color_pair(f_rgb,r,g,b,r,g,b) end else local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then k = 1 - k - return checked_color_pair(format("%.3f g %.3f G",k,k)) + return checked_color_pair(f_gray,k,k) else - return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end elseif n == 1 then local s = cr[1] - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) elseif n == 3 then local r, g, b = cr[1], cr[2], cr[3] - return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + return checked_color_pair(f_rgb,r,g,b,r,g,b) else local c, m, y, k = cr[1], cr[2], cr[3], cr[4] - return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end @@ -293,27 +302,27 @@ function models.rgb(cr) elseif metapost.reducetogray then if n == 1 then local s = cr[1] - checked_color_pair(format("%.3f g %.3f G",s,s)) + checked_color_pair(f_gray,s,s) elseif n == 3 then local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then - return checked_color_pair(format("%.3f g %.3f G",r,r)) + return checked_color_pair(f_gray,r,r) else - return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + return checked_color_pair(f_rgb,r,g,b,r,g,b) end else local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then k = 1 - k - return checked_color_pair(format("%.3f g %.3f G",k,k)) + return checked_color_pair(f_gray,k,k) else local r, g, b = cmyktorgb(c,m,y,k) - return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + return checked_color_pair(f_rgb,r,g,b,r,g,b) end end elseif n == 1 then local s = cr[1] - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) else local r, g, b if n == 3 then @@ -321,7 +330,7 @@ function models.rgb(cr) else r, g, b = cr[1], cr[2], cr[3] end - return checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + return checked_color_pair(f_rgb,r,g,b,r,g,b) end end @@ -332,27 +341,27 @@ function models.cmyk(cr) elseif metapost.reducetogray then if n == 1 then local s = cr[1] - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) elseif n == 3 then local r, g, b = cr[1], cr[2], cr[3] if r == g and g == b then - return checked_color_pair(format("%.3f g %.3f G",r,r)) + return checked_color_pair(f_gray,r,r) else local c, m, y, k = rgbtocmyk(r,g,b) - return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end else local c, m, y, k = cr[1], cr[2], cr[3], cr[4] if c == m and m == y and y == 0 then - k = 1 - k - return checked_color_pair(format("%.3f g %.3f G",k,k)) + k = k - 1 + return checked_color_pair(f_gray,k,k) else - return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end elseif n == 1 then local s = cr[1] - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) else local c, m, y, k if n == 3 then @@ -360,7 +369,7 @@ function models.cmyk(cr) else c, m, y, k = cr[1], cr[2], cr[3], cr[4] end - return checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end @@ -375,7 +384,7 @@ function models.gray(cr) else s = cr[1] end - return checked_color_pair(format("%.3f g %.3f G",s,s)) + return checked_color_pair(f_gray,s,s) end setmetatableindex(models, function(t,k) @@ -461,12 +470,13 @@ local function sxsy(wd,ht,dp) -- helper for text return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0 end -local no_trial_run = "mfun_trial_run := false ;" -local do_trial_run = "mfun_trial_run := true ;" -local text_data_template = "mfun_tt_w[%i] := %f ; mfun_tt_h[%i] := %f ; mfun_tt_d[%i] := %f ;" -local do_begin_fig = "; beginfig(1) ; " -local do_end_fig = "; endfig ;" -local do_safeguard = ";" +local no_trial_run = "mfun_trial_run := false ;" +local do_trial_run = "mfun_trial_run := true ;" +local do_begin_fig = "; beginfig(1) ; " +local do_end_fig = "; endfig ;" +local do_safeguard = ";" + +local f_text_data = formatters["mfun_tt_w[%i] := %f ; mfun_tt_h[%i] := %f ; mfun_tt_d[%i] := %f ;"] function metapost.textextsdata() local t, nt, n = { }, 0, 0 @@ -477,7 +487,7 @@ function metapost.textextsdata() report_textexts("passed data %s: (%0.4f,%0.4f,%0.4f)",n,wd,ht,dp) end nt = nt + 1 - t[nt] = format(text_data_template,n,wd,n,ht,n,dp) + t[nt] = f_text_data(n,wd,n,ht,n,dp) else break end @@ -827,14 +837,21 @@ local function tx_process(object,prescript,before,after) if trace_textexts then report_textexts("processing %s (second pass)",tx_number) end - -- before[#before+1] = format("q %f %f %f %f %f %f cm",cm(object)) + -- before[#before+1] = f_cm(cm(object)) local sx,rx,ry,sy,tx,ty = cm(object) before[#before+1] = function() -- flush always happens, we can have a special flush function injected before local box = textexts[tx_number] if box then -- context.MPLIBgettextscaled(tx_number,sxsy(box.width,box.height,box.depth)) - context.MPLIBgettextscaledcm(tx_number,sx,rx,ry,sy,tx,ty,sxsy(box.width,box.height,box.depth)) + context.MPLIBgettextscaledcm(tx_number, + format("%f",sx), -- bah ... %s no longer checks + format("%f",rx), -- bah ... %s no longer checks + format("%f",ry), -- bah ... %s no longer checks + format("%f",sy), -- bah ... %s no longer checks + format("%f",tx), -- bah ... %s no longer checks + format("%f",ty), -- bah ... %s no longer checks + sxsy(box.width,box.height,box.depth)) else report_textexts("unknown %s",tx_number) end @@ -952,7 +969,7 @@ end local function bm_process(object,prescript,before,after) local bm_xresolution = prescript.bm_xresolution if bm_xresolution then - before[#before+1] = format("q %f %f %f %f %f %f cm",cm(object)) + before[#before+1] = f_cm(cm(object)) before[#before+1] = function() figures.bitmapimage { xresolution = tonumber(bm_xresolution), @@ -992,7 +1009,7 @@ end local function fg_process(object,prescript,before,after) local fg_name = prescript.fg_name if fg_name then - before[#before+1] = format("q %f %f %f %f %f %f cm",cm(object)) -- beware: does not use the cm stack + before[#before+1] = f_cm(cm(object)) -- beware: does not use the cm stack before[#before+1] = function() context.MPLIBfigure(fg_name,prescript.fg_mask or "") end @@ -1062,16 +1079,16 @@ local function tr_process(object,prescript,before,after) local f = cs[1] if colorspace == 2 then local s = f*v[2] - c_b, c_a = checked_color_pair(format("%.3f g %.3f G",s,s)) + c_b, c_a = checked_color_pair(f_gray,s,s) elseif colorspace == 3 then local r, g, b = f*v[3], f*v[4], f*v[5] - c_b, c_a = checked_color_pair(format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b)) + c_b, c_a = checked_color_pair(f_rgb,r,g,b,r,g,b) elseif colorspace == 4 or colorspace == 1 then local c, m, y, k = f*v[6], f*v[7], f*v[8], f*v[9] - c_b, c_a = checked_color_pair(format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k)) + c_b, c_a = checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) else local s = f*v[2] - c_b, c_a = checked_color_pair(format("%.3f g %.3f G",s,s)) + c_b, c_a = checked_color_pair(f_gray,s,s) end end -- diff --git a/tex/context/base/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv index 704c9e635..3ecabc1c3 100644 --- a/tex/context/base/mlib-pps.mkiv +++ b/tex/context/base/mlib-pps.mkiv @@ -60,7 +60,7 @@ \def\MPLIBgettextscaledcm#1#2#3#4#5#6#7#8#9% 2-7: sx,rx,ry,sy,tx,ty {\ctxlua{metapost.gettext(\number\MPtextbox,#1)}% \setbox\MPbox\hbox\bgroup - \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop + \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop ... will be changed to proper lua call (avoid small numbers) \vbox to \zeropoint\bgroup \vss \hbox to \zeropoint \bgroup diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex index 019a7b2fb..68cdea6f0 100644 --- a/tex/context/base/s-abr-01.tex +++ b/tex/context/base/s-abr-01.tex @@ -136,6 +136,7 @@ \logo [JAVASCRIPT] {Java\-Script} \logo [JPEG] {jpeg} \logo [JPG] {jpg} +\logo [JBIG] {jbig} \logo [KPATHSEA] {kpathsea} \logo [KPSE] {kpse} \logo [KPSEWHICH] {kpsewhich} diff --git a/tex/context/base/s-abr-04.tex b/tex/context/base/s-abr-04.tex index bcc2c8265..0725bcdcf 100644 --- a/tex/context/base/s-abr-04.tex +++ b/tex/context/base/s-abr-04.tex @@ -123,6 +123,7 @@ \logo [JAVASCRIPT] {Java\-Script} \logo [JPEG] {jpeg} \logo [JPG] {jpg} +\logo [JBIG] {jbig} \logo [KPATHSEA] {kpathsea} \logo [KPSE] {kpse} \logo [KPSEWHICH] {kpsewhich} diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 43c9014a6..95940634b 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex 588c718a3..3563789f6 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index 13ea04489..115b58063 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -249,7 +249,7 @@ local function filtercollected(names, criterium, number, collected, forced, nest if block == "" then block = false end ---~ print(">>",block,criterium) +-- print(">>",block,criterium) -- forced = forced or { } -- todo: also on other branched, for the moment only needed for bookmarks if type(names) == "string" then @@ -274,7 +274,7 @@ local function filtercollected(names, criterium, number, collected, forced, nest for i=1,#collected do local v = collected[i] local r = v.references - if r then + if r and (not block or not r.block or block == r.block) then local metadata = v.metadata if metadata then local name = metadata.name or false diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index 6c8213099..40d2860be 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -19,6 +19,7 @@ local texcount = tex and tex.count local next, type, select = next, type, select local setmetatableindex = table.setmetatableindex +local formatters = string.formatters --[[ldx-- <p>This is a prelude to a more extensive logging module. We no longer @@ -65,61 +66,76 @@ if tex and (tex.jobname or tex.formatname) then write_nl(target,"\n") end + local f_one = formatters["%-15s > %s\n"] + local f_two = formatters["%-15s >\n"] + report = function(a,b,c,...) if c then - write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s >\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s"] + local f_two = formatters["%-15s >"] + direct = function(a,b,c,...) if c then - return format("%-15s > %s",translations[a],format(formats[b],c,...)) + return f_one(translations[a],format(formats[b],c,...)) elseif b then - return format("%-15s > %s",translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return format("%-15s >", translations[a]) + return f_two(translations[a]) else return "" end end + local f_one = formatters["%-15s > %s > %s\n"] + local f_two = formatters["%-15s > %s >\n"] + subreport = function(a,s,b,c,...) if c then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],translations[s],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s > %s > %s\n",translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,format("%-15s > %s >\n", translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end + local f_one = formatters["%-15s > %s > %s"] + local f_two = formatters["%-15s > %s >"] + subdirect = function(a,s,b,c,...) if c then - return format("%-15s > %s > %s",translations[a],translations[s],format(formats[b],c,...)) + return f_one(translations[a],translations[s],format(formats[b],c,...)) elseif b then - return format("%-15s > %s > %s",translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return format("%-15s > %s >", translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) if c then - write_nl(target,format("%-15s : %s\n",translations[a],format(formats[b],c,...))) + write_nl(target,f_one(translations[a],format(formats[b],c,...))) elseif b then - write_nl(target,format("%-15s : %s\n",translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,format("%-15s :\n", translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -174,37 +190,46 @@ else write_nl("\n") end + local f_one = formatters["%-15s | %s"] + local f_two = formatters["%-15s |"] + report = function(a,b,c,...) if c then - write_nl(format("%-15s | %s",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s",a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(format("%-15s |", a)) + write_nl(f_two(a)) else write_nl("") end end + local f_one = formatters["%-15s | %s | %s"] + local f_two = formatters["%-15s | %s |"] + subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s | %s | %s",a,sub,format(b,c,...))) + write_nl(f_one(a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s | %s | %s",a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(format("%-15s | %s |", a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end + local f_one = formatters["%-15s : %s\n"] + local f_two = formatters["%-15s :\n"] + status = function(a,b,c,...) -- not to be used in lua anyway if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) + write_nl(f_one(a,format(b,c,...))) elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + write_nl(f_one(a,b)) -- b can have %'s elseif a then - write_nl(format("%-15s :\n", a)) + write_nl(f_two(a)) else write_nl("\n") end diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index 9252ef874..db8508a4a 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -36,11 +36,11 @@ if not modules then modules = { } end modules ['typo-mar'] = { -- if not w then -- -- error -- elseif how == "horizontal" or how == "h" then --- pdfprint("page",format(" q 1 0 0 1 %s 0 cm ", (w[1] - pdf.h) * factor)) +-- pdfprint("page",format(" q 1 0 0 1 %f 0 cm ", (w[1] - pdf.h) * factor)) -- elseif how == "vertical" or how == "v" then --- pdfprint("page",format(" q 1 0 0 1 0 %s cm ", (w[2] - pdf.v) * factor)) +-- pdfprint("page",format(" q 1 0 0 1 0 %f cm ", (w[2] - pdf.v) * factor)) -- else --- pdfprint("page",format(" q 1 0 0 1 %s %s cm ", (w[1] - pdf.h) * factor, (w[2] - pdf.v) * factor)) +-- pdfprint("page",format(" q 1 0 0 1 %f %f cm ", (w[1] - pdf.h) * factor, (w[2] - pdf.v) * factor)) -- end -- end -- diff --git a/tex/context/base/util-str.lua b/tex/context/base/util-str.lua index 377dd163f..bade3493a 100644 --- a/tex/context/base/util-str.lua +++ b/tex/context/base/util-str.lua @@ -10,9 +10,27 @@ utilities = utilities or {} utilities.strings = utilities.strings or { } local strings = utilities.strings -local gsub, rep = string.gsub, string.rep -local Cs, C, Cp, P, Carg = lpeg.Cs, lpeg.C, lpeg.Cp, lpeg.P, lpeg.Carg +local load = load +local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub +local concat = table.concat +local P, V, C, S, R, Ct, Cs, Cp, Carg = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg local patterns, lpegmatch = lpeg.patterns, lpeg.match +local utfchar, utfbyte = utf.char, utf.byte +local setmetatableindex = table.setmetatableindex +-- + +local stripper = patterns.stripzeros + +local function points(n) + return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +end + +local function basepoints(n) + return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) +end + +number.points = points +number.basepoints = basepoints -- str = " \n \ntest \n test\ntest " -- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]") @@ -47,17 +65,15 @@ function strings.newrepeater(str,offset) return t end t = { } - setmetatable(t, { - __index = function(t,k) - if not k then - return "" - end - local n = k + offset - local s = n > 0 and rep(str,n) or "" - t[k] = s - return s + setmetatableindex(t, function(t,k) + if not k then + return "" end - } ) + local n = k + offset + local s = n > 0 and rep(str,n) or "" + t[k] = s + return s + end) s[offset] = t return t end @@ -94,20 +110,20 @@ function strings.tabtospace(str,tab) return lpegmatch(pattern,str,1,tab or 7) end ---~ local t = { ---~ "1234567123456712345671234567", ---~ "\tb\tc", ---~ "a\tb\tc", ---~ "aa\tbb\tcc", ---~ "aaa\tbbb\tccc", ---~ "aaaa\tbbbb\tcccc", ---~ "aaaaa\tbbbbb\tccccc", ---~ "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc", ---~ "one\n two\nxxx three\nxx four\nx five\nsix", ---~ } ---~ for k=1,#t do ---~ print(strings.tabtospace(t[k])) ---~ end +-- local t = { +-- "1234567123456712345671234567", +-- "\tb\tc", +-- "a\tb\tc", +-- "aa\tbb\tcc", +-- "aaa\tbbb\tccc", +-- "aaaa\tbbbb\tcccc", +-- "aaaaa\tbbbbb\tccccc", +-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc", +-- "one\n two\nxxx three\nxx four\nx five\nsix", +-- } +-- for k=1,#t do +-- print(strings.tabtospace(t[k])) +-- end function strings.striplong(str) -- strips all leading spaces str = gsub(str,"^%s*","") @@ -115,13 +131,288 @@ function strings.striplong(str) -- strips all leading spaces return str end ---~ local template = string.striplong([[ ---~ aaaa ---~ bb ---~ cccccc ---~ ]]) +-- local template = string.striplong([[ +-- aaaa +-- bb +-- cccccc +-- ]]) function strings.nice(str) str = gsub(str,"[:%-+_]+"," ") -- maybe more return str end + +-- Work in progress. Interesting is that compared to the built-in this +-- is faster in luatex than in luajittex where we have a comparable speed. + +local n = 0 + +-- we are somewhat sloppy in parsing prefixes as it's not that critical +-- +-- this does not work out ok: +-- +-- function fnc(...) -- 1,2,3 +-- print(...,...,...) -- 1,1,1,2,3 +-- end + +local prefix_any = C((S("+- .") + R("09"))^0) +local prefix_tab = C((1-R("az","AZ","09","%%"))^0) + +-- we've split all cases as then we can optimize them (let's omit the fuzzy u) + +local format_s = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%ss',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_q = function() + n = n + 1 + return format("format('%%q',(select(%s,...)))",n) -- maybe an own lpeg +end + +local format_i = function(f) + n = n + 1 + if f and f ~= "" then + return format("format('%%%si',(select(%s,...)))",f,n) + else + return format("(select(%s,...))",n) + end +end + +local format_d = format_i + +local format_f = function(f) + n = n + 1 + return format("format('%%%sf',(select(%s,...)))",f,n) +end + +local format_g = function(f) + n = n + 1 + return format("format('%%%sg',(select(%s,...)))",f,n) +end + +local format_G = function(f) + n = n + 1 + return format("format('%%%sG',(select(%s,...)))",f,n) +end + +local format_e = function(f) + n = n + 1 + return format("format('%%%se',(select(%s,...)))",f,n) +end + +local format_E = function(f) + n = n + 1 + return format("format('%%%sE',(select(%s,...)))",f,n) +end + +local format_x = function(f) + n = n + 1 + return format("format('%%%sx',(select(%s,...)))",f,n) +end + +local format_X = function(f) + n = n + 1 + return format("format('%%%sX',(select(%s,...)))",f,n) +end + +local format_o = function(f) + n = n + 1 + return format("format('%%%so',(select(%s,...)))",f,n) +end + +local format_c = function() + n = n + 1 + return format("utfchar((select(%s,...)))",n) +end + +local format_r = function(f) + n = n + 1 + return format("format('%%%s.0f',(select(%s,...)))",f,n) +end + +local format_v = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_V = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('0x%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_u = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('u+%%%sx',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_U = function(f) + n = n + 1 + if f == "-" then + f = sub(f,2) + return format("format('%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + else + return format("format('U+%%%sX',utfbyte((select(%s,...))))",f == "" and "05" or f,n) + end +end + +local format_p = function() + n = n + 1 + return format("points((select(%s,...)))",n) +end + +local format_b = function() + n = n + 1 + return format("basepoints((select(%s,...)))",n) +end + +local format_t = function(f) + n = n + 1 + if f and f ~= "" then + return format("concat((select(%s,...)),%q)",n,f) + else + return format("concat((select(%s,...)))",n) + end +end + +local format_l = function() + n = n + 1 + return format("(select(%s,...) and 'true' or 'false')",n) +end + +local format_a = function(s) + return format("%q",s) +end + +local builder = Ct { "start", + start = (P("%") * ( + V("s") + V("q") + + V("i") + V("d") + + V("f") + V("g") + V("G") + V("e") + V("E") + + V("x") + V("X") + V("o") + -- + + V("c") + -- + + V("r") + + V("v") + V("V") + V("u") + V("U") + + V("p") + V("b") + + V("t") + + V("l") + ) + + V("a") + )^0, + -- + ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string) + ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string) + ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer) + ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer) + ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float) + ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float) + ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float) + ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float) + ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float) + ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal) + ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL) + ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal) + -- + ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) + -- + ["r"] = (prefix_any * P("r")) / format_r, -- %r => round + ["v"] = (prefix_any * P("v")) / format_v, -- %v => 0x0a1b2 (when - no 0x) + ["V"] = (prefix_any * P("V")) / format_V, -- %V => 0x0A1B2 (when - no 0x) + ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+) + ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+) + ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units) + ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units) + ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat + ["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean + -- + ["a"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_a, -- %a => text (including %%) +} + +-- we can be clever and only alias what is needed + +local template = [[ +local format = string.format +local concat = table.concat +local points = number.points +local basepoints = number.basepoints +local utfchar = utf.char +local utfbyte = utf.byte +return function(...) + return %s +end +]] + +local function make(t,str) + n = 0 + local p = lpegmatch(builder,str) +-- inspect(p) + local c = format(template,concat(p,"..")) +-- inspect(c) + formatter = load(c)() + t[str] = formatter + return formatter +end + +local formatters = string.formatters or { } +string.formatters = formatters + +setmetatableindex(formatters,make) + +function string.makeformatter(str) + return formatters[str] +end + +function string.formatter(str,...) + return formatters[str](...) +end + +-- local p1 = "%s test %f done %p and %c and %V or %+t or %%" +-- local p2 = "%s test %f done %s and %s and 0x%05X or %s or %%" +-- +-- local t = { 1,2,3,4 } +-- local r = "" +-- +-- local format, formatter, formatters = string.format, string.formatter, string.formatters +-- local utfchar, utfbyte, concat, points = utf.char, utf.byte, table.concat, number.points +-- +-- local c = os.clock() +-- local f = formatters[p1] +-- for i=1,500000 do +-- -- r = formatters[p1]("hans",123.45,123.45,123,"a",t) +-- r = formatter(p1,"hans",123.45,123.45,123,"a",t) +-- -- r = f("hans",123.45,123.45,123,"a",t) +-- end +-- print(os.clock()-c,r) +-- +-- local c = os.clock() +-- for i=1,500000 do +-- r = format(p2,"hans",123.45,points(123.45),utfchar(123),utfbyte("a"),concat(t,"+")) +-- end +-- print(os.clock()-c,r) + +-- local f = format +-- function string.format(fmt,...) +-- print(fmt,...) +-- return f(fmt,...) +-- end diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index e3d6a9f7d..47e533fa4 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -236,6 +236,58 @@ local function fastserialize(t,r,outer) -- no mixes return r end +-- local f_hashed_string = formatters["[%q]=%q,"] +-- local f_hashed_number = formatters["[%q]=%s,"] +-- local f_hashed_table = formatters["[%q]="] +-- local f_hashed_true = formatters["[%q]=true,"] +-- local f_hashed_false = formatters["[%q]=false,"] +-- +-- local f_indexed_string = formatters["%q,"] +-- local f_indexed_number = formatters["%s,"] +-- ----- f_indexed_true = formatters["true,"] +-- ----- f_indexed_false = formatters["false,"] +-- +-- local function fastserialize(t,r,outer) -- no mixes +-- r[#r+1] = "{" +-- local n = #t +-- if n > 0 then +-- for i=1,n do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_indexed_string(v) +-- elseif tv == "number" then +-- r[#r+1] = f_indexed_number(v) +-- elseif tv == "table" then +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k) +-- r[#r+1] = v and "true," or "false," +-- end +-- end +-- else +-- for k, v in next, t do +-- local tv = type(v) +-- if tv == "string" then +-- r[#r+1] = f_hashed_string(k,v) +-- elseif tv == "number" then +-- r[#r+1] = f_hashed_number(k,v) +-- elseif tv == "table" then +-- r[#r+1] = f_hashed_table(k) +-- fastserialize(v,r) +-- elseif tv == "boolean" then +-- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k) +-- end +-- end +-- end +-- if outer then +-- r[#r+1] = "}" +-- else +-- r[#r+1] = "}," +-- end +-- return r +-- end + function table.fastserialize(t,prefix) -- so prefix should contain the = return concat(fastserialize(t,{ prefix or "return" },true)) end diff --git a/tex/context/base/x-calcmath.lua b/tex/context/base/x-calcmath.lua index 707abe82a..e8656c78e 100644 --- a/tex/context/base/x-calcmath.lua +++ b/tex/context/base/x-calcmath.lua @@ -156,8 +156,8 @@ local function totex(str,mode) end -- parenthesis (optional) if mode == 2 then - str = gsub(str,"%(", "\\left\(") - str = gsub(str,"%)", "\\right\)") + str = gsub(str,"%(", "\\left(") + str = gsub(str,"%)", "\\right)") end -- csnames str = gsub(str,"(\\[A-Z]+)", lower) diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua index f35251d37..9565057d0 100644 --- a/tex/context/base/x-mathml.lua +++ b/tex/context/base/x-mathml.lua @@ -13,7 +13,7 @@ local format, lower, find, gsub = string.format, string.lower, string.find, stri local strip = string.strip local xmlsprint, xmlcprint, xmltext, xmlcontent = xml.sprint, xml.cprint, xml.text, xml.content local getid = lxml.getid -local utfchar. utfcharacters, utfvalues = utf.char, utf.characters, utf.values +local utfchar, utfcharacters, utfvalues = utf.char, utf.characters, utf.values local lpegmatch = lpeg.match local mathml = { } diff --git a/tex/generic/context/luatex/luatex-basics-gen.lua b/tex/generic/context/luatex/luatex-basics-gen.lua index 2f03efba8..e7e98154a 100644 --- a/tex/generic/context/luatex/luatex-basics-gen.lua +++ b/tex/generic/context/luatex/luatex-basics-gen.lua @@ -74,32 +74,42 @@ texconfig.kpse_init = true resolvers = resolvers or { } -- no fancy file helpers used local remapper = { - otf = "opentype fonts", - ttf = "truetype fonts", - ttc = "truetype fonts", - dfont = "truetype fonts", -- "truetype dictionary", - cid = "cid maps", - fea = "font feature files", - pfa = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! - pfb = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + dfont = "truetype fonts", -- "truetype dictionary", + cid = "cid maps", + cidmap = "cid maps", + fea = "font feature files", + pfa = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! + pfb = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! } function resolvers.findfile(name,fileformat) - name = string.gsub(name,"\\","\/") - fileformat = fileformat and string.lower(fileformat) - local found = kpse.find_file(name,(fileformat and fileformat ~= "" and (remapper[fileformat] or fileformat)) or file.suffix(name,"tex")) + name = string.gsub(name,"\\","/") + if not fileformat or fileformat == "" then + fileformat = file.suffix(name) + if fileformat == "" then + fileformat = "tex" + end + end + fileformat = string.lower(fileformat) + fileformat = remapper[fileformat] or fileformat + local found = kpse.find_file(name,fileformat) if not found or found == "" then found = kpse.find_file(name,"other text files") end return found end -function resolvers.findbinfile(name,fileformat) - if not fileformat or fileformat == "" then - fileformat = file.suffix(name) -- string.match(name,"%.([^%.]-)$") - end - return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat) -end +-- function resolvers.findbinfile(name,fileformat) +-- if not fileformat or fileformat == "" then +-- fileformat = file.suffix(name) +-- end +-- return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat) +-- end + +resolvers.findbinfile = resolvers.findfile function resolvers.resolve(s) return s diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index f302df378..66560b702 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 12/25/12 15:14:15 +-- merge date : 12/28/12 20:30:09 do -- begin closure to overcome local limits and interference @@ -2701,7 +2701,7 @@ io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty local f = io.open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') +-- local data = f:read('*all') local data = readall(f) f:close() if #data > 0 then @@ -2730,29 +2730,29 @@ end function io.loadlines(filename,n) -- return nil if empty local f = io.open(filename,'r') - if f then - if n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break - end - end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - assert(f:close()) - if #line > 0 then - return line + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[#lines+1] = line + else + break end end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end @@ -2772,7 +2772,7 @@ function io.exists(filename) if f == nil then return false else - assert(f:close()) + f:close() return true end end @@ -2783,7 +2783,7 @@ function io.size(filename) return 0 else local s = f:seek("end") - assert(f:close()) + f:close() return s end end @@ -2791,9 +2791,13 @@ end function io.noflines(f) if type(f) == "string" then local f = io.open(filename) - local n = f and io.noflines(f) or 0 - assert(f:close()) - return n + if f then + local n = f and io.noflines(f) or 0 + f:close() + return n + else + return 0 + end else local n = 0 for _ in f:lines() do @@ -3077,32 +3081,42 @@ texconfig.kpse_init = true resolvers = resolvers or { } -- no fancy file helpers used local remapper = { - otf = "opentype fonts", - ttf = "truetype fonts", - ttc = "truetype fonts", - dfont = "truetype fonts", -- "truetype dictionary", - cid = "cid maps", - fea = "font feature files", - pfa = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! - pfb = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! + otf = "opentype fonts", + ttf = "truetype fonts", + ttc = "truetype fonts", + dfont = "truetype fonts", -- "truetype dictionary", + cid = "cid maps", + cidmap = "cid maps", + fea = "font feature files", + pfa = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! + pfb = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! } function resolvers.findfile(name,fileformat) - name = string.gsub(name,"\\","\/") - fileformat = fileformat and string.lower(fileformat) - local found = kpse.find_file(name,(fileformat and fileformat ~= "" and (remapper[fileformat] or fileformat)) or file.suffix(name,"tex")) + name = string.gsub(name,"\\","/") + if not fileformat or fileformat == "" then + fileformat = file.suffix(name) + if fileformat == "" then + fileformat = "tex" + end + end + fileformat = string.lower(fileformat) + fileformat = remapper[fileformat] or fileformat + local found = kpse.find_file(name,fileformat) if not found or found == "" then found = kpse.find_file(name,"other text files") end return found end -function resolvers.findbinfile(name,fileformat) - if not fileformat or fileformat == "" then - fileformat = file.suffix(name) -- string.match(name,"%.([^%.]-)$") - end - return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat) -end +-- function resolvers.findbinfile(name,fileformat) +-- if not fileformat or fileformat == "" then +-- fileformat = file.suffix(name) +-- end +-- return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat) +-- end + +resolvers.findbinfile = resolvers.findfile function resolvers.resolve(s) return s |