diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | lualibs-dir.lua | 66 | ||||
-rw-r--r-- | lualibs-io.lua | 2 | ||||
-rw-r--r-- | lualibs-lpeg.lua | 4 | ||||
-rw-r--r-- | lualibs-lua.lua | 17 | ||||
-rw-r--r-- | lualibs-os.lua | 20 | ||||
-rw-r--r-- | lualibs-string.lua | 5 | ||||
-rw-r--r-- | lualibs-table.lua | 38 | ||||
-rw-r--r-- | lualibs-trac-inf.lua | 26 | ||||
-rw-r--r-- | lualibs-unicode.lua | 9 | ||||
-rw-r--r-- | lualibs-util-deb.lua | 46 | ||||
-rw-r--r-- | lualibs-util-env.lua | 290 | ||||
-rw-r--r-- | lualibs-util-prs.lua | 4 | ||||
-rw-r--r-- | lualibs-util-str.lua | 287 | ||||
-rw-r--r-- | lualibs-util-tab.lua | 28 | ||||
-rw-r--r-- | lualibs.dtx | 43 | ||||
-rw-r--r-- | test-lualibs.lua | 2 |
18 files changed, 406 insertions, 486 deletions
@@ -1,4 +1,8 @@ History of the lualibs package +2014/05/05 v2.1b/ + * sync with Context beta as of 2014-04-05 + * remove util-env.lua + 2013/31/03 v2.1a/ * sync with Context beta as of 2013-12-30 @@ -59,7 +59,6 @@ Source files: lualibs-url.lua tex/luatex/lualibs/lualibs-url.lua lualibs-util-deb.lua tex/luatex/lualibs/lualibs-util-deb.lua lualibs-util-dim.lua tex/luatex/lualibs/lualibs-util-dim.lua - lualibs-util-env.lua tex/luatex/lualibs/lualibs-util-env.lua lualibs-util-jsn.lua tex/luatex/lualibs/lualibs-util-jsn.lua lualibs-util-lua.lua tex/luatex/lualibs/lualibs-util-lua.lua lualibs-util-prs.lua tex/luatex/lualibs/lualibs-util-prs.lua diff --git a/lualibs-dir.lua b/lualibs-dir.lua index 40081cc..2572120 100644 --- a/lualibs-dir.lua +++ b/lualibs-dir.lua @@ -25,8 +25,9 @@ local isdir = lfs.isdir local isfile = lfs.isfile local currentdir = lfs.currentdir local chdir = lfs.chdir +local mkdir = lfs.mkdir -local onwindows = os.type == "windows" or find(os.getenv("PATH"),";") +local onwindows = os.type == "windows" or find(os.getenv("PATH"),";",1,true) -- in case we load outside luatex @@ -188,7 +189,7 @@ local function glob(str,t) local split = lpegmatch(pattern,str) -- we could use the file splitter if split then local root, path, base = split[1], split[2], split[3] - local recurse = find(base,"%*%*") + local recurse = find(base,"**",1,true) -- find(base,"%*%*") local start = root .. path local result = lpegmatch(filter,start .. base) globpattern(start,result,recurse,t) @@ -214,7 +215,7 @@ local function glob(str,t) local t = t or { } local action = action or function(name) t[#t+1] = name end local root, path, base = split[1], split[2], split[3] - local recurse = find(base,"%*%*") + local recurse = find(base,"**",1,true) -- find(base,"%*%*") local start = root .. path local result = lpegmatch(filter,start .. base) globpattern(start,result,recurse,action) @@ -284,17 +285,27 @@ local make_indeed = true -- false if onwindows then function dir.mkdirs(...) - local str, pth = "", "" - for i=1,select("#",...) do - local s = select(i,...) - if s == "" then - -- skip - elseif str == "" then - str = s - else - str = str .. "/" .. s + local n = select("#",...) + local str + if n == 1 then + str = select(1,...) + if isdir(str) then + return str, true + end + else + str = "" + for i=1,n do + local s = select(i,...) + if s == "" then + -- skip + elseif str == "" then + str = s + else + str = str .. "/" .. s + end end end + local pth = "" local drive = false local first, middle, last = match(str,"^(//)(//*)(.*)$") if first then @@ -330,7 +341,7 @@ if onwindows then pth = pth .. "/" .. s end if make_indeed and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end return pth, (isdir(pth) == true) @@ -351,14 +362,23 @@ if onwindows then else function dir.mkdirs(...) - local str, pth = "", "" - for i=1,select("#",...) do - local s = select(i,...) - if s and s ~= "" then -- we catch nil and false - if str ~= "" then - str = str .. "/" .. s - else - str = s + local n = select("#",...) + local str, pth + if n == 1 then + str = select(1,...) + if isdir(str) then + return str, true + end + else + str = "" + for i=1,n do + local s = select(i,...) + if s and s ~= "" then -- we catch nil and false + if str ~= "" then + str = str .. "/" .. s + else + str = s + end end end end @@ -373,7 +393,7 @@ else pth = pth .. "/" .. s end if make_indeed and not first and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end else @@ -381,7 +401,7 @@ else for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s if make_indeed and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end end diff --git a/lualibs-io.lua b/lualibs-io.lua index 52f166a..020e811 100644 --- a/lualibs-io.lua +++ b/lualibs-io.lua @@ -12,7 +12,7 @@ local concat = table.concat local floor = math.floor local type = type -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";",1,true) then io.fileseparator, io.pathseparator = "\\", ";" else io.fileseparator, io.pathseparator = "/" , ":" diff --git a/lualibs-lpeg.lua b/lualibs-lpeg.lua index 6d3acd7..6feb708 100644 --- a/lualibs-lpeg.lua +++ b/lualibs-lpeg.lua @@ -176,12 +176,14 @@ patterns.whitespace = whitespace patterns.nonspacer = nonspacer patterns.nonwhitespace = nonwhitespace -local stripper = spacer^0 * C((spacer^0 * nonspacer^1)^0) -- from example by roberto +local stripper = spacer ^0 * C((spacer ^0 * nonspacer ^1)^0) -- from example by roberto +local fullstripper = whitespace^0 * C((whitespace^0 * nonwhitespace^1)^0) ----- collapser = Cs(spacer^0/"" * ((spacer^1 * endofstring / "") + (spacer^1/" ") + P(1))^0) local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspacer^1)^0)) patterns.stripper = stripper +patterns.fullstripper = fullstripper patterns.collapser = collapser patterns.lowercase = lowercase diff --git a/lualibs-lua.lua b/lualibs-lua.lua index fc05afa..9565f48 100644 --- a/lualibs-lua.lua +++ b/lualibs-lua.lua @@ -6,6 +6,17 @@ if not modules then modules = { } end modules ['l-lua'] = { license = "see context related readme files" } +-- potential issues with 5.3: + +-- i'm not sure yet if the int/float change is good for luatex + +-- math.min +-- math.max +-- tostring +-- tonumber +-- utf.* +-- bit32 + -- compatibility hacksand helpers local major, minor = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$") @@ -148,3 +159,9 @@ function optionalrequire(...) return result end end + +-- nice for non ascii scripts (this might move): + +if lua then + lua.mask = load([[τεχ = 1]]) and "utf" or "ascii" +end diff --git a/lualibs-os.lua b/lualibs-os.lua index bfafa4f..1dff79c 100644 --- a/lualibs-os.lua +++ b/lualibs-os.lua @@ -137,7 +137,7 @@ function os.resultof(command) end if not io.fileseparator then - if find(os.getenv("PATH"),";") then + if find(os.getenv("PATH"),";",1,true) then io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "mswin" else io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix" @@ -236,7 +236,7 @@ elseif os.type == "windows" then function resolvers.platform(t,k) local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" - if find(architecture,"AMD64") then + if find(architecture,"AMD64",1,true) then -- platform = "mswin-64" platform = "win64" else @@ -252,9 +252,9 @@ elseif name == "linux" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform = "linux-64" - elseif find(architecture,"ppc") then + elseif find(architecture,"ppc",1,true) then platform = "linux-ppc" else platform = "linux" @@ -285,9 +285,9 @@ elseif name == "macosx" then if architecture == "" then -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") platform = "osx-intel" - elseif find(architecture,"i386") then + elseif find(architecture,"i386",1,true) then platform = "osx-intel" - elseif find(architecture,"x86_64") then + elseif find(architecture,"x86_64",1,true) then platform = "osx-64" else platform = "osx-ppc" @@ -301,7 +301,7 @@ elseif name == "sunos" then function resolvers.platform(t,k) local platform, architecture = "", os.resultof("uname -m") or "" - if find(architecture,"sparc") then + if find(architecture,"sparc",1,true) then platform = "solaris-sparc" else -- if architecture == 'i86pc' platform = "solaris-intel" @@ -315,7 +315,7 @@ elseif name == "freebsd" then function resolvers.platform(t,k) local platform, architecture = "", os.resultof("uname -m") or "" - if find(architecture,"amd64") then + if find(architecture,"amd64",1,true) then platform = "freebsd-amd64" else platform = "freebsd" @@ -330,7 +330,7 @@ elseif name == "kfreebsd" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform = "kfreebsd-amd64" else platform = "kfreebsd-i386" @@ -356,7 +356,7 @@ else end function resolvers.bits(t,k) - local bits = find(os.platform,"64") and 64 or 32 + local bits = find(os.platform,"64",1,true) and 64 or 32 os.bits = bits return bits end diff --git a/lualibs-string.lua b/lualibs-string.lua index 9b079b0..3b1a000 100644 --- a/lualibs-string.lua +++ b/lualibs-string.lua @@ -70,6 +70,7 @@ function string.limit(str,n,sentinel) -- not utf proof end local stripper = patterns.stripper +local fullstripper = patterns.fullstripper local collapser = patterns.collapser local longtostring = patterns.longtostring @@ -77,6 +78,10 @@ function string.strip(str) return lpegmatch(stripper,str) or "" end +function string.fullstrip(str) + return lpegmatch(fullstripper,str) or "" +end + function string.collapsespaces(str) return lpegmatch(collapser,str) or "" end diff --git a/lualibs-table.lua b/lualibs-table.lua index c318c57..d231830 100644 --- a/lualibs-table.lua +++ b/lualibs-table.lua @@ -88,6 +88,38 @@ local function sortedkeys(tab) end end +local function sortedhashonly(tab) + if tab then + local srt, s = { }, 0 + for key,_ in next, tab do + if type(key) == "string" then + s = s + 1 + srt[s] = key + end + end + sort(srt) + return srt + else + return { } + end +end + +local function sortedindexonly(tab) + if tab then + local srt, s = { }, 0 + for key,_ in next, tab do + if type(key) == "number" then + s = s + 1 + srt[s] = key + end + end + sort(srt) + return srt + else + return { } + end +end + local function sortedhashkeys(tab,cmp) -- fast one if tab then local srt, s = { }, 0 @@ -114,8 +146,10 @@ function table.allkeys(t) return sortedkeys(keys) end -table.sortedkeys = sortedkeys -table.sortedhashkeys = sortedhashkeys +table.sortedkeys = sortedkeys +table.sortedhashonly = sortedhashonly +table.sortedindexonly = sortedindexonly +table.sortedhashkeys = sortedhashkeys local function nothing() end diff --git a/lualibs-trac-inf.lua b/lualibs-trac-inf.lua index 802f2e6..034726f 100644 --- a/lualibs-trac-inf.lua +++ b/lualibs-trac-inf.lua @@ -12,7 +12,7 @@ if not modules then modules = { } end modules ['trac-inf'] = { -- and rawget. local type, tonumber, select = type, tonumber, select -local format, lower = string.format, string.lower +local format, lower, find = string.format, string.lower, string.find local concat = table.concat local clock = os.gettimeofday or os.clock -- should go in environment @@ -123,7 +123,8 @@ function statistics.show() -- this code will move local register = statistics.register register("used platform", function() - return format("%s, type: %s, binary subtree: %s",os.platform or "unknown",os.type or "unknown", environment.texos or "unknown") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown", environment.texos or "unknown") end) register("luatex banner", function() return lower(status.banner) @@ -136,16 +137,25 @@ function statistics.show() return format("%s direct, %s indirect, %s total", total-indirect, indirect, total) end) if jit then - local status = { jit.status() } - if status[1] then - register("luajit status", function() - return concat(status," ",2) - end) + local jitstatus = { jit.status() } + if jitstatus[1] then + register("luajit options", concat(jitstatus," ",2)) end end -- so far -- collectgarbage("collect") - register("current memory usage",statistics.memused) + register("lua properties",function() + local list = status.list() + local hashchar = tonumber(list.luatex_hashchars) + local mask = lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask == "utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() -- initial newline for i=1,#statusinfo do diff --git a/lualibs-unicode.lua b/lualibs-unicode.lua index 6601a4c..be61f3d 100644 --- a/lualibs-unicode.lua +++ b/lualibs-unicode.lua @@ -6,7 +6,14 @@ if not modules then modules = { } end modules ['l-unicode'] = { license = "see context related readme files" } --- this module will be reorganized +-- in lua 5.3: + +-- utf8.char(···) : concatinated +-- utf8.charpatt : "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" +-- utf8.codes(s) : for p, c in utf8.codes(s) do body end +-- utf8.codepoint(s [, i [, j]]) +-- utf8.len(s [, i]) +-- utf8.offset(s, n [, i]) -- todo: utf.sub replacement (used in syst-aux) -- we put these in the utf namespace: diff --git a/lualibs-util-deb.lua b/lualibs-util-deb.lua index 785373f..ee732b3 100644 --- a/lualibs-util-deb.lua +++ b/lualibs-util-deb.lua @@ -92,37 +92,41 @@ end function debugger.disable() debug.sethook() ---~ counters[debug.getinfo(2,"f").func] = nil + -- counters[debug.getinfo(2,"f").func] = nil end ---~ debugger.enable() - ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) - ---~ debugger.disable() - ---~ print("") ---~ debugger.showstats() ---~ print("") ---~ debugger.showstats(print,3) - +-- debugger.enable() +-- +-- print(math.sin(1*.5)) +-- print(math.sin(1*.5)) +-- print(math.sin(1*.5)) +-- print(math.sin(1*.5)) +-- print(math.sin(1*.5)) +-- +-- debugger.disable() +-- +-- print("") +-- debugger.showstats() +-- print("") +-- debugger.showstats(print,3) +-- -- from the lua book: -function traceback() - local level = 1 +local function showtraceback(rep) -- from lua site / adapted + local level = 2 -- we don't want this function to be reported + local reporter = rep or report while true do - local info = debug.getinfo(level, "Sl") + local info = getinfo(level, "Sl") if not info then break elseif info.what == "C" then - print(format("%3i : C function",level)) + reporter("%2i : %s",level-1,"C function") else - print(format("%3i : [%s]:%d",level,info.short_src,info.currentline)) + reporter("%2i : %s : %s",level-1,info.short_src,info.currentline) end level = level + 1 end end + +debugger.showtraceback = showtraceback +-- debug.showtraceback = showtraceback diff --git a/lualibs-util-env.lua b/lualibs-util-env.lua deleted file mode 100644 index 0a708ea..0000000 --- a/lualibs-util-env.lua +++ /dev/null @@ -1,290 +0,0 @@ -if not modules then modules = { } end modules ['util-env'] = { - 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" -} - -local allocate, mark = utilities.storage.allocate, utilities.storage.mark - -local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find -local unquoted, quoted = string.unquoted, string.quoted -local concat, insert, remove = table.concat, table.insert, table.remove - -environment = environment or { } -local environment = environment - --- precautions - -os.setlocale(nil,nil) -- useless feature and even dangerous in luatex - -function os.setlocale() - -- no way you can mess with it -end - --- dirty tricks (we will replace the texlua call by luatex --luaonly) - -local validengines = allocate { - ["luatex"] = true, - ["luajittex"] = true, - -- ["luatex.exe"] = true, - -- ["luajittex.exe"] = true, -} - -local basicengines = allocate { - ["luatex"] = "luatex", - ["texlua"] = "luatex", - ["texluac"] = "luatex", - ["luajittex"] = "luajittex", - ["texluajit"] = "luajittex", - -- ["texlua.exe"] = "luatex", - -- ["texluajit.exe"] = "luajittex", -} - -local luaengines = allocate { - ["lua"] = true, - ["luajit"] = true, -} - -environment.validengines = validengines -environment.basicengines = basicengines - --- [-1] = binary --- [ 0] = self --- [ 1] = argument 1 ... - --- instead we could set ranges - -if not arg then - environment.used_as_library = true - -- used as library -elseif luaengines[file.removesuffix(arg[-1])] then --- arg[-1] = arg[0] --- arg[ 0] = arg[1] --- for k=2,#arg do --- arg[k-1] = arg[k] --- end --- remove(arg) -- last --- --- environment.used_as_library = true -elseif validengines[file.removesuffix(arg[0])] then - if arg[1] == "--luaonly" then - arg[-1] = arg[0] - arg[ 0] = arg[2] - for k=3,#arg do - arg[k-2] = arg[k] - end - remove(arg) -- last - remove(arg) -- pre-last - else - -- tex run - end - - -- This is an ugly hack but it permits symlinking a script (say 'context') to 'mtxrun' as in: - -- - -- ln -s /opt/minimals/tex/texmf-linux-64/bin/mtxrun context - -- - -- The special mapping hack is needed because 'luatools' boils down to 'mtxrun --script base' - -- but it's unlikely that there will be more of this - - local originalzero = file.basename(arg[0]) - local specialmapping = { luatools == "base" } - - if originalzero ~= "mtxrun" and originalzero ~= "mtxrun.lua" then - arg[0] = specialmapping[originalzero] or originalzero - insert(arg,0,"--script") - insert(arg,0,"mtxrun") - end - -end - --- environment - -environment.arguments = allocate() -environment.files = allocate() -environment.sortedflags = nil - --- context specific arguments (in order not to confuse the engine) - -function environment.initializearguments(arg) - local arguments, files = { }, { } - environment.arguments, environment.files, environment.sortedflags = arguments, files, nil - for index=1,#arg do - local argument = arg[index] - if index > 0 then - local flag, value = match(argument,"^%-+(.-)=(.-)$") - if flag then - flag = gsub(flag,"^c:","") - arguments[flag] = unquoted(value or "") - else - flag = match(argument,"^%-+(.+)") - if flag then - flag = gsub(flag,"^c:","") - arguments[flag] = true - else - files[#files+1] = argument - end - end - end - end - environment.ownname = file.reslash(environment.ownname or arg[0] or 'unknown.lua') -end - -function environment.setargument(name,value) - environment.arguments[name] = value -end - --- todo: defaults, better checks e.g on type (boolean versus string) --- --- tricky: too many hits when we support partials unless we add --- a registration of arguments so from now on we have 'partial' - -function environment.getargument(name,partial) - local arguments, sortedflags = environment.arguments, environment.sortedflags - if arguments[name] then - return arguments[name] - elseif partial then - if not sortedflags then - sortedflags = allocate(table.sortedkeys(arguments)) - for k=1,#sortedflags do - sortedflags[k] = "^" .. sortedflags[k] - end - environment.sortedflags = sortedflags - end - -- example of potential clash: ^mode ^modefile - for k=1,#sortedflags do - local v = sortedflags[k] - if find(name,v) then - return arguments[sub(v,2,#v)] - end - end - end - return nil -end - -environment.argument = environment.getargument - -function environment.splitarguments(separator) -- rather special, cut-off before separator - local done, before, after = false, { }, { } - local originalarguments = environment.originalarguments - for k=1,#originalarguments do - local v = originalarguments[k] - if not done and v == separator then - done = true - elseif done then - after[#after+1] = v - else - before[#before+1] = v - end - end - return before, after -end - -function environment.reconstructcommandline(arg,noquote) - arg = arg or environment.originalarguments - if noquote and #arg == 1 then - -- we could just do: return unquoted(resolvers.resolve(arg[i])) - local a = arg[1] - a = resolvers.resolve(a) - a = unquoted(a) - return a - elseif #arg > 0 then - local result = { } - for i=1,#arg do - -- we could just do: result[#result+1] = format("%q",unquoted(resolvers.resolve(arg[i]))) - local a = arg[i] - a = resolvers.resolve(a) - a = unquoted(a) - a = gsub(a,'"','\\"') -- tricky - if find(a," ") then - result[#result+1] = quoted(a) - else - result[#result+1] = a - end - end - return concat(result," ") - else - return "" - end -end - --- handy in e.g. package.addluapath(environment.relativepath("scripts")) - -function environment.relativepath(path,root) - if not path then - path = "" - end - if not file.is_rootbased_path(path) then - if not root then - root = file.pathpart(environment.ownscript or environment.ownname or ".") - end - if root == "" then - root = "." - end - path = root .. "/" .. path - end - return file.collapsepath(path,true) -end - --- -- when script lives on e:/tmp we get this: --- --- print(environment.relativepath("x/y/z","c:/w")) -- c:/w/x/y/z --- print(environment.relativepath("x")) -- e:/tmp/x --- print(environment.relativepath("../x")) -- e:/x --- print(environment.relativepath("./x")) -- e:/tmp/x --- print(environment.relativepath("/x")) -- /x --- print(environment.relativepath("c:/x")) -- c:/x --- print(environment.relativepath("//x")) -- //x --- print(environment.relativepath()) -- e:/tmp - --- -- to be tested: --- --- function environment.reconstructcommandline(arg,noquote) --- arg = arg or environment.originalarguments --- if noquote and #arg == 1 then --- return unquoted(resolvers.resolve(arg[1])) --- elseif #arg > 0 then --- local result = { } --- for i=1,#arg do --- result[#result+1] = format("%q",unquoted(resolvers.resolve(arg[i]))) -- always quote --- end --- return concat(result," ") --- else --- return "" --- end --- end - -if arg then - - -- new, reconstruct quoted snippets (maybe better just remove the " then and add them later) - local newarg, instring = { }, false - - for index=1,#arg do - local argument = arg[index] - if find(argument,"^\"") then - newarg[#newarg+1] = gsub(argument,"^\"","") - if not find(argument,"\"$") then - instring = true - end - elseif find(argument,"\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") - instring = false - elseif instring then - newarg[#newarg] = newarg[#newarg] .. " " .. argument - else - newarg[#newarg+1] = argument - end - end - for i=1,-5,-1 do - newarg[i] = arg[i] - end - - environment.initializearguments(newarg) - - environment.originalarguments = mark(newarg) - environment.rawarguments = mark(arg) - - arg = { } -- prevent duplicate handling - -end diff --git a/lualibs-util-prs.lua b/lualibs-util-prs.lua index e5b35a7..2cede91 100644 --- a/lualibs-util-prs.lua +++ b/lualibs-util-prs.lua @@ -179,12 +179,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str == "" then return { } elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } diff --git a/lualibs-util-str.lua b/lualibs-util-str.lua index f04f0e5..52c48ba 100644 --- a/lualibs-util-str.lua +++ b/lualibs-util-str.lua @@ -20,16 +20,24 @@ local utfchar, utfbyte = utf.char, utf.byte ----- loadstripped = utilities.lua.loadstripped ----- setmetatableindex = table.setmetatableindex --- local loadstripped = _LUAVERSION < 5.2 and load or function(str) --- return load(dump(load(str),true)) -- it only makes sense in luajit and luatex where we have a stipped load --- end +local loadstripped = nil -local loadstripped = function(str,shortcuts) - if shortcuts then - return load(dump(load(str),true),nil,nil,shortcuts) - else - return load(dump(load(str),true)) +if _LUAVERSION < 5.2 then + + loadstripped = function(str,shortcuts) + return load(str) + end + +else + + loadstripped = function(str,shortcuts) + if shortcuts then + return load(dump(load(str),true),nil,nil,shortcuts) + else + return load(dump(load(str),true)) + end end + end -- todo: make a special namespace for the formatter @@ -39,10 +47,12 @@ if not number then number = { } end -- temp hack for luatex-fonts local stripper = patterns.stripzeros local function points(n) + n = tonumber(n) return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) end local function basepoints(n) + n = tonumber(n) return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) end @@ -144,17 +154,105 @@ end -- 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 +-- todo: lpeg + +-- function strings.striplong(str) -- strips all leading spaces +-- str = gsub(str,"^%s*","") +-- str = gsub(str,"[\n\r]+ *","\n") +-- return str +-- end + +local newline = patterns.newline +local endofstring = patterns.endofstring +local whitespace = patterns.whitespace +local spacer = patterns.spacer + +local space = spacer^0 +local nospace = space/"" +local endofline = nospace * newline + +local stripend = (whitespace^1 * endofstring)/"" + +local normalline = (nospace * ((1-space*(newline+endofstring))^1) * nospace) + +local stripempty = endofline^1/"" +local normalempty = endofline^1 +local singleempty = endofline * (endofline^0/"") +local doubleempty = endofline * endofline^-1 * (endofline^0/"") + +local stripstart = stripempty^0 + +local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 ) +local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 ) +local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 ) +local p_retain_normal = Cs ( ( normalline + normalempty )^0 ) +local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 ) +local p_retain_noempty = Cs ( ( normalline + singleempty )^0 ) + +-- function striplines(str,prune,collapse,noempty) +-- if prune then +-- if noempty then +-- return lpegmatch(p_prune_noempty,str) or str +-- elseif collapse then +-- return lpegmatch(p_prune_collapse,str) or str +-- else +-- return lpegmatch(p_prune_normal,str) or str +-- end +-- else +-- if noempty then +-- return lpegmatch(p_retain_noempty,str) or str +-- elseif collapse then +-- return lpegmatch(p_retain_collapse,str) or str +-- else +-- return lpegmatch(p_retain_normal,str) or str +-- end +-- end +-- end + +local striplinepatterns = { + ["prune"] = p_prune_normal, + ["prune and collapse"] = p_prune_collapse, -- default + ["prune and no empty"] = p_prune_noempty, + ["retain"] = p_retain_normal, + ["retain and collapse"] = p_retain_collapse, + ["retain and no empty"] = p_retain_noempty, +} + +strings.striplinepatterns = striplinepatterns + +function strings.striplines(str,how) + return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str end --- local template = string.striplong([[ +strings.striplong = strings.striplines -- for old times sake + +-- local str = table.concat( { +-- " ", +-- " aap", +-- " noot mies", +-- " ", +-- " ", +-- " zus wim jet", +-- "zus wim jet", +-- " zus wim jet", +-- " ", +-- }, "\n") + +-- local str = table.concat( { +-- " aaaa", +-- " bb", +-- " cccccc", +-- }, "\n") + +-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do +-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k)) +-- end + +-- inspect(strings.striplong([[ -- aaaa -- bb -- cccccc --- ]]) +-- ]])) function strings.nice(str) str = gsub(str,"[:%-+_]+"," ") -- maybe more @@ -305,60 +403,58 @@ local template = [[ return function(%s) return %s end ]] --- local environment = { --- lpeg = lpeg, --- type = type, --- string = string, --- number = number, --- table = table, --- utf = utf, --- } --- --- local preamble = [[ --- local type = type --- local tostring = tostring --- local tonumber = tonumber --- local format = string.format --- local concat = table.concat --- local signed = number.signed --- local points = number.points --- local basepoints = number.basepoints --- local utfchar = utf.char --- local utfbyte = utf.byte --- local lpegmatch = lpeg.match --- local nspaces = string.nspaces --- local tracedchar = string.tracedchar --- local autosingle = string.autosingle --- local autodouble = string.autodouble --- local sequenced = table.sequenced --- local formattednumber = number.formatted --- local sparseexponent = number.sparseexponent --- ]] - -local environment = { - global = global or _G, - lpeg = lpeg, - type = type, - tostring = tostring, - tonumber = tonumber, - format = string.format, - concat = table.concat, - signed = number.signed, - points = number.points, - basepoints = number.basepoints, - utfchar = utf.char, - utfbyte = utf.byte, - lpegmatch = lpeg.match, - nspaces = string.nspaces, - tracedchar = string.tracedchar, - autosingle = string.autosingle, - autodouble = string.autodouble, - sequenced = table.sequenced, - formattednumber = number.formatted, - sparseexponent = number.sparseexponent, -} +local preamble, environment = "", { } + +if _LUAVERSION < 5.2 then + + preamble = [[ +local lpeg=lpeg +local type=type +local tostring=tostring +local tonumber=tonumber +local format=string.format +local concat=table.concat +local signed=number.signed +local points=number.points +local basepoints= number.basepoints +local utfchar=utf.char +local utfbyte=utf.byte +local lpegmatch=lpeg.match +local nspaces=string.nspaces +local tracedchar=string.tracedchar +local autosingle=string.autosingle +local autodouble=string.autodouble +local sequenced=table.sequenced +local formattednumber=number.formatted +local sparseexponent=number.sparseexponent + ]] + +else + + environment = { + global = global or _G, + lpeg = lpeg, + type = type, + tostring = tostring, + tonumber = tonumber, + format = string.format, + concat = table.concat, + signed = number.signed, + points = number.points, + basepoints = number.basepoints, + utfchar = utf.char, + utfbyte = utf.byte, + lpegmatch = lpeg.match, + nspaces = string.nspaces, + tracedchar = string.tracedchar, + autosingle = string.autosingle, + autodouble = string.autodouble, + sequenced = table.sequenced, + formattednumber = number.formatted, + sparseexponent = number.sparseexponent, + } -local preamble = "" +end -- -- -- @@ -412,7 +508,7 @@ local format_i = function(f) if f and f ~= "" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("format('%%i',a%s)",n) -- why not just tostring() end end @@ -428,6 +524,11 @@ local format_f = function(f) return format("format('%%%sf',a%s)",f,n) end +local format_F = function(f) + n = n + 1 + return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n) +end + local format_g = function(f) n = n + 1 return format("format('%%%sg',a%s)",f,n) @@ -701,7 +802,7 @@ local builder = Cs { "start", V("!") -- new + V("s") + V("q") + V("i") + V("d") - + V("f") + V("g") + V("G") + V("e") + V("E") + + V("f") + V("F") + V("g") + V("G") + V("e") + V("E") + V("x") + V("X") + V("o") -- + V("c") @@ -736,6 +837,7 @@ local builder = Cs { "start", ["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) + ["F"] = (prefix_any * P("F")) / format_F, -- %F => regular %f (float) but 0/1 check ["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) @@ -810,7 +912,8 @@ local function make(t,str) f = loadstripped(p)() else n = 0 - p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n + -- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n + p = lpegmatch(builder,str,1,t._connector_,t._extensions_) -- after this we know n if n > 0 then p = format(template,preamble,t._preamble_,arguments[n],p) -- print("builder 2 >",p) @@ -869,14 +972,28 @@ strings.formatters = { } -- table (metatable) in which case we could better keep a count and -- clear that table when a threshold is reached -function strings.formatters.new() - local e = { } -- better make a copy as we can overload - for k, v in next, environment do - e[k] = v +-- _connector_ is an experiment + +if _LUAVERSION < 5.2 then + + function strings.formatters.new(noconcat) + local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } } + setmetatable(t, { __index = make, __call = use }) + return t end - local t = { _extensions_ = { }, _preamble_ = "", _environment_ = e, _type_ = "formatter" } - setmetatable(t, { __index = make, __call = use }) - return t + +else + + function strings.formatters.new(noconcat) + local e = { } -- better make a copy as we can overload + for k, v in next, environment do + e[k] = v + end + local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e } + setmetatable(t, { __index = make, __call = use }) + return t + end + end -- function strings.formatters.new() @@ -921,9 +1038,19 @@ patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n" -- add(formatters,"tex", [[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) -- add(formatters,"lua", [[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) -add(formatters,"xml", [[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape }) -add(formatters,"tex", [[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape }) -add(formatters,"lua", [[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape }) +if _LUAVERSION < 5.2 then + + add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") + add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape") + add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape") + +else + + add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape }) + add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape }) + add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape }) + +end -- -- yes or no: -- diff --git a/lualibs-util-tab.lua b/lualibs-util-tab.lua index ae44269..f9e9b31 100644 --- a/lualibs-util-tab.lua +++ b/lualibs-util-tab.lua @@ -21,27 +21,29 @@ local utftoeight = utf.toeight local splitter = lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) -- defines undefined tables - local composed, shortcut, t = nil, nil, { } +function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables + local composed, t = nil, { } local snippets = lpegmatch(splitter,target) for i=1,#snippets - (nolast and 1 or 0) do local name = snippets[i] if composed then - composed = shortcut .. "." .. name - shortcut = shortcut .. "_" .. name - t[#t+1] = formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed = composed .. "." .. name + t[#t+1] = formatters["if not %s then %s = { } end"](composed,composed) else composed = name - shortcut = name if not nofirst then t[#t+1] = formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed = shortcut .. "." .. snippets[#snippets] + if composed then + if nolast then + composed = composed .. "." .. snippets[#snippets] + end + return concat(t,"\n"), composed -- could be shortcut + else + return "", target end - return concat(t,"\n"), composed end -- local t = tables.definedtable("a","b","c","d") @@ -73,7 +75,7 @@ end function tables.migratetable(target,v,root) local t = root or _G - local names = string.split(target,".") + local names = lpegmatch(splitter,target) for i=1,#names-1 do local name = names[i] t[name] = t[name] or { } @@ -316,7 +318,7 @@ function table.fastserialize(t,prefix) -- not sorted -- only number and string indices (currently) - local r = { prefix or "return" } + local r = { type(prefix) == "string" and prefix or "return" } local m = 1 local function fastserialize(t,outer) -- no mixes @@ -376,7 +378,6 @@ function table.fastserialize(t,prefix) end return r end - return concat(fastserialize(t,true)) end @@ -494,7 +495,8 @@ end -- The next version is somewhat faster, although in practice one will seldom -- serialize a lot using this one. Often the above variants are more efficient. --- If we would really need this a lot, we could hash q keys. +-- If we would really need this a lot, we could hash q keys, or just not used +-- indented code. -- char-def.lua : 0.53 -> 0.38 -- husayni.tma : 0.28 -> 0.19 diff --git a/lualibs.dtx b/lualibs.dtx index 43e567a..be4a57b 100644 --- a/lualibs.dtx +++ b/lualibs.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2009--2013 by PRAGMA ADE / ConTeXt Development Team +% Copyright (C) 2009--2014 by PRAGMA ADE / ConTeXt Development Team % % See ConTeXt's mreadme.pdf for the license. % @@ -34,7 +34,7 @@ \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} -\Msg{* Package: lualibs 2013/11/03 v2.1 Lua additional functions.} +\Msg{* Package: lualibs 2014/05/05 v2.1 Lua additional functions.} \Msg{************************************************************************} \keepsilent @@ -45,7 +45,7 @@ \preamble This is a generated file. -Copyright (C) 2009--2013 by PRAGMA ADE / ConTeXt Development Team +Copyright (C) 2009--2014 by PRAGMA ADE / ConTeXt Development Team See ConTeXt's mreadme.pdf for the license. @@ -101,7 +101,7 @@ and the derived file lualibs.lua. %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{lualibs.drv} - [2013/11/03 v2.1 Lua Libraries.] + [2014/05/05 v2.1 Lua Libraries.] \documentclass{ltxdoc} \usepackage{fancyvrb,xspace} \usepackage[x11names]{xcolor} @@ -202,7 +202,7 @@ and the derived file lualibs.lua. % \GetFileInfo{lualibs.drv} % % \title{The \identifier{lualibs} package} -% \date{2013/11/03 v2.1} +% \date{2014/05/05 v2.1} % \author{Élie Roux · \email{elie.roux@telecom-bretagne.eu}\\ % Philipp Gesang · \email{philipp.gesang@alumni.uni-heidelberg.de}} % @@ -349,7 +349,6 @@ and the derived file lualibs.lua. % lualibs-util-deb.lua & util-deb.lua & extra |debug| functionality \\ % lualibs-util-tpl.lua & util-tpl.lua & templating \\ % lualibs-util-sta.lua & util-sta.lua & stacker (e.~g. for \abbrev{pdf}) \\ -% lualibs-util-env.lua & util-env.lua & |argv| handling \\ % lualibs-util-jsn.lua & util-jsn.lua & conversion to and from json \\[1ex] % \end{tabular} % \label{tab:extended} @@ -418,8 +417,8 @@ lualibs = lualibs or { } lualibs.module_info = { name = "lualibs", - version = 2.10, - date = "2013/11/03", + version = 2.11, + date = "2014/05/05", description = "ConTeXt Lua standard libraries.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -573,8 +572,8 @@ local loadmodule = lualibs.loadmodule local lualibs_basic_module = { name = "lualibs-basic", - version = 2.10, - date = "2013/11/03", + version = 2.11, + date = "2014/05/05", description = "ConTeXt Lua libraries -- basic collection.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -655,8 +654,8 @@ lualibs = lualibs or { } local lualibs_extended_module = { name = "lualibs-extended", - version = 2.10, - date = "2013/11/03", + version = 2.11, + date = "2014/05/05", description = "ConTeXt Lua libraries -- extended collection.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -733,17 +732,6 @@ local fake_trackers = function (name) } end -% \end{macrocode} -% Among the libraries loaded is \verb|util-env.lua|, which adds -% \CONTEXT’s own, superior command line argument handler. -% Packages that rely on their own handling of arguments might not be -% aware of this, or the library might have been loaded by another package -% altogether. -% For these cases we provide a copy of the original \verb|arg| list and -% restore it after we are done loading. -% -% \begin{macrocode} - local backup_store = { } local fake_context = function ( ) @@ -751,8 +739,6 @@ local fake_context = function ( ) if trackers then backup_store.trackers = trackers end logs = fake_logs"logs" trackers = fake_trackers"trackers" - - backup_store.argv = table.fastcopy(arg) end @@ -763,10 +749,8 @@ end local unfake_context = function ( ) if backup_store then local bl, bt = backup_store.logs, backup_store.trackers - local argv = backup_store.argv if bl then logs = bl end if bt then trackers = bt end - if argv then arg = argv end end end @@ -800,11 +784,6 @@ if loaded == false then loadmodule("lualibs-util-deb.lua")--- extra debugging loadmodule("lualibs-util-tpl.lua")--- templating loadmodule("lualibs-util-sta.lua")--- stacker (for writing pdf) - -------------------------------------!data-* -- Context specific - ----------("lualibs-util-lib.lua")---!swiglib; there is a luatex-swiglib - loadmodule("lualibs-util-env.lua")--- environment arguments - ----------("lualibs-mult-ini.lua")--- - ----------("lualibs-core-con.lua")--- end unfake_context() --- TODO check if this works at runtime diff --git a/test-lualibs.lua b/test-lualibs.lua index c592c6e..afc674d 100644 --- a/test-lualibs.lua +++ b/test-lualibs.lua @@ -12,7 +12,7 @@ local luafiles = { "lualibs-string.lua", "lualibs-table.lua", "lualibs-trac-inf.lua", "lualibs-unicode.lua", "lualibs-url.lua", "lualibs-util-deb.lua", - "lualibs-util-dim.lua", "lualibs-util-env.lua", + "lualibs-util-dim.lua", "lualibs-util-jsn.lua", "lualibs-util-lua.lua", "lualibs-util-prs.lua", "lualibs-util-sta.lua", "lualibs-util-sto.lua", "lualibs-util-str.lua", |