From 5eb872dbc6bbc35e222d5b23fc783fb0e75d4a99 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 29 Dec 2009 22:32:00 +0100 Subject: beta 2009.12.29 22:32 --- context/data/scite/scite-ctx.lua | 838 ++++++++++++++++++++++++++++ context/data/scite/scite-ctx.properties | 3 +- scripts/context/lua/luatools.lua | 251 +++++---- scripts/context/lua/mtx-context.lua | 1 + scripts/context/lua/mtx-scite.lua | 155 +++++ scripts/context/lua/mtxrun.lua | 347 +++++++----- scripts/context/lua/scite-ctx.lua | 838 ---------------------------- scripts/context/lua/x-ldx.lua | 2 + scripts/context/stubs/mswin/luatools.lua | 251 +++++---- scripts/context/stubs/mswin/mtxrun.lua | 347 +++++++----- scripts/context/stubs/unix/luatools | 251 +++++---- scripts/context/stubs/unix/mtxrun | 347 +++++++----- tex/context/base/anch-pos.lua | 3 +- tex/context/base/back-pdf.lua | 2 +- tex/context/base/bibl-bib.lua | 5 +- tex/context/base/buff-ini.lua | 23 +- tex/context/base/chem-ini.lua | 7 +- tex/context/base/chem-str.lua | 15 +- tex/context/base/colo-ini.lua | 4 +- tex/context/base/cont-new.mkiv | 6 - tex/context/base/cont-new.tex | 2 +- tex/context/base/context.mkiv | 2 + tex/context/base/context.tex | 2 +- tex/context/base/core-def.mkiv | 2 +- tex/context/base/core-env.mkiv | 7 +- tex/context/base/core-job.lua | 6 +- tex/context/base/core-job.mkiv | 5 +- tex/context/base/core-sys.lua | 4 + tex/context/base/core-uti.lua | 4 +- tex/context/base/data-crl.lua | 8 +- tex/context/base/data-res.lua | 11 +- tex/context/base/data-tex.lua | 3 +- tex/context/base/data-tmf.lua | 41 +- tex/context/base/data-tre.lua | 6 +- tex/context/base/data-use.lua | 6 +- tex/context/base/data-zip.lua | 4 +- tex/context/base/font-afm.lua | 11 +- tex/context/base/font-cid.lua | 3 +- tex/context/base/font-col.lua | 3 +- tex/context/base/font-ctx.lua | 7 +- tex/context/base/font-def.lua | 3 +- tex/context/base/font-ext.lua | 6 +- tex/context/base/font-map.lua | 7 +- tex/context/base/font-mis.lua | 2 +- tex/context/base/font-otb.lua | 139 +++-- tex/context/base/font-otf.lua | 58 +- tex/context/base/font-otn.lua | 281 +++++----- tex/context/base/font-otp.lua | 223 +++++++- tex/context/base/font-syn.lua | 11 +- tex/context/base/font-xtx.lua | 3 +- tex/context/base/grph-inc.lua | 7 +- tex/context/base/java-ini.lua | 11 +- tex/context/base/l-aux.lua | 21 +- tex/context/base/l-dimen.lua | 9 +- tex/context/base/l-dir.lua | 43 +- tex/context/base/l-file.lua | 35 +- tex/context/base/l-io.lua | 6 +- tex/context/base/l-lpeg.lua | 15 +- tex/context/base/l-md5.lua | 2 +- tex/context/base/l-number.lua | 8 +- tex/context/base/l-string.lua | 19 +- tex/context/base/l-url.lua | 7 +- tex/context/base/l-utils.lua | 19 +- tex/context/base/lang-ini.lua | 13 +- tex/context/base/lpdf-fld.lua | 11 +- tex/context/base/lpdf-ini.lua | 5 +- tex/context/base/luat-cnf.lua | 4 +- tex/context/base/luat-env.lua | 33 +- tex/context/base/luat-exe.lua | 11 +- tex/context/base/luat-sta.lua | 9 +- tex/context/base/lxml-ctx.lua | 24 +- tex/context/base/lxml-ent.lua | 3 +- tex/context/base/lxml-ini.mkiv | 2 + tex/context/base/lxml-lpt.lua | 116 ++-- tex/context/base/lxml-mis.lua | 9 +- tex/context/base/lxml-sor.lua | 3 +- tex/context/base/lxml-tab.lua | 15 +- tex/context/base/lxml-tex.lua | 59 +- tex/context/base/meta-pdf.lua | 14 +- tex/context/base/meta-pdh.lua | 54 +- tex/context/base/mlib-pdf.lua | 4 +- tex/context/base/mlib-pps.lua | 21 +- tex/context/base/mlib-run.lua | 7 +- tex/context/base/mult-chk.lua | 6 +- tex/context/base/mult-ini.lua | 5 +- tex/context/base/regi-ini.lua | 4 +- tex/context/base/spac-ver.lua | 5 +- tex/context/base/strc-blk.lua | 7 +- tex/context/base/strc-doc.lua | 8 +- tex/context/base/strc-ini.lua | 7 +- tex/context/base/strc-lst.lua | 5 +- tex/context/base/strc-ref.lua | 7 +- tex/context/base/strc-reg.lua | 5 +- tex/context/base/syst-lua.lua | 11 +- tex/context/base/trac-deb.lua | 5 +- tex/context/base/trac-log.lua | 5 +- tex/context/base/trac-tim.lua | 12 +- tex/context/base/trac-tra.lua | 2 +- tex/context/base/typo-mir.lua | 11 +- tex/context/base/x-asciimath.lua | 9 +- tex/context/base/x-calcmath.lua | 71 +-- tex/context/base/x-ct.lua | 10 +- tex/context/base/x-ldx.tex | 9 +- tex/context/base/x-mathml.lua | 76 +-- tex/context/base/x-mathml.mkiv | 19 +- tex/context/test/x-cals-test.cdx | 31 - tex/context/test/x-cals-test.tex | 48 -- tex/context/test/x-cals-test.xml | 522 ----------------- tex/generic/context/luatex-fonts-merged.lua | 571 +++++++++++-------- tex/generic/context/luatex-mplib.lua | 4 +- 110 files changed, 3471 insertions(+), 3189 deletions(-) create mode 100644 context/data/scite/scite-ctx.lua create mode 100644 scripts/context/lua/mtx-scite.lua delete mode 100644 scripts/context/lua/scite-ctx.lua delete mode 100644 tex/context/test/x-cals-test.cdx delete mode 100644 tex/context/test/x-cals-test.tex delete mode 100644 tex/context/test/x-cals-test.xml diff --git a/context/data/scite/scite-ctx.lua b/context/data/scite/scite-ctx.lua new file mode 100644 index 000000000..8e6b6ebab --- /dev/null +++ b/context/data/scite/scite-ctx.lua @@ -0,0 +1,838 @@ +-- version : 1.0.0 - 07/2005 (2008: lua 5.1) +-- author : Hans Hagen - PRAGMA ADE - www.pragma-ade.com +-- copyright : public domain or whatever suits +-- remark : part of the context distribution, my first lua code + +-- todo: name space for local functions + +-- loading: scite-ctx.properties + +-- # environment variable +-- # +-- # CTXSPELLPATH=t:/spell +-- # +-- # auto language detection +-- # +-- # % version =1.0 language=uk +-- # + +-- ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua +-- +-- # extension.$(file.patterns.context)=scite-ctx.lua +-- # extension.$(file.patterns.example)=scite-ctx.lua +-- +-- # ext.lua.reset=1 +-- # ext.lua.auto.reload=1 +-- # ext.lua.startup.script=t:/lua/scite-ctx.lua +-- +-- ctx.menulist.default=\ +-- wrap=wrap_text|\ +-- unwrap=unwrap_text|\ +-- sort=sort_text|\ +-- document=document_text|\ +-- quote=quote_text|\ +-- compound=compound_text|\ +-- check=check_text +-- +-- ctx.spellcheck.language=auto +-- ctx.spellcheck.wordsize=4 +-- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) +-- +-- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt +-- +-- ctx.spellcheck.wordfile.uk=spell-uk.txt +-- ctx.spellcheck.wordfile.nl=spell-nl.txt +-- ctx.spellcheck.wordsize.uk=4 +-- ctx.spellcheck.wordsize.nl=4 +-- +-- command.name.21.*=CTX Action List +-- command.subsystem.21.*=3 +-- command.21.*=show_menu $(ctx.menulist.default) +-- command.groupundo.21.*=yes +-- command.shortcut.21.*=Shift+F11 +-- +-- command.name.22.*=CTX Check Text +-- command.subsystem.22.*=3 +-- command.22.*=check_text +-- command.groupundo.22.*=yes +-- command.shortcut.22.*=Ctrl+L +-- +-- command.name.23.*=CTX Wrap Text +-- command.subsystem.23.*=3 +-- command.23.*=wrap_text +-- command.groupundo.23.*=yes +-- command.shortcut.23.*=Ctrl+M +-- +-- # command.21.*=check_text +-- # command.21.*=dofile e:\context\lua\scite-ctx.lua + +-- generic functions + +props = props or { } -- setmetatable(props,{ __index = function(k,v) props[k] = "unknown" return "unknown" end } ) + +local byte, lower, upper, gsub, sub, find, rep, match, gmatch = string.byte, string.lower, string.upper, string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch +local sort, concat = table.sort, table.concat + +local crlf = "\n" + +function traceln(str) + trace(str .. crlf) + io.flush() +end + +function string:grab(delimiter) + local list = {} + for snippet in self:gmatch(delimiter) do + list[#list+1] = snippet + end + return list +end + +function string:expand() + return (self:gsub("ENV%((%w+)%)", os.envvar)) +end + +function string:strip() + return (self:gsub("^%s*(.-)%s*$", "%1")) +end + +function table.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',' ')) + end + sort(list,alphacmp) + else + local function alphacmp(a,b) + return lower(a) < lower(b) + end + sort(list,alphacmp) + end +end + +function io.exists(filename) + local ok, result, message = pcall(io.open,filename) + if result then + io.close(result) + return true + else + return false + end +end + +function os.envvar(str) + local s = os.getenv(str) + if s ~= '' then + return s + end + s = os.getenv(upper(str)) + if s ~= '' then + return s + end + s = os.getenv(lower(str)) + if s ~= '' then + return s + end +end + +-- support functions, maybe editor namespace + +-- function column_of_position(position) +-- local line = editor:LineFromPosition(position) +-- local oldposition = editor.CurrentPos +-- local column = 0 +-- editor:GotoPos(position) +-- while editor.CurrentPos ~= 0 and line == editor:LineFromPosition(editor.CurrentPos) do +-- editor:CharLeft() +-- column = column + 1 +-- end +-- editor:GotoPos(oldposition) +-- if line > 0 then +-- return column -1 +-- else +-- return column +-- end +-- end + +-- function line_of_position(position) +-- return editor:LineFromPosition(position) +-- end + +function extend_to_start() + local selectionstart = editor.SelectionStart + local selectionend = editor.SelectionEnd + local line = editor:LineFromPosition(selectionstart) + if line > 0 then + while line == editor:LineFromPosition(selectionstart-1) do + selectionstart = selectionstart - 1 + editor:SetSel(selectionstart,selectionend) + end + else + selectionstart = 0 + end + editor:SetSel(selectionstart,selectionend) + return selectionstart +end + +function extend_to_end() -- editor:LineEndExtend() does not work + local selectionstart = editor.SelectionStart + local selectionend = editor.SelectionEnd + local line = editor:LineFromPosition(selectionend) + while line == editor:LineFromPosition(selectionend+1) do + selectionend = selectionend + 1 + editor:SetSel(selectionstart,selectionend) + end + editor:SetSel(selectionstart,selectionend) + return selectionend +end + +function getfiletype() + local firstline = editor:GetLine(0) + if editor.Lexer == SCLEX_TEX then + return 'tex' + elseif editor.Lexer == SCLEX_XML then + return 'xml' + elseif find(firstline,"^%%") then + return 'tex' + elseif find(firstline,"^<%?xml") then + return 'xml' + else + return 'unknown' + end +end + +-- inspired by LuaExt's scite_Files + +function get_dir_list(mask) + local f + if props['PLAT_GTK'] and props['PLAT_GTK'] ~= "" then + f = io.popen('ls -1 ' .. mask) + else + mask = gsub(mask,'/','\\') + local tmpfile = 'scite-ctx.tmp' + local cmd = 'dir /b "' .. mask .. '" > ' .. tmpfile + os.execute(cmd) + f = io.open(tmpfile) + end + local files = {} + if not f then -- path check added + return files + end + for line in f:lines() do + files[#files+1] = line + end + f:close() + return files +end + +-- banner + +do + + print("loading scite-ctx.lua definition file\n") + print("- see scite-ctx.properties for configuring info\n") + print("- ctx.spellcheck.wordpath set to " .. props['ctx.spellcheck.wordpath']) + if find(lower(props['ctx.spellcheck.wordpath']),"ctxspellpath") then + if os.getenv('ctxspellpath') then + print("- ctxspellpath set to " .. os.getenv('CTXSPELLPATH')) + else + print("- 'ctxspellpath is not set") + end + print("- ctx.spellcheck.wordpath expands to " .. string.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"))) + end + print("\n- recognized first lines:\n") + print("xml ", 2) + +function wrap_text() + + -- We always go to the end of a line, so in fact some of + -- the variables set next are not needed. + + local length = props["ctx.wraptext.length"] + + if length == '' then length = 80 else length = tonumber(length) end + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + editor:LineEndExtend() + + startposition = editor.SelectionStart + endposition = editor.SelectionEnd + + -- local startline = line_of_position(startposition) + -- local endline = line_of_position(endposition) + -- local startcolumn = column_of_position(startposition) + -- local endcolumn = column_of_position(endposition) + -- + -- editor:SetSel(startposition,endposition) + + local startline = props['SelectionStartLine'] + local endline = props['SelectionEndLine'] + local startcolumn = props['SelectionStartColumn'] - 1 + local endcolumn = props['SelectionEndColumn'] - 1 + + local replacement = { } + local templine = '' + local indentation = rep(' ',startcolumn) + local selection = editor:GetSelText() + + selection = gsub(selection,"[\n\r][\n\r]","\n") + selection = gsub(selection,"\n\n+",' ' .. magicstring .. ' ') + selection = gsub(selection,"^%s",'') + + for snippet in gmatch(selection,"%S+") do + if snippet == magicstring then + replacement[#replacement+1] = templine + replacement[#replacement+1] = "" + templine = '' + elseif #templine + #snippet > length then + replacement[#replacement+1] = templine + templine = indentation .. snippet + elseif #templine == 0 then + templine = indentation .. snippet + else + templine = templine .. ' ' .. snippet + end + end + + replacement[#replacement+1] = templine + replacement[1] = gsub(replacement[1],"^%s+",'') + + if endcolumn == 0 then + replacement[#replacement+1] = "" + end + + editor:ReplaceSel(concat(replacement,"\n")) + +end + +function unwrap_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + editor:HomeExtend() + editor:LineEndExtend() + + startposition = editor.SelectionStart + endposition = editor.SelectionEnd + + local magicstring = rep("", 2) + local selection = gsub(editor:GetSelText(),"[\n\r][\n\r]+", ' ' .. magicstring .. ' ') + local replacement = '' + + for snippet in gmatch(selection,"%S+") do + if snippet == magicstring then + replacement = replacement .. "\n" + else + replacement = replacement .. snippet .. "\n" + end + end + + if endcolumn == 0 then replacement = replacement .. "\n" end + + editor:ReplaceSel(replacement) + +end + +function sort_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + -- local startcolumn = column_of_position(startposition) + -- local endcolumn = column_of_position(endposition) + -- + -- editor:SetSel(startposition,endposition) + + local startline = props['SelectionStartLine'] + local endline = props['SelectionEndLine'] + 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) + local replacement = concat(list, "\n") + + editor:GotoPos(startposition) + editor:SetSel(startposition,endposition) + + if endcolumn == 0 then replacement = replacement .. "\n" end + + editor:ReplaceSel(replacement) + +end + +function uncomment_xml() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + local selection = gsub(editor:GetSelText(), "%<%!%-%-.-%-%-%>", '') + + editor:GotoPos(startposition) + editor:SetSel(startposition,endposition) + + editor:ReplaceSel(selection) + editor:GotoPos(startposition) + +end + +function document_text() + + local startposition = editor.SelectionStart + local endposition = editor.SelectionEnd + + if startposition == endposition then return end + + startposition = extend_to_start() + endposition = extend_to_end() + + editor:SetSel(startposition,endposition) + + local filetype = getfiletype() + + local replacement = '' + for i = editor:LineFromPosition(startposition), editor:LineFromPosition(endposition) do + local str = editor:GetLine(i) + if filetype == 'xml' then + if find(str,"^<%!%-%- .* %-%->%s*$") then + replacement = replacement .. gsub(str,"^<%!%-%- (.*) %-%->(%s*)$","%1\n") + elseif find(str,"%S") then + replacement = replacement .. '\n" + else + replacement = replacement .. str + end + else + if find(str,"^%%D%s+$") then + replacement = replacement .. "\n" + elseif find(str,"^%%D ") then + replacement = replacement .. gsub(str,"^%%D ",'') + else + replacement = replacement .. '%D ' .. str + end + end + end + + editor:ReplaceSel(gsub(replacement,"[\n\r]$",'')) + +end + +function quote_text() + + local filetype, leftquotation, rightquotation = getfiletype(), '', '' + + if filetype == 'xml' then + leftquotation, rightquotation = "", "" + leftquote, rightquote = "", "" + else + leftquotation, rightquotation = "\\quotation {", "}" + leftquote, rightquote = "\\quote {", "}" + end + + local replacement = editor:GetSelText() + replacement = gsub(replacement,"\`\`(.-)\'\'", leftquotation .. "%1" .. rightquotation) + replacement = gsub(replacement,"\"(.-)\"", leftquotation .. "%1" .. rightquotation) + replacement = gsub(replacement,"\`(.-)\'", leftquote .. "%1" .. rightquote ) + replacement = gsub(replacement,"\'(.-)\'", leftquote .. "%1" .. rightquote ) + editor:ReplaceSel(replacement) + +end + +function compound_text() + + local filetype = getfiletype() + + if filetype == 'xml' then + editor:ReplaceSel(gsub(editor:GetSelText(),"(>[^<%-][^<%-]+)([-\/])(%w%w+)","%1%3")) + else + editor:ReplaceSel(gsub(editor:GetSelText(),"([^\|])([-\/]+)([^\|])","%1|%2|%3")) + end + +end + +-- written while listening to Alanis Morissette's acoustic +-- Jagged Little Pill and Tori Amos' Beekeeper after +-- reinstalling on my good old ATH-7 + +local language = props["ctx.spellcheck.language"] +local wordsize = props["ctx.spellcheck.wordsize"] +local wordpath = props["ctx.spellcheck.wordpath"] + +if language == '' then language = 'uk' end +if wordsize == '' then wordsize = 4 else wordsize = tonumber(wordsize) end + +local wordfile = "" +local wordlist = {} +local worddone = 0 + +-- we use wordlist as a hash so that we can add entries without the +-- need to sort and also use a fast (built in) search + +-- function kpsewhich_file(filename,filetype,progname) +-- local progflag, typeflag = '', '' +-- local tempname = os.tmpname() +-- if progname then +-- progflag = " --progname=" .. progname .. " " +-- end +-- if filetype then +-- typeflag = " --format=" .. filetype .. " " +-- end +-- local command = "kpsewhich" .. progflag .. typeflag .. " " .. filename .. " > " .. tempname +-- os.execute(command) +-- for line in io.lines(tempname) do +-- return gsub(line, "\s*$", '') +-- end +-- end + +function check_text() + + local dlanguage = props["ctx.spellcheck.language"] + local dwordsize = props["ctx.spellcheck.wordsize"] + local dwordpath = props["ctx.spellcheck.wordpath"] + + if dlanguage ~= '' then dlanguage = tostring(language) end + if dwordsize ~= '' then dwordsize = tonumber(wordsize) end + + local firstline, skipfirst = editor:GetLine(0), false + local filetype, wordskip, wordgood = getfiletype(), '', '' + + if filetype == 'tex' then + wordskip = "\\" + elseif filetype == 'xml' then + wordskip = "<" + wordgood = ">" + end + + if props["ctx.spellcheck.language"] == 'auto' then + if filetype == 'tex' then + -- % version =1.0 language=uk + firstline = gsub(firstline,"^%%%s*",'') + firstline = gsub(firstline,"%s*$",'') + for key, val in gmatch(firstline,"(%w+)=(%w+)") do + if key == "language" then + language = val + traceln("auto document language " .. "'" .. language .. "' (tex)") + end + end + skipfirst = true + elseif filetype == 'xml' then + -- + firstline = gsub(firstline,"^%<%?xml%s*", '') + firstline = gsub(firstline,"%s*%?%>%s*$", '') + for key, val in gmatch(firstline,"(%w+)=[\"\'](.-)[\"\']") do + if key == "language" then + language = val + traceln("auto document language " .. "'" .. language .. "' (xml)") + end + end + skipfirst = true + end + end + + local fname = props["ctx.spellcheck.wordfile." .. language] + local fsize = props["ctx.spellcheck.wordsize." .. language] + + if fsize ~= '' then wordsize = tonumber(fsize) end + + if fname ~= '' and fname ~= wordfile then + wordfile, worddone, wordlist = fname, 0, {} + for filename in gmatch(wordfile,"[^%,]+") do + if wordpath ~= '' then + filename = string.expand(wordpath) .. '/' .. filename + end + if io.exists(filename) then + traceln("loading " .. filename) + for line in io.lines(filename) do + if not find(line,"^[\%\#\-]") then + str = gsub(line,"%s*$", '') + rawset(wordlist,str,true) + worddone = worddone + 1 + end + end + else + traceln("unknown file '" .. filename .."'") + end + end + traceln(worddone .. " words loaded") + end + + reset_text() + + if worddone == 0 then + traceln("no (valid) language or wordfile specified") + else + traceln("start checking") + if wordskip ~= '' then + traceln("ignoring " .. wordskip .. "..." .. wordgood) + end + local i, j, lastpos, startpos, endpos, snippet, len, first = 0, 0, -1, 0, 0, '', 0, 0 + local ok, skip, ch = false, false, '' + if skipfirst then first = #firstline end + for k = first, editor.TextLength do + ch = editor:textrange(k,k+1) + if wordgood ~= '' and ch == wordgood then + skip = false + elseif ch == wordskip then + skip = true + end + if find(ch,"%w") and not find(ch,"%d") then + if not skip then + if ok then + endpos = k + else + startpos = k + endpos = k + ok = true + end + end + elseif ok and not skip then + len = endpos - startpos + 1 + if len >= wordsize then + snippet = editor:textrange(startpos,endpos+1) + i = i + 1 + if wordlist[snippet] or wordlist[lower(snippet)] then + j = j + 1 + else + editor:StartStyling(startpos,INDICS_MASK) + editor:SetStyling(len,INDIC2_MASK) -- INDIC0_MASK+2 + end + end + ok = false + elseif wordgood == '' then + skip = (ch == wordskip) + end + end + traceln(i .. " words checked, " .. (i-j) .. " errors") + end + +end + +function reset_text() + editor:StartStyling(0,INDICS_MASK) + editor:SetStyling(editor.TextLength,INDIC_PLAIN) +end + +-- menu + +local menuactions = {} +local menufunctions = {} + +function UserListShow(menutrigger, menulist) + local menuentries = {} + local list = string.grab(menulist,"[^%|]+") + menuactions = {} + for i=1, #list do + if list[i] ~= '' then + for key, val in gmatch(list[i],"%s*(.+)=(.+)%s*") do + menuentries[#menuentries+1] = key + menuactions[key] = val + end + end + end + local menustring = concat(menuentries,'|') + if menustring == "" then + traceln("There are no templates defined for this file type.") + else + editor.AutoCSeparator = byte('|') + editor:UserListShow(menutrigger,menustring) + editor.AutoCSeparator = byte(' ') + end +end + +function OnUserListSelection(trigger,choice) + if menufunctions[trigger] and menuactions[choice] then + return menufunctions[trigger](menuactions[choice]) + else + return false + end +end + +-- main menu + +local menutrigger = 12 + +function show_menu(menulist) + UserListShow(menutrigger, menulist) +end + +function process_menu(action) + if not find(action,"%(%)$") then + assert(loadstring(action .. "()"))() + else + assert(loadstring(action))() + end +end + +menufunctions[12] = process_menu + +-- templates + +local templatetrigger = 13 + +local ctx_template_paths = { "./ctx-templates", "../ctx-templates", "../../ctx-templates" } +local ctx_auto_templates = false +local ctx_template_list = "" + +local ctx_path_list = {} +local ctx_path_done = {} +local ctx_path_name = {} + +function ctx_list_loaded(path) + return ctx_path_list[path] and #ctx_path_list[path] > 0 +end + +function insert_template(templatelist) + if props["ctx.template.scan"] == "yes" then + local path = props["FileDir"] + local rescan = props["ctx.template.rescan"] == "yes" + local suffix = props["ctx.template.suffix." .. props["FileExt"]] -- alas, no suffix expansion here + local current = path .. "+" .. props["FileExt"] + if rescan then + print("re-scanning enabled") + end + ctx_template_list = "" + if not ctx_path_done[path] or rescan then + local pattern = "*.*" + for i, pathname in ipairs(ctx_template_paths) do + print("scanning " .. gsub(path,"\\","/") .. "/" .. pathname) + ctx_path_name[path] = pathname + ctx_path_list[path] = get_dir_list(pathname .. "/" .. pattern) + if ctx_list_loaded(path) then + print("finished locating template files") + break + end + end + if ctx_list_loaded(path) then + print(#ctx_path_list[path] .. " template files found") + else + print("no template files found") + end + end + if ctx_list_loaded(path) then + ctx_template_list = "" + local pattern = "%." .. suffix .. "$" + local n = 0 + for j, filename in ipairs(ctx_path_list[path]) do + if find(filename,pattern) then + n = n + 1 + local menuname = gsub(filename,"%..-$","") + if ctx_template_list ~= "" then + ctx_template_list = ctx_template_list .. "|" + end + ctx_template_list = ctx_template_list .. menuname .. "=" .. ctx_path_name[path] .. "/" .. filename + end + end + if not ctx_path_done[path] then + print(n .. " suitable template files found") + end + end + ctx_path_done[path] = true + if ctx_template_list == "" then + ctx_auto_templates = false + else + ctx_auto_templates = true + templatelist = ctx_template_list + end + else + ctx_auto_templates = false + end + if templatelist ~= "" then + UserListShow(templatetrigger, templatelist) + end +end + + +-- ctx.template.[whatever].[filetype] +-- ctx.template.[whatever].data.[filetype] +-- ctx.template.[whatever].file.[filetype] +-- ctx.template.[whatever].list.[filetype] + +function process_template_one(action) + local text = nil + if ctx_auto_templates then + local f = io.open(action,"r") + if f then + text = gsub(f:read("*all"),"\n$","") + f:close() + else + print("unable to auto load template file " .. text) + text = nil + end + end + if not text or text == "" then + text = props["ctx.template." .. action .. ".file"] + if not text or text == "" then + text = props["ctx.template." .. action .. ".data"] + if not text or text == "" then + text = props["ctx.template." .. action] + end + else + local f = io.open(text,"r") + if f then + text = gsub(f:read("*all"),"\n$","") + f:close() + else + print("unable to load template file " .. text) + text = nil + end + end + end + if text then + text = gsub(text,"\\n","\n") + local pos = find(text,"%?") + text = gsub(text,"%?","") + editor:insert(editor.CurrentPos,text) + if pos then + editor.CurrentPos = editor.CurrentPos + pos - 1 + editor.SelectionStart = editor.CurrentPos + editor.SelectionEnd = editor.CurrentPos + editor:GotoPos(editor.CurrentPos) + end + end +end + +menufunctions[13] = process_template_one +menufunctions[14] = process_template_two + +-- command.name.26.*=Open Logfile +-- command.subsystem.26.*=3 +-- command.26.*=open_log +-- command.save.before.26.*=2 +-- command.groupundo.26.*=yes +-- command.shortcut.26.*=Ctrl+E + +function open_log() + scite.Open(props['FileName'] .. ".log") +end diff --git a/context/data/scite/scite-ctx.properties b/context/data/scite/scite-ctx.properties index 94a51aeb7..f23508aca 100644 --- a/context/data/scite/scite-ctx.properties +++ b/context/data/scite/scite-ctx.properties @@ -12,7 +12,8 @@ # ext.lua.auto.reload=1 -ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua +#~ ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua +ext.lua.startup.script=$(SciteUserHome)/scite-ctx.lua #~ extension.$(file.patterns.context)=scite-ctx.lua #~ extension.$(file.patterns.example)=scite-ctx.lua diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua index 8568595a6..1019439e0 100644 --- a/scripts/context/lua/luatools.lua +++ b/scripts/context/lua/luatools.lua @@ -45,7 +45,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -87,14 +90,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -114,8 +117,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -153,14 +167,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -173,7 +187,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -182,7 +196,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -252,7 +266,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -271,7 +285,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -298,7 +312,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -325,6 +339,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -377,15 +392,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -416,7 +431,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -429,7 +444,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1356,7 +1371,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1514,7 +1529,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1527,7 +1542,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1548,14 +1563,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1581,7 +1598,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1876,7 +1893,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1934,12 +1952,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2014,27 +2032,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2043,7 +2061,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2054,9 +2072,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2065,11 +2083,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2103,11 +2121,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2120,7 +2138,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2194,7 +2212,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2221,8 +2239,9 @@ if not modules then modules = { } end modules ['l-url'] = { license = "see context related readme files" } -local char, gmatch = string.char, string.gmatch +local char, gmatch, gsub = string.char, string.gmatch, string.gsub local tonumber, type = tonumber, type +local lpegmatch = lpeg.match -- from the spec (on the web): -- @@ -2255,7 +2274,7 @@ local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0 local parser = lpeg.Ct(scheme * authority * path * query * fragment) function url.split(str) - return (type(str) == "string" and parser:match(str)) or str + return (type(str) == "string" and lpegmatch(parser,str)) or str end function url.hashed(str) @@ -2272,7 +2291,7 @@ end function url.filename(filename) local t = url.hashed(filename) - return (t.scheme == "file" and t.path:gsub("^/([a-zA-Z])([:|])/)","%1:")) or filename + return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename end function url.query(str) @@ -2333,7 +2352,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2426,14 +2446,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2514,13 +2534,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2528,11 +2548,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2567,33 +2587,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2614,7 +2634,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2652,8 +2672,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2983,6 +3003,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -3020,7 +3043,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -3038,7 +3061,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -3048,8 +3071,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -3059,7 +3082,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -3085,15 +3108,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -3161,6 +3184,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -3210,9 +3234,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -3223,7 +3247,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -3233,7 +3257,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -3252,7 +3276,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -3264,7 +3288,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3316,7 +3340,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3352,11 +3376,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3465,7 +3489,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3741,7 +3765,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -3777,11 +3802,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -3816,8 +3841,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -3843,16 +3868,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -3869,13 +3894,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -4188,7 +4213,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -4442,7 +4468,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -4533,6 +4559,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -5310,7 +5337,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -6076,7 +6103,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -6097,7 +6124,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -6107,7 +6134,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -6564,7 +6591,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -6964,7 +6991,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -7020,9 +7047,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index d80c7242b..21bc87f73 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -311,6 +311,7 @@ do command = ctxrunner.justtext(command) logs.simple("command: %s",command) local result = os.spawn(command) or 0 + -- somehow we get the wrong return value if result > 0 then logs.simple("error, return code: %s",result) end diff --git a/scripts/context/lua/mtx-scite.lua b/scripts/context/lua/mtx-scite.lua new file mode 100644 index 000000000..7caedea29 --- /dev/null +++ b/scripts/context/lua/mtx-scite.lua @@ -0,0 +1,155 @@ +if not modules then modules = { } end modules ['mtx-scite'] = { + version = 1.001, + comment = "companion to mtxrun.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +scripts = scripts or { } +scripts.scite = scripts.scite or { } + +local scitesignals = { "scite-context.rme", "context.properties" } +local screenfont = "lmtypewriter10-regular.ttf" + +function scripts.scite.start(indeed) + local usedsignal, datapath, fullname, workname, userpath, fontpath + if os.type == "windows" then + workname = "scite.exe" + userpath = os.getenv("USERPROFILE") or "" + fontpath = os.getenv("SYSTEMROOT") + fontpath = (fontpath and file.join(fontpath,"fonts")) or "" + else + workname = "scite" + userpath = os.getenv("HOME") or "" + fontpath = "" + end + local binpaths = file.split_path(os.getenv("PATH")) or file.split_path(os.getenv("path")) + for _, scitesignal in ipairs(scitesignals) do + local scitepath = resolvers.find_file(scitesignal,"other text files") or "" + if scitepath ~= "" then + scitepath = file.dirname(scitepath) -- data + if scitepath == "" then + scitepath = resolvers.clean_path(lfs.currentdir()) + else + usedsignal, datapath = scitesignal, scitepath + break + end + end + end + if not datapath or datapath == "" then + logs.simple("invalid datapath, maybe you need to regenerate the file database") + return false + end + if not binpaths or #binpaths == 0 then + logs.simple("invalid binpath") + return false + end + for i=1,#binpaths do + local p = file.join(binpaths[i],workname) + if lfs.isfile(p) and lfs.attributes(p,"size") > 10000 then -- avoind stub + fullname = p + break + end + end + if not fullname then + logs.simple("unable to locate %s",workname) + return false + end + local properties = dir.glob(file.join(datapath,"*.properties")) + local luafiles = dir.glob(file.join(datapath,"*.lua")) + local extrafont = resolvers.find_file(screenfont,"truetype font") or "" + local pragmafound = dir.glob(file.join(datapath,"pragma.properties")) + if userpath == "" then + logs.simple("unable to figure out userpath") + return false + end + local verbose = environment.argument("verbose") + local tobecopied, logdata = { }, { } + local function check_state(fullname,newpath) + local basename = file.basename(fullname) + local destination = file.join(newpath,basename) + local pa, da = lfs.attributes(fullname), lfs.attributes(destination) + if not da then + logdata[#logdata+1] = { "new : %s", basename } + tobecopied[#tobecopied+1] = { fullname, destination } + elseif pa.modification > da.modification then + logdata[#logdata+1] = { "outdated : %s", basename } + tobecopied[#tobecopied+1] = { fullname, destination } + else + logdata[#logdata+1] = { "up to date : %s", basename } + end + end + for _, property in ipairs(properties) do + check_state(property,userpath) + end + for _, luafile in ipairs(luafiles) do + check_state(luafile,userpath) + end + if fontpath ~= "" then + check_state(extrafont,fontpath) + end + local userpropfile = "sciteuser.properties" + local fullpropfile = file.join(userpath,userpropfile) + local userpropdata = io.loaddata(fullpropfile) + local propfiledone = false + if pragmafound then + if string.find(userpropdata,"import *pragma") then + logdata[#logdata+1] = { "up to date : 'import pragma' in '%s'", userpropfile } + else + logdata[#logdata+1] = { "yet unset : 'import pragma' in '%s'", userpropfile } + userproperties = userpropdata .. "\n\nimport pragma\n\n" + propfiledone = true + end + else + if string.find(userpropdata,"import *context") then + logdata[#logdata+1] = { "up to date : 'import context' in '%s'", userpropfile } + else + logdata[#logdata+1] = { "yet unset : 'import context' in '%s'", userpropfile } + userproperties = userpropdata .. "\n\nimport context\n\n" + propfiledone = true + end + end + if not indeed or verbose then + logs.simple("used signal: %s", usedsignal) + logs.simple("data path : %s", datapath) + logs.simple("full name : %s", fullname) + logs.simple("user path : %s", userpath) + logs.simple("extra font : %s", extrafont) + end + if #logdata > 0 then + logs.simple("") + for k,v in ipairs(logdata) do + logs.simple(v[1],v[2]) + end + end + if indeed then + if #tobecopied > 0 then + logs.simple("warning : copying updated files") + for _, what in ipairs(tobecopied) do + logs.simple("copying : '%s' => '%s'",what[1],what[2]) + file.copy(what[1],what[2]) + end + end + if propfiledone then + logs.simple("saving : '%s'",userpropfile) + io.savedata(fullpropfile,userpropdata) + end + os.launch(fullname) + end +end + +logs.extendbanner("Scite Startup Script 1.00",true) + +messages.help = [[ +--start [--verbose] start scite +--test report what will happen +]] + +if environment.argument("start") then + scripts.scite.start(true) +elseif environment.argument("test") then + scripts.scite.start() +else + logs.help(messages.help) +end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 89cda6978..84bbcb8cc 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -54,7 +54,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -96,14 +99,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -123,8 +126,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -162,14 +176,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -182,7 +196,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -191,7 +205,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -261,7 +275,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -280,7 +294,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -307,7 +321,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -334,6 +348,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -386,15 +401,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -425,7 +440,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -438,7 +453,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1365,7 +1380,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1523,7 +1538,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1536,7 +1551,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1557,14 +1572,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1590,7 +1607,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1885,7 +1902,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1943,12 +1961,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2023,27 +2041,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2052,7 +2070,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2063,9 +2081,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2074,11 +2092,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2112,11 +2130,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2129,7 +2147,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2203,7 +2221,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2231,7 +2249,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2324,14 +2343,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2412,13 +2431,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2426,11 +2445,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2465,33 +2484,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2512,7 +2531,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2550,8 +2569,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2682,6 +2701,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -2719,7 +2741,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -2737,7 +2759,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -2747,8 +2769,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -2758,7 +2780,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -2784,15 +2806,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -2860,6 +2882,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -2909,9 +2932,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -2922,7 +2945,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -2932,7 +2955,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -2951,7 +2974,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -2963,7 +2986,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3015,7 +3038,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3051,11 +3074,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3164,7 +3187,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3456,8 +3479,9 @@ xml = xml or { } local concat, remove, insert = table.concat, table.remove, table.insert local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber -local format, lower, find = string.format, string.lower, string.find +local format, lower, find, match = string.format, string.lower, string.find, string.match local utfchar = unicode.utf8.char +local lpegmatch = lpeg.match --[[ldx--

First a hack to enable namespace resolving. A namespace is characterized by @@ -3497,7 +3521,7 @@ xml.checkns("m","http://www.w3.org/mathml") --ldx]]-- function xml.checkns(namespace,url) - local ns = parse:match(lower(url)) + local ns = lpegmatch(parse,lower(url)) if ns and namespace ~= ns then xml.xmlns[namespace] = ns end @@ -3515,7 +3539,7 @@ This returns mml. --ldx]]-- function xml.resolvens(url) - return parse:match(lower(url)) or "" + return lpegmatch(parse,lower(url)) or "" end --[[ldx-- @@ -3782,7 +3806,7 @@ local function handle_any_entity(str) if trace_entities then logs.report("xml","resolved entity &%s; -> %s (internal)",str,a) end - a = parsedentity:match(a) or a + a = lpegmatch(parsedentity,a) or a else if xml.unknown_any_entity_format then a = xml.unknown_any_entity_format(str) or "" @@ -3961,13 +3985,13 @@ local function xmlconvert(data, settings) if not data or data == "" then errorstr = "empty xml file" elseif utfize or resolve then - if grammar_parsed_text:match(data) then + if lpegmatch(grammar_parsed_text,data) then errorstr = "" else errorstr = "invalid xml file - parsed text" end else - if grammar_unparsed_text:match(data) then + if lpegmatch(grammar_unparsed_text,data) then errorstr = "" else errorstr = "invalid xml file - unparsed text" @@ -4018,7 +4042,7 @@ function xml.is_valid(root) end function xml.package(tag,attributes,data) - local ns, tg = tag:match("^(.-):?([^:]+)$") + local ns, tg = match(tag,"^(.-):?([^:]+)$") local t = { ns = ns, tg = tg, dt = data or "", at = attributes or {} } setmetatable(t, mt) return t @@ -4487,6 +4511,7 @@ if not modules then modules = { } end modules ['lxml-pth'] = { local concat, remove, insert = table.concat, table.remove, table.insert local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep +local lpegmatch = lpeg.match -- beware, this is not xpath ... e.g. position is different (currently) and -- we have reverse-sibling as reversed preceding sibling @@ -4865,6 +4890,7 @@ local function apply_nodes(list,directive,nodes) if ltg then local lns = ll.rn or ll.ns local ok = ltg == ntg and lns == nns +--~ if lns ~= "" then logs.report("!",ltg .. " < " .. (lns or "?")) end if directive then if ok then local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end @@ -4890,6 +4916,9 @@ local function apply_nodes(list,directive,nodes) for n=1,maxn,3 do local nns, ntg = nodes[n+1], nodes[n+2] ok = (not ntg or ltg == ntg) and (not nns or lns == nns) +--~ if lns ~= "" and ntg == "mo" then +--~ logs.report("!",n .. "< ".. maxn .. " < ".. (lns or "?") .. ":" .. ltg .. "< " .. (nns or "?") .. ":" .. ntg .. "==>".. tostring(ok)) +--~ end if ok then break end @@ -4984,8 +5013,7 @@ local cleaner local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s) if expressions[t] then - s = s and s ~= "" and cleaner:match(s) ---~ print("!!!",t,s) + s = s and s ~= "" and lpegmatch(cleaner,s) if s and s ~= "" then return "expr." .. t .. "(ll," .. s ..")" else @@ -5056,7 +5084,7 @@ local function register_nodes(nodetest,nodes) end local function register_expression(expression) - local converted = converter:match(expression) + local converted = lpegmatch(converter,expression) local runner = loadstring(format(template_e,converted)) runner = (runner and runner()) or function() errorrunner_e(expression,converted) end return { kind = "expression", expression = expression, converted = converted, evaluator = runner } @@ -5220,6 +5248,8 @@ end xml.nodesettostring = nodesettostring +local parse_pattern -- we have a harmless kind of circular reference + local function lshow(parsed) if type(parsed) == "string" then parsed = parse_pattern(parsed) @@ -5232,7 +5262,7 @@ end xml.lshow = lshow -local function parse_pattern(pattern) -- the gain of caching is rather minimal +parse_pattern = function (pattern) -- the gain of caching is rather minimal lpathcalls = lpathcalls + 1 if type(pattern) == "table" then return pattern @@ -5241,7 +5271,7 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal if parsed then lpathcached = lpathcached + 1 else - parsed = parser:match(pattern) + parsed = lpegmatch(parser,pattern) if parsed then parsed.pattern = pattern local np = #parsed @@ -5666,7 +5696,8 @@ if not modules then modules = { } end modules ['lxml-mis'] = { local concat = table.concat local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring -local format, gsub = string.format, string.gsub +local format, gsub, match = string.format, string.gsub, string.match +local lpegmatch = lpeg.match --[[ldx--

The following helper functions best belong to the lxml-ini @@ -5740,9 +5771,9 @@ xml.escaped_pattern = escaped xml.unescaped_pattern = unescaped xml.cleansed_pattern = cleansed -function xml.escaped (str) return escaped :match(str) end -function xml.unescaped(str) return unescaped:match(str) end -function xml.cleansed (str) return cleansed :match(str) end +function xml.escaped (str) return lpegmatch(escaped,str) end +function xml.unescaped(str) return lpegmatch(unescaped,str) end +function xml.cleansed (str) return lpegmatch(cleansed,str) end -- this might move @@ -6562,7 +6593,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -6598,11 +6630,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -6637,8 +6669,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -6664,16 +6696,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -6690,13 +6722,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -7009,7 +7041,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -7263,7 +7296,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -7354,6 +7387,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -8131,7 +8165,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -8897,7 +8931,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -8918,7 +8952,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -8928,7 +8962,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -9385,7 +9419,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -9899,7 +9933,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -9955,9 +9989,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end @@ -10031,7 +10065,7 @@ if not modules then modules = { } end modules ['data-zip'] = { license = "see context related readme files" } -local format, find = string.format, string.find +local format, find, match = string.format, string.find, string.match local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -10247,7 +10281,7 @@ function resolvers.register_zip_file(z,tree) end local register, n = resolvers.register_file, 0 for i in z:files() do - local path, name = i.filename:match(filter) + local path, name = match(i.filename,filter) if path then if name and name ~= '' then register(files, name, path) @@ -10277,6 +10311,8 @@ if not modules then modules = { } end modules ['data-crl'] = { license = "see context related readme files" } +local gsub = string.gsub + curl = curl or { } curl.cached = { } @@ -10285,9 +10321,9 @@ curl.cachepath = caches.definepath("curl") local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders function curl.fetch(protocol, name) - local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-") --- cachename = cachename:gsub("[\\/]", io.fileseparator) - cachename = cachename:gsub("[\\]", "/") -- cleanup + local cachename = curl.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") +-- cachename = gsub(cachename,"[\\/]", io.fileseparator) + cachename = gsub(cachename,"[\\]", "/") -- cleanup if not curl.cached[name] then if not io.exists(cachename) then curl.cached[name] = cachename @@ -10639,19 +10675,22 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local find, gsub, match = string.find, string.gsub, string.match +local getenv, setenv = os.getenv, os.setenv + -- loads *.tmf files in minimal tree roots (to be optimized and documented) function resolvers.check_environment(tree) logs.simpleline() - os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) - os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) - os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) + setenv('TMP', getenv('TMP') or getenv('TEMP') or getenv('TMPDIR') or getenv('HOME')) + setenv('TEXOS', getenv('TEXOS') or ("texmf-" .. os.platform)) + setenv('TEXPATH', gsub(tree or "tex","\/+$",'')) + setenv('TEXMFOS', getenv('TEXPATH') .. "/" .. getenv('TEXOS')) logs.simpleline() - logs.simple("preset : TEXPATH => %s", os.getenv('TEXPATH')) - logs.simple("preset : TEXOS => %s", os.getenv('TEXOS')) - logs.simple("preset : TEXMFOS => %s", os.getenv('TEXMFOS')) - logs.simple("preset : TMP => %s", os.getenv('TMP')) + logs.simple("preset : TEXPATH => %s", getenv('TEXPATH')) + logs.simple("preset : TEXOS => %s", getenv('TEXOS')) + logs.simple("preset : TEXMFOS => %s", getenv('TEXMFOS')) + logs.simple("preset : TMP => %s", getenv('TMP')) logs.simple('') end @@ -10659,27 +10698,27 @@ function resolvers.load_environment(name) -- todo: key=value as well as lua local f = io.open(name) if f then for line in f:lines() do - if line:find("^[%%%#]") then + if find(line,"^[%%%#]") then -- skip comment else - local key, how, value = line:match("^(.-)%s*([<=>%?]+)%s*(.*)%s*$") + local key, how, value = match(line,"^(.-)%s*([<=>%?]+)%s*(.*)%s*$") if how then - value = value:gsub("%%(.-)%%", function(v) return os.getenv(v) or "" end) + value = gsub(value,"%%(.-)%%", function(v) return getenv(v) or "" end) if how == "=" or how == "<<" then - os.setenv(key,value) + setenv(key,value) elseif how == "?" or how == "??" then - os.setenv(key,os.getenv(key) or value) + setenv(key,getenv(key) or value) elseif how == "<" or how == "+=" then - if os.getenv(key) then - os.setenv(key,os.getenv(key) .. io.fileseparator .. value) + if getenv(key) then + setenv(key,getenv(key) .. io.fileseparator .. value) else - os.setenv(key,value) + setenv(key,value) end elseif how == ">" or how == "=+" then - if os.getenv(key) then - os.setenv(key,value .. io.pathseparator .. os.getenv(key)) + if getenv(key) then + setenv(key,value .. io.pathseparator .. getenv(key)) else - os.setenv(key,value) + setenv(key,value) end end end @@ -10718,6 +10757,9 @@ if not modules then modules = { } end modules ['luat-sta'] = { -- this code is used in the updater +local gmatch, match = string.gmatch, string.match +local type = type + states = states or { } states.data = states.data or { } states.hash = states.hash or { } @@ -10746,9 +10788,9 @@ function states.set_by_tag(tag,key,value,default,persistent) if d then if type(d) == "table" then local dkey, hkey = key, key - local pre, post = key:match("(.+)%.([^%.]+)$") + local pre, post = match(key,"(.+)%.([^%.]+)$") if pre and post then - for k in pre:gmatch("[^%.]+") do + for k in gmatch(pre,"[^%.]+") do local dk = d[k] if not dk then dk = { } @@ -10780,7 +10822,7 @@ function states.get_by_tag(tag,key,default) else local d = states.data[tag] if d then - for k in key:gmatch("[^%.]+") do + for k in gmatch(key,"[^%.]+") do local dk = d[k] if dk then d = dk @@ -11693,4 +11735,5 @@ end if ok == false then ok = 1 elseif ok == true then ok = 0 end + os.exit(ok) diff --git a/scripts/context/lua/scite-ctx.lua b/scripts/context/lua/scite-ctx.lua deleted file mode 100644 index 8e6b6ebab..000000000 --- a/scripts/context/lua/scite-ctx.lua +++ /dev/null @@ -1,838 +0,0 @@ --- version : 1.0.0 - 07/2005 (2008: lua 5.1) --- author : Hans Hagen - PRAGMA ADE - www.pragma-ade.com --- copyright : public domain or whatever suits --- remark : part of the context distribution, my first lua code - --- todo: name space for local functions - --- loading: scite-ctx.properties - --- # environment variable --- # --- # CTXSPELLPATH=t:/spell --- # --- # auto language detection --- # --- # % version =1.0 language=uk --- # - --- ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua --- --- # extension.$(file.patterns.context)=scite-ctx.lua --- # extension.$(file.patterns.example)=scite-ctx.lua --- --- # ext.lua.reset=1 --- # ext.lua.auto.reload=1 --- # ext.lua.startup.script=t:/lua/scite-ctx.lua --- --- ctx.menulist.default=\ --- wrap=wrap_text|\ --- unwrap=unwrap_text|\ --- sort=sort_text|\ --- document=document_text|\ --- quote=quote_text|\ --- compound=compound_text|\ --- check=check_text --- --- ctx.spellcheck.language=auto --- ctx.spellcheck.wordsize=4 --- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) --- --- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt --- --- ctx.spellcheck.wordfile.uk=spell-uk.txt --- ctx.spellcheck.wordfile.nl=spell-nl.txt --- ctx.spellcheck.wordsize.uk=4 --- ctx.spellcheck.wordsize.nl=4 --- --- command.name.21.*=CTX Action List --- command.subsystem.21.*=3 --- command.21.*=show_menu $(ctx.menulist.default) --- command.groupundo.21.*=yes --- command.shortcut.21.*=Shift+F11 --- --- command.name.22.*=CTX Check Text --- command.subsystem.22.*=3 --- command.22.*=check_text --- command.groupundo.22.*=yes --- command.shortcut.22.*=Ctrl+L --- --- command.name.23.*=CTX Wrap Text --- command.subsystem.23.*=3 --- command.23.*=wrap_text --- command.groupundo.23.*=yes --- command.shortcut.23.*=Ctrl+M --- --- # command.21.*=check_text --- # command.21.*=dofile e:\context\lua\scite-ctx.lua - --- generic functions - -props = props or { } -- setmetatable(props,{ __index = function(k,v) props[k] = "unknown" return "unknown" end } ) - -local byte, lower, upper, gsub, sub, find, rep, match, gmatch = string.byte, string.lower, string.upper, string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch -local sort, concat = table.sort, table.concat - -local crlf = "\n" - -function traceln(str) - trace(str .. crlf) - io.flush() -end - -function string:grab(delimiter) - local list = {} - for snippet in self:gmatch(delimiter) do - list[#list+1] = snippet - end - return list -end - -function string:expand() - return (self:gsub("ENV%((%w+)%)", os.envvar)) -end - -function string:strip() - return (self:gsub("^%s*(.-)%s*$", "%1")) -end - -function table.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',' ')) - end - sort(list,alphacmp) - else - local function alphacmp(a,b) - return lower(a) < lower(b) - end - sort(list,alphacmp) - end -end - -function io.exists(filename) - local ok, result, message = pcall(io.open,filename) - if result then - io.close(result) - return true - else - return false - end -end - -function os.envvar(str) - local s = os.getenv(str) - if s ~= '' then - return s - end - s = os.getenv(upper(str)) - if s ~= '' then - return s - end - s = os.getenv(lower(str)) - if s ~= '' then - return s - end -end - --- support functions, maybe editor namespace - --- function column_of_position(position) --- local line = editor:LineFromPosition(position) --- local oldposition = editor.CurrentPos --- local column = 0 --- editor:GotoPos(position) --- while editor.CurrentPos ~= 0 and line == editor:LineFromPosition(editor.CurrentPos) do --- editor:CharLeft() --- column = column + 1 --- end --- editor:GotoPos(oldposition) --- if line > 0 then --- return column -1 --- else --- return column --- end --- end - --- function line_of_position(position) --- return editor:LineFromPosition(position) --- end - -function extend_to_start() - local selectionstart = editor.SelectionStart - local selectionend = editor.SelectionEnd - local line = editor:LineFromPosition(selectionstart) - if line > 0 then - while line == editor:LineFromPosition(selectionstart-1) do - selectionstart = selectionstart - 1 - editor:SetSel(selectionstart,selectionend) - end - else - selectionstart = 0 - end - editor:SetSel(selectionstart,selectionend) - return selectionstart -end - -function extend_to_end() -- editor:LineEndExtend() does not work - local selectionstart = editor.SelectionStart - local selectionend = editor.SelectionEnd - local line = editor:LineFromPosition(selectionend) - while line == editor:LineFromPosition(selectionend+1) do - selectionend = selectionend + 1 - editor:SetSel(selectionstart,selectionend) - end - editor:SetSel(selectionstart,selectionend) - return selectionend -end - -function getfiletype() - local firstline = editor:GetLine(0) - if editor.Lexer == SCLEX_TEX then - return 'tex' - elseif editor.Lexer == SCLEX_XML then - return 'xml' - elseif find(firstline,"^%%") then - return 'tex' - elseif find(firstline,"^<%?xml") then - return 'xml' - else - return 'unknown' - end -end - --- inspired by LuaExt's scite_Files - -function get_dir_list(mask) - local f - if props['PLAT_GTK'] and props['PLAT_GTK'] ~= "" then - f = io.popen('ls -1 ' .. mask) - else - mask = gsub(mask,'/','\\') - local tmpfile = 'scite-ctx.tmp' - local cmd = 'dir /b "' .. mask .. '" > ' .. tmpfile - os.execute(cmd) - f = io.open(tmpfile) - end - local files = {} - if not f then -- path check added - return files - end - for line in f:lines() do - files[#files+1] = line - end - f:close() - return files -end - --- banner - -do - - print("loading scite-ctx.lua definition file\n") - print("- see scite-ctx.properties for configuring info\n") - print("- ctx.spellcheck.wordpath set to " .. props['ctx.spellcheck.wordpath']) - if find(lower(props['ctx.spellcheck.wordpath']),"ctxspellpath") then - if os.getenv('ctxspellpath') then - print("- ctxspellpath set to " .. os.getenv('CTXSPELLPATH')) - else - print("- 'ctxspellpath is not set") - end - print("- ctx.spellcheck.wordpath expands to " .. string.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"))) - end - print("\n- recognized first lines:\n") - print("xml ", 2) - -function wrap_text() - - -- We always go to the end of a line, so in fact some of - -- the variables set next are not needed. - - local length = props["ctx.wraptext.length"] - - if length == '' then length = 80 else length = tonumber(length) end - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - if startposition == endposition then return end - - editor:LineEndExtend() - - startposition = editor.SelectionStart - endposition = editor.SelectionEnd - - -- local startline = line_of_position(startposition) - -- local endline = line_of_position(endposition) - -- local startcolumn = column_of_position(startposition) - -- local endcolumn = column_of_position(endposition) - -- - -- editor:SetSel(startposition,endposition) - - local startline = props['SelectionStartLine'] - local endline = props['SelectionEndLine'] - local startcolumn = props['SelectionStartColumn'] - 1 - local endcolumn = props['SelectionEndColumn'] - 1 - - local replacement = { } - local templine = '' - local indentation = rep(' ',startcolumn) - local selection = editor:GetSelText() - - selection = gsub(selection,"[\n\r][\n\r]","\n") - selection = gsub(selection,"\n\n+",' ' .. magicstring .. ' ') - selection = gsub(selection,"^%s",'') - - for snippet in gmatch(selection,"%S+") do - if snippet == magicstring then - replacement[#replacement+1] = templine - replacement[#replacement+1] = "" - templine = '' - elseif #templine + #snippet > length then - replacement[#replacement+1] = templine - templine = indentation .. snippet - elseif #templine == 0 then - templine = indentation .. snippet - else - templine = templine .. ' ' .. snippet - end - end - - replacement[#replacement+1] = templine - replacement[1] = gsub(replacement[1],"^%s+",'') - - if endcolumn == 0 then - replacement[#replacement+1] = "" - end - - editor:ReplaceSel(concat(replacement,"\n")) - -end - -function unwrap_text() - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - if startposition == endposition then return end - - editor:HomeExtend() - editor:LineEndExtend() - - startposition = editor.SelectionStart - endposition = editor.SelectionEnd - - local magicstring = rep("", 2) - local selection = gsub(editor:GetSelText(),"[\n\r][\n\r]+", ' ' .. magicstring .. ' ') - local replacement = '' - - for snippet in gmatch(selection,"%S+") do - if snippet == magicstring then - replacement = replacement .. "\n" - else - replacement = replacement .. snippet .. "\n" - end - end - - if endcolumn == 0 then replacement = replacement .. "\n" end - - editor:ReplaceSel(replacement) - -end - -function sort_text() - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - if startposition == endposition then return end - - -- local startcolumn = column_of_position(startposition) - -- local endcolumn = column_of_position(endposition) - -- - -- editor:SetSel(startposition,endposition) - - local startline = props['SelectionStartLine'] - local endline = props['SelectionEndLine'] - 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) - local replacement = concat(list, "\n") - - editor:GotoPos(startposition) - editor:SetSel(startposition,endposition) - - if endcolumn == 0 then replacement = replacement .. "\n" end - - editor:ReplaceSel(replacement) - -end - -function uncomment_xml() - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - if startposition == endposition then return end - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - local selection = gsub(editor:GetSelText(), "%<%!%-%-.-%-%-%>", '') - - editor:GotoPos(startposition) - editor:SetSel(startposition,endposition) - - editor:ReplaceSel(selection) - editor:GotoPos(startposition) - -end - -function document_text() - - local startposition = editor.SelectionStart - local endposition = editor.SelectionEnd - - if startposition == endposition then return end - - startposition = extend_to_start() - endposition = extend_to_end() - - editor:SetSel(startposition,endposition) - - local filetype = getfiletype() - - local replacement = '' - for i = editor:LineFromPosition(startposition), editor:LineFromPosition(endposition) do - local str = editor:GetLine(i) - if filetype == 'xml' then - if find(str,"^<%!%-%- .* %-%->%s*$") then - replacement = replacement .. gsub(str,"^<%!%-%- (.*) %-%->(%s*)$","%1\n") - elseif find(str,"%S") then - replacement = replacement .. '\n" - else - replacement = replacement .. str - end - else - if find(str,"^%%D%s+$") then - replacement = replacement .. "\n" - elseif find(str,"^%%D ") then - replacement = replacement .. gsub(str,"^%%D ",'') - else - replacement = replacement .. '%D ' .. str - end - end - end - - editor:ReplaceSel(gsub(replacement,"[\n\r]$",'')) - -end - -function quote_text() - - local filetype, leftquotation, rightquotation = getfiletype(), '', '' - - if filetype == 'xml' then - leftquotation, rightquotation = "", "" - leftquote, rightquote = "", "" - else - leftquotation, rightquotation = "\\quotation {", "}" - leftquote, rightquote = "\\quote {", "}" - end - - local replacement = editor:GetSelText() - replacement = gsub(replacement,"\`\`(.-)\'\'", leftquotation .. "%1" .. rightquotation) - replacement = gsub(replacement,"\"(.-)\"", leftquotation .. "%1" .. rightquotation) - replacement = gsub(replacement,"\`(.-)\'", leftquote .. "%1" .. rightquote ) - replacement = gsub(replacement,"\'(.-)\'", leftquote .. "%1" .. rightquote ) - editor:ReplaceSel(replacement) - -end - -function compound_text() - - local filetype = getfiletype() - - if filetype == 'xml' then - editor:ReplaceSel(gsub(editor:GetSelText(),"(>[^<%-][^<%-]+)([-\/])(%w%w+)","%1%3")) - else - editor:ReplaceSel(gsub(editor:GetSelText(),"([^\|])([-\/]+)([^\|])","%1|%2|%3")) - end - -end - --- written while listening to Alanis Morissette's acoustic --- Jagged Little Pill and Tori Amos' Beekeeper after --- reinstalling on my good old ATH-7 - -local language = props["ctx.spellcheck.language"] -local wordsize = props["ctx.spellcheck.wordsize"] -local wordpath = props["ctx.spellcheck.wordpath"] - -if language == '' then language = 'uk' end -if wordsize == '' then wordsize = 4 else wordsize = tonumber(wordsize) end - -local wordfile = "" -local wordlist = {} -local worddone = 0 - --- we use wordlist as a hash so that we can add entries without the --- need to sort and also use a fast (built in) search - --- function kpsewhich_file(filename,filetype,progname) --- local progflag, typeflag = '', '' --- local tempname = os.tmpname() --- if progname then --- progflag = " --progname=" .. progname .. " " --- end --- if filetype then --- typeflag = " --format=" .. filetype .. " " --- end --- local command = "kpsewhich" .. progflag .. typeflag .. " " .. filename .. " > " .. tempname --- os.execute(command) --- for line in io.lines(tempname) do --- return gsub(line, "\s*$", '') --- end --- end - -function check_text() - - local dlanguage = props["ctx.spellcheck.language"] - local dwordsize = props["ctx.spellcheck.wordsize"] - local dwordpath = props["ctx.spellcheck.wordpath"] - - if dlanguage ~= '' then dlanguage = tostring(language) end - if dwordsize ~= '' then dwordsize = tonumber(wordsize) end - - local firstline, skipfirst = editor:GetLine(0), false - local filetype, wordskip, wordgood = getfiletype(), '', '' - - if filetype == 'tex' then - wordskip = "\\" - elseif filetype == 'xml' then - wordskip = "<" - wordgood = ">" - end - - if props["ctx.spellcheck.language"] == 'auto' then - if filetype == 'tex' then - -- % version =1.0 language=uk - firstline = gsub(firstline,"^%%%s*",'') - firstline = gsub(firstline,"%s*$",'') - for key, val in gmatch(firstline,"(%w+)=(%w+)") do - if key == "language" then - language = val - traceln("auto document language " .. "'" .. language .. "' (tex)") - end - end - skipfirst = true - elseif filetype == 'xml' then - -- - firstline = gsub(firstline,"^%<%?xml%s*", '') - firstline = gsub(firstline,"%s*%?%>%s*$", '') - for key, val in gmatch(firstline,"(%w+)=[\"\'](.-)[\"\']") do - if key == "language" then - language = val - traceln("auto document language " .. "'" .. language .. "' (xml)") - end - end - skipfirst = true - end - end - - local fname = props["ctx.spellcheck.wordfile." .. language] - local fsize = props["ctx.spellcheck.wordsize." .. language] - - if fsize ~= '' then wordsize = tonumber(fsize) end - - if fname ~= '' and fname ~= wordfile then - wordfile, worddone, wordlist = fname, 0, {} - for filename in gmatch(wordfile,"[^%,]+") do - if wordpath ~= '' then - filename = string.expand(wordpath) .. '/' .. filename - end - if io.exists(filename) then - traceln("loading " .. filename) - for line in io.lines(filename) do - if not find(line,"^[\%\#\-]") then - str = gsub(line,"%s*$", '') - rawset(wordlist,str,true) - worddone = worddone + 1 - end - end - else - traceln("unknown file '" .. filename .."'") - end - end - traceln(worddone .. " words loaded") - end - - reset_text() - - if worddone == 0 then - traceln("no (valid) language or wordfile specified") - else - traceln("start checking") - if wordskip ~= '' then - traceln("ignoring " .. wordskip .. "..." .. wordgood) - end - local i, j, lastpos, startpos, endpos, snippet, len, first = 0, 0, -1, 0, 0, '', 0, 0 - local ok, skip, ch = false, false, '' - if skipfirst then first = #firstline end - for k = first, editor.TextLength do - ch = editor:textrange(k,k+1) - if wordgood ~= '' and ch == wordgood then - skip = false - elseif ch == wordskip then - skip = true - end - if find(ch,"%w") and not find(ch,"%d") then - if not skip then - if ok then - endpos = k - else - startpos = k - endpos = k - ok = true - end - end - elseif ok and not skip then - len = endpos - startpos + 1 - if len >= wordsize then - snippet = editor:textrange(startpos,endpos+1) - i = i + 1 - if wordlist[snippet] or wordlist[lower(snippet)] then - j = j + 1 - else - editor:StartStyling(startpos,INDICS_MASK) - editor:SetStyling(len,INDIC2_MASK) -- INDIC0_MASK+2 - end - end - ok = false - elseif wordgood == '' then - skip = (ch == wordskip) - end - end - traceln(i .. " words checked, " .. (i-j) .. " errors") - end - -end - -function reset_text() - editor:StartStyling(0,INDICS_MASK) - editor:SetStyling(editor.TextLength,INDIC_PLAIN) -end - --- menu - -local menuactions = {} -local menufunctions = {} - -function UserListShow(menutrigger, menulist) - local menuentries = {} - local list = string.grab(menulist,"[^%|]+") - menuactions = {} - for i=1, #list do - if list[i] ~= '' then - for key, val in gmatch(list[i],"%s*(.+)=(.+)%s*") do - menuentries[#menuentries+1] = key - menuactions[key] = val - end - end - end - local menustring = concat(menuentries,'|') - if menustring == "" then - traceln("There are no templates defined for this file type.") - else - editor.AutoCSeparator = byte('|') - editor:UserListShow(menutrigger,menustring) - editor.AutoCSeparator = byte(' ') - end -end - -function OnUserListSelection(trigger,choice) - if menufunctions[trigger] and menuactions[choice] then - return menufunctions[trigger](menuactions[choice]) - else - return false - end -end - --- main menu - -local menutrigger = 12 - -function show_menu(menulist) - UserListShow(menutrigger, menulist) -end - -function process_menu(action) - if not find(action,"%(%)$") then - assert(loadstring(action .. "()"))() - else - assert(loadstring(action))() - end -end - -menufunctions[12] = process_menu - --- templates - -local templatetrigger = 13 - -local ctx_template_paths = { "./ctx-templates", "../ctx-templates", "../../ctx-templates" } -local ctx_auto_templates = false -local ctx_template_list = "" - -local ctx_path_list = {} -local ctx_path_done = {} -local ctx_path_name = {} - -function ctx_list_loaded(path) - return ctx_path_list[path] and #ctx_path_list[path] > 0 -end - -function insert_template(templatelist) - if props["ctx.template.scan"] == "yes" then - local path = props["FileDir"] - local rescan = props["ctx.template.rescan"] == "yes" - local suffix = props["ctx.template.suffix." .. props["FileExt"]] -- alas, no suffix expansion here - local current = path .. "+" .. props["FileExt"] - if rescan then - print("re-scanning enabled") - end - ctx_template_list = "" - if not ctx_path_done[path] or rescan then - local pattern = "*.*" - for i, pathname in ipairs(ctx_template_paths) do - print("scanning " .. gsub(path,"\\","/") .. "/" .. pathname) - ctx_path_name[path] = pathname - ctx_path_list[path] = get_dir_list(pathname .. "/" .. pattern) - if ctx_list_loaded(path) then - print("finished locating template files") - break - end - end - if ctx_list_loaded(path) then - print(#ctx_path_list[path] .. " template files found") - else - print("no template files found") - end - end - if ctx_list_loaded(path) then - ctx_template_list = "" - local pattern = "%." .. suffix .. "$" - local n = 0 - for j, filename in ipairs(ctx_path_list[path]) do - if find(filename,pattern) then - n = n + 1 - local menuname = gsub(filename,"%..-$","") - if ctx_template_list ~= "" then - ctx_template_list = ctx_template_list .. "|" - end - ctx_template_list = ctx_template_list .. menuname .. "=" .. ctx_path_name[path] .. "/" .. filename - end - end - if not ctx_path_done[path] then - print(n .. " suitable template files found") - end - end - ctx_path_done[path] = true - if ctx_template_list == "" then - ctx_auto_templates = false - else - ctx_auto_templates = true - templatelist = ctx_template_list - end - else - ctx_auto_templates = false - end - if templatelist ~= "" then - UserListShow(templatetrigger, templatelist) - end -end - - --- ctx.template.[whatever].[filetype] --- ctx.template.[whatever].data.[filetype] --- ctx.template.[whatever].file.[filetype] --- ctx.template.[whatever].list.[filetype] - -function process_template_one(action) - local text = nil - if ctx_auto_templates then - local f = io.open(action,"r") - if f then - text = gsub(f:read("*all"),"\n$","") - f:close() - else - print("unable to auto load template file " .. text) - text = nil - end - end - if not text or text == "" then - text = props["ctx.template." .. action .. ".file"] - if not text or text == "" then - text = props["ctx.template." .. action .. ".data"] - if not text or text == "" then - text = props["ctx.template." .. action] - end - else - local f = io.open(text,"r") - if f then - text = gsub(f:read("*all"),"\n$","") - f:close() - else - print("unable to load template file " .. text) - text = nil - end - end - end - if text then - text = gsub(text,"\\n","\n") - local pos = find(text,"%?") - text = gsub(text,"%?","") - editor:insert(editor.CurrentPos,text) - if pos then - editor.CurrentPos = editor.CurrentPos + pos - 1 - editor.SelectionStart = editor.CurrentPos - editor.SelectionEnd = editor.CurrentPos - editor:GotoPos(editor.CurrentPos) - end - end -end - -menufunctions[13] = process_template_one -menufunctions[14] = process_template_two - --- command.name.26.*=Open Logfile --- command.subsystem.26.*=3 --- command.26.*=open_log --- command.save.before.26.*=2 --- command.groupundo.26.*=yes --- command.shortcut.26.*=Ctrl+E - -function open_log() - scite.Open(props['FileName'] .. ".log") -end diff --git a/scripts/context/lua/x-ldx.lua b/scripts/context/lua/x-ldx.lua index af5c9c0c8..991640795 100644 --- a/scripts/context/lua/x-ldx.lua +++ b/scripts/context/lua/x-ldx.lua @@ -384,3 +384,5 @@ The main conversion call is: if arg and arg[1] then ldx.convert(arg[1],arg[2]) end + +--~ exit(1) diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua index 8568595a6..1019439e0 100644 --- a/scripts/context/stubs/mswin/luatools.lua +++ b/scripts/context/stubs/mswin/luatools.lua @@ -45,7 +45,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -87,14 +90,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -114,8 +117,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -153,14 +167,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -173,7 +187,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -182,7 +196,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -252,7 +266,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -271,7 +285,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -298,7 +312,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -325,6 +339,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -377,15 +392,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -416,7 +431,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -429,7 +444,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1356,7 +1371,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1514,7 +1529,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1527,7 +1542,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1548,14 +1563,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1581,7 +1598,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1876,7 +1893,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1934,12 +1952,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2014,27 +2032,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2043,7 +2061,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2054,9 +2072,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2065,11 +2083,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2103,11 +2121,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2120,7 +2138,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2194,7 +2212,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2221,8 +2239,9 @@ if not modules then modules = { } end modules ['l-url'] = { license = "see context related readme files" } -local char, gmatch = string.char, string.gmatch +local char, gmatch, gsub = string.char, string.gmatch, string.gsub local tonumber, type = tonumber, type +local lpegmatch = lpeg.match -- from the spec (on the web): -- @@ -2255,7 +2274,7 @@ local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0 local parser = lpeg.Ct(scheme * authority * path * query * fragment) function url.split(str) - return (type(str) == "string" and parser:match(str)) or str + return (type(str) == "string" and lpegmatch(parser,str)) or str end function url.hashed(str) @@ -2272,7 +2291,7 @@ end function url.filename(filename) local t = url.hashed(filename) - return (t.scheme == "file" and t.path:gsub("^/([a-zA-Z])([:|])/)","%1:")) or filename + return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename end function url.query(str) @@ -2333,7 +2352,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2426,14 +2446,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2514,13 +2534,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2528,11 +2548,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2567,33 +2587,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2614,7 +2634,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2652,8 +2672,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2983,6 +3003,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -3020,7 +3043,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -3038,7 +3061,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -3048,8 +3071,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -3059,7 +3082,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -3085,15 +3108,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -3161,6 +3184,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -3210,9 +3234,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -3223,7 +3247,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -3233,7 +3257,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -3252,7 +3276,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -3264,7 +3288,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3316,7 +3340,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3352,11 +3376,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3465,7 +3489,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3741,7 +3765,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -3777,11 +3802,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -3816,8 +3841,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -3843,16 +3868,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -3869,13 +3894,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -4188,7 +4213,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -4442,7 +4468,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -4533,6 +4559,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -5310,7 +5337,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -6076,7 +6103,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -6097,7 +6124,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -6107,7 +6134,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -6564,7 +6591,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -6964,7 +6991,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -7020,9 +7047,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 89cda6978..84bbcb8cc 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -54,7 +54,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -96,14 +99,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -123,8 +126,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -162,14 +176,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -182,7 +196,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -191,7 +205,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -261,7 +275,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -280,7 +294,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -307,7 +321,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -334,6 +348,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -386,15 +401,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -425,7 +440,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -438,7 +453,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1365,7 +1380,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1523,7 +1538,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1536,7 +1551,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1557,14 +1572,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1590,7 +1607,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1885,7 +1902,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1943,12 +1961,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2023,27 +2041,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2052,7 +2070,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2063,9 +2081,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2074,11 +2092,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2112,11 +2130,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2129,7 +2147,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2203,7 +2221,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2231,7 +2249,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2324,14 +2343,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2412,13 +2431,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2426,11 +2445,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2465,33 +2484,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2512,7 +2531,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2550,8 +2569,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2682,6 +2701,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -2719,7 +2741,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -2737,7 +2759,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -2747,8 +2769,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -2758,7 +2780,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -2784,15 +2806,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -2860,6 +2882,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -2909,9 +2932,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -2922,7 +2945,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -2932,7 +2955,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -2951,7 +2974,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -2963,7 +2986,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3015,7 +3038,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3051,11 +3074,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3164,7 +3187,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3456,8 +3479,9 @@ xml = xml or { } local concat, remove, insert = table.concat, table.remove, table.insert local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber -local format, lower, find = string.format, string.lower, string.find +local format, lower, find, match = string.format, string.lower, string.find, string.match local utfchar = unicode.utf8.char +local lpegmatch = lpeg.match --[[ldx--

First a hack to enable namespace resolving. A namespace is characterized by @@ -3497,7 +3521,7 @@ xml.checkns("m","http://www.w3.org/mathml") --ldx]]-- function xml.checkns(namespace,url) - local ns = parse:match(lower(url)) + local ns = lpegmatch(parse,lower(url)) if ns and namespace ~= ns then xml.xmlns[namespace] = ns end @@ -3515,7 +3539,7 @@ This returns mml. --ldx]]-- function xml.resolvens(url) - return parse:match(lower(url)) or "" + return lpegmatch(parse,lower(url)) or "" end --[[ldx-- @@ -3782,7 +3806,7 @@ local function handle_any_entity(str) if trace_entities then logs.report("xml","resolved entity &%s; -> %s (internal)",str,a) end - a = parsedentity:match(a) or a + a = lpegmatch(parsedentity,a) or a else if xml.unknown_any_entity_format then a = xml.unknown_any_entity_format(str) or "" @@ -3961,13 +3985,13 @@ local function xmlconvert(data, settings) if not data or data == "" then errorstr = "empty xml file" elseif utfize or resolve then - if grammar_parsed_text:match(data) then + if lpegmatch(grammar_parsed_text,data) then errorstr = "" else errorstr = "invalid xml file - parsed text" end else - if grammar_unparsed_text:match(data) then + if lpegmatch(grammar_unparsed_text,data) then errorstr = "" else errorstr = "invalid xml file - unparsed text" @@ -4018,7 +4042,7 @@ function xml.is_valid(root) end function xml.package(tag,attributes,data) - local ns, tg = tag:match("^(.-):?([^:]+)$") + local ns, tg = match(tag,"^(.-):?([^:]+)$") local t = { ns = ns, tg = tg, dt = data or "", at = attributes or {} } setmetatable(t, mt) return t @@ -4487,6 +4511,7 @@ if not modules then modules = { } end modules ['lxml-pth'] = { local concat, remove, insert = table.concat, table.remove, table.insert local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep +local lpegmatch = lpeg.match -- beware, this is not xpath ... e.g. position is different (currently) and -- we have reverse-sibling as reversed preceding sibling @@ -4865,6 +4890,7 @@ local function apply_nodes(list,directive,nodes) if ltg then local lns = ll.rn or ll.ns local ok = ltg == ntg and lns == nns +--~ if lns ~= "" then logs.report("!",ltg .. " < " .. (lns or "?")) end if directive then if ok then local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end @@ -4890,6 +4916,9 @@ local function apply_nodes(list,directive,nodes) for n=1,maxn,3 do local nns, ntg = nodes[n+1], nodes[n+2] ok = (not ntg or ltg == ntg) and (not nns or lns == nns) +--~ if lns ~= "" and ntg == "mo" then +--~ logs.report("!",n .. "< ".. maxn .. " < ".. (lns or "?") .. ":" .. ltg .. "< " .. (nns or "?") .. ":" .. ntg .. "==>".. tostring(ok)) +--~ end if ok then break end @@ -4984,8 +5013,7 @@ local cleaner local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s) if expressions[t] then - s = s and s ~= "" and cleaner:match(s) ---~ print("!!!",t,s) + s = s and s ~= "" and lpegmatch(cleaner,s) if s and s ~= "" then return "expr." .. t .. "(ll," .. s ..")" else @@ -5056,7 +5084,7 @@ local function register_nodes(nodetest,nodes) end local function register_expression(expression) - local converted = converter:match(expression) + local converted = lpegmatch(converter,expression) local runner = loadstring(format(template_e,converted)) runner = (runner and runner()) or function() errorrunner_e(expression,converted) end return { kind = "expression", expression = expression, converted = converted, evaluator = runner } @@ -5220,6 +5248,8 @@ end xml.nodesettostring = nodesettostring +local parse_pattern -- we have a harmless kind of circular reference + local function lshow(parsed) if type(parsed) == "string" then parsed = parse_pattern(parsed) @@ -5232,7 +5262,7 @@ end xml.lshow = lshow -local function parse_pattern(pattern) -- the gain of caching is rather minimal +parse_pattern = function (pattern) -- the gain of caching is rather minimal lpathcalls = lpathcalls + 1 if type(pattern) == "table" then return pattern @@ -5241,7 +5271,7 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal if parsed then lpathcached = lpathcached + 1 else - parsed = parser:match(pattern) + parsed = lpegmatch(parser,pattern) if parsed then parsed.pattern = pattern local np = #parsed @@ -5666,7 +5696,8 @@ if not modules then modules = { } end modules ['lxml-mis'] = { local concat = table.concat local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring -local format, gsub = string.format, string.gsub +local format, gsub, match = string.format, string.gsub, string.match +local lpegmatch = lpeg.match --[[ldx--

The following helper functions best belong to the lxml-ini @@ -5740,9 +5771,9 @@ xml.escaped_pattern = escaped xml.unescaped_pattern = unescaped xml.cleansed_pattern = cleansed -function xml.escaped (str) return escaped :match(str) end -function xml.unescaped(str) return unescaped:match(str) end -function xml.cleansed (str) return cleansed :match(str) end +function xml.escaped (str) return lpegmatch(escaped,str) end +function xml.unescaped(str) return lpegmatch(unescaped,str) end +function xml.cleansed (str) return lpegmatch(cleansed,str) end -- this might move @@ -6562,7 +6593,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -6598,11 +6630,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -6637,8 +6669,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -6664,16 +6696,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -6690,13 +6722,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -7009,7 +7041,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -7263,7 +7296,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -7354,6 +7387,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -8131,7 +8165,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -8897,7 +8931,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -8918,7 +8952,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -8928,7 +8962,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -9385,7 +9419,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -9899,7 +9933,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -9955,9 +9989,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end @@ -10031,7 +10065,7 @@ if not modules then modules = { } end modules ['data-zip'] = { license = "see context related readme files" } -local format, find = string.format, string.find +local format, find, match = string.format, string.find, string.match local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -10247,7 +10281,7 @@ function resolvers.register_zip_file(z,tree) end local register, n = resolvers.register_file, 0 for i in z:files() do - local path, name = i.filename:match(filter) + local path, name = match(i.filename,filter) if path then if name and name ~= '' then register(files, name, path) @@ -10277,6 +10311,8 @@ if not modules then modules = { } end modules ['data-crl'] = { license = "see context related readme files" } +local gsub = string.gsub + curl = curl or { } curl.cached = { } @@ -10285,9 +10321,9 @@ curl.cachepath = caches.definepath("curl") local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders function curl.fetch(protocol, name) - local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-") --- cachename = cachename:gsub("[\\/]", io.fileseparator) - cachename = cachename:gsub("[\\]", "/") -- cleanup + local cachename = curl.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") +-- cachename = gsub(cachename,"[\\/]", io.fileseparator) + cachename = gsub(cachename,"[\\]", "/") -- cleanup if not curl.cached[name] then if not io.exists(cachename) then curl.cached[name] = cachename @@ -10639,19 +10675,22 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local find, gsub, match = string.find, string.gsub, string.match +local getenv, setenv = os.getenv, os.setenv + -- loads *.tmf files in minimal tree roots (to be optimized and documented) function resolvers.check_environment(tree) logs.simpleline() - os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) - os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) - os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) + setenv('TMP', getenv('TMP') or getenv('TEMP') or getenv('TMPDIR') or getenv('HOME')) + setenv('TEXOS', getenv('TEXOS') or ("texmf-" .. os.platform)) + setenv('TEXPATH', gsub(tree or "tex","\/+$",'')) + setenv('TEXMFOS', getenv('TEXPATH') .. "/" .. getenv('TEXOS')) logs.simpleline() - logs.simple("preset : TEXPATH => %s", os.getenv('TEXPATH')) - logs.simple("preset : TEXOS => %s", os.getenv('TEXOS')) - logs.simple("preset : TEXMFOS => %s", os.getenv('TEXMFOS')) - logs.simple("preset : TMP => %s", os.getenv('TMP')) + logs.simple("preset : TEXPATH => %s", getenv('TEXPATH')) + logs.simple("preset : TEXOS => %s", getenv('TEXOS')) + logs.simple("preset : TEXMFOS => %s", getenv('TEXMFOS')) + logs.simple("preset : TMP => %s", getenv('TMP')) logs.simple('') end @@ -10659,27 +10698,27 @@ function resolvers.load_environment(name) -- todo: key=value as well as lua local f = io.open(name) if f then for line in f:lines() do - if line:find("^[%%%#]") then + if find(line,"^[%%%#]") then -- skip comment else - local key, how, value = line:match("^(.-)%s*([<=>%?]+)%s*(.*)%s*$") + local key, how, value = match(line,"^(.-)%s*([<=>%?]+)%s*(.*)%s*$") if how then - value = value:gsub("%%(.-)%%", function(v) return os.getenv(v) or "" end) + value = gsub(value,"%%(.-)%%", function(v) return getenv(v) or "" end) if how == "=" or how == "<<" then - os.setenv(key,value) + setenv(key,value) elseif how == "?" or how == "??" then - os.setenv(key,os.getenv(key) or value) + setenv(key,getenv(key) or value) elseif how == "<" or how == "+=" then - if os.getenv(key) then - os.setenv(key,os.getenv(key) .. io.fileseparator .. value) + if getenv(key) then + setenv(key,getenv(key) .. io.fileseparator .. value) else - os.setenv(key,value) + setenv(key,value) end elseif how == ">" or how == "=+" then - if os.getenv(key) then - os.setenv(key,value .. io.pathseparator .. os.getenv(key)) + if getenv(key) then + setenv(key,value .. io.pathseparator .. getenv(key)) else - os.setenv(key,value) + setenv(key,value) end end end @@ -10718,6 +10757,9 @@ if not modules then modules = { } end modules ['luat-sta'] = { -- this code is used in the updater +local gmatch, match = string.gmatch, string.match +local type = type + states = states or { } states.data = states.data or { } states.hash = states.hash or { } @@ -10746,9 +10788,9 @@ function states.set_by_tag(tag,key,value,default,persistent) if d then if type(d) == "table" then local dkey, hkey = key, key - local pre, post = key:match("(.+)%.([^%.]+)$") + local pre, post = match(key,"(.+)%.([^%.]+)$") if pre and post then - for k in pre:gmatch("[^%.]+") do + for k in gmatch(pre,"[^%.]+") do local dk = d[k] if not dk then dk = { } @@ -10780,7 +10822,7 @@ function states.get_by_tag(tag,key,default) else local d = states.data[tag] if d then - for k in key:gmatch("[^%.]+") do + for k in gmatch(key,"[^%.]+") do local dk = d[k] if dk then d = dk @@ -11693,4 +11735,5 @@ end if ok == false then ok = 1 elseif ok == true then ok = 0 end + os.exit(ok) diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools index 8568595a6..1019439e0 100755 --- a/scripts/context/stubs/unix/luatools +++ b/scripts/context/stubs/unix/luatools @@ -45,7 +45,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -87,14 +90,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -114,8 +117,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -153,14 +167,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -173,7 +187,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -182,7 +196,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -252,7 +266,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -271,7 +285,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -298,7 +312,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -325,6 +339,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -377,15 +392,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -416,7 +431,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -429,7 +444,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1356,7 +1371,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1514,7 +1529,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1527,7 +1542,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1548,14 +1563,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1581,7 +1598,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1876,7 +1893,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1934,12 +1952,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2014,27 +2032,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2043,7 +2061,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2054,9 +2072,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2065,11 +2083,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2103,11 +2121,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2120,7 +2138,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2194,7 +2212,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2221,8 +2239,9 @@ if not modules then modules = { } end modules ['l-url'] = { license = "see context related readme files" } -local char, gmatch = string.char, string.gmatch +local char, gmatch, gsub = string.char, string.gmatch, string.gsub local tonumber, type = tonumber, type +local lpegmatch = lpeg.match -- from the spec (on the web): -- @@ -2255,7 +2274,7 @@ local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0 local parser = lpeg.Ct(scheme * authority * path * query * fragment) function url.split(str) - return (type(str) == "string" and parser:match(str)) or str + return (type(str) == "string" and lpegmatch(parser,str)) or str end function url.hashed(str) @@ -2272,7 +2291,7 @@ end function url.filename(filename) local t = url.hashed(filename) - return (t.scheme == "file" and t.path:gsub("^/([a-zA-Z])([:|])/)","%1:")) or filename + return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename end function url.query(str) @@ -2333,7 +2352,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2426,14 +2446,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2514,13 +2534,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2528,11 +2548,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2567,33 +2587,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2614,7 +2634,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2652,8 +2672,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2983,6 +3003,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -3020,7 +3043,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -3038,7 +3061,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -3048,8 +3071,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -3059,7 +3082,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -3085,15 +3108,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -3161,6 +3184,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -3210,9 +3234,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -3223,7 +3247,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -3233,7 +3257,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -3252,7 +3276,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -3264,7 +3288,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3316,7 +3340,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3352,11 +3376,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3465,7 +3489,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3741,7 +3765,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -3777,11 +3802,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -3816,8 +3841,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -3843,16 +3868,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -3869,13 +3894,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -4188,7 +4213,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -4442,7 +4468,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -4533,6 +4559,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -5310,7 +5337,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -6076,7 +6103,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -6097,7 +6124,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -6107,7 +6134,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -6564,7 +6591,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -6964,7 +6991,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -7020,9 +7047,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 89cda6978..84bbcb8cc 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -54,7 +54,10 @@ if not modules then modules = { } end modules ['l-string'] = { license = "see context related readme files" } -local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep +local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match + +-- some functions may disappear as they are not used anywhere if not string.split then @@ -96,14 +99,14 @@ end --~ function string:unquote() --~ if find(self,"^[\'\"]") then ---~ return self:sub(2,-2) +--~ return sub(self,2,-2) --~ else --~ return self --~ end --~ end function string:quote() -- we could use format("%q") - return '"' .. self:unquote() .. '"' + return format("%q",self) end function string:count(pattern) -- variant 3 @@ -123,8 +126,19 @@ function string:limit(n,sentinel) end end -function string:strip() - return (gsub(self,"^%s*(.-)%s*$", "%1")) +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -162,14 +176,14 @@ if not string.characters then local function nextchar(str, index) index = index + 1 - return (index <= #str) and index or nil, str:sub(index,index) + return (index <= #str) and index or nil, sub(str,index,index) end function string:characters() return nextchar, self, 0 end local function nextbyte(str, index) index = index + 1 - return (index <= #str) and index or nil, byte(str:sub(index,index)) + return (index <= #str) and index or nil, byte(sub(str,index,index)) end function string:bytes() return nextbyte, self, 0 @@ -182,7 +196,7 @@ end function string:rpadd(n,chr) local m = n-#self if m > 0 then - return self .. self.rep(chr or " ",m) + return self .. rep(chr or " ",m) else return self end @@ -191,7 +205,7 @@ end function string:lpadd(n,chr) local m = n-#self if m > 0 then - return self.rep(chr or " ",m) .. self + return rep(chr or " ",m) .. self else return self end @@ -261,7 +275,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -280,7 +294,7 @@ function string.tabtospace(str,tab) local s = find(str,"\t") if s then if not tab then tab = 7 end -- only when found - local d = tab-(s-1)%tab + local d = tab-(s-1) % tab if d > 0 then str = gsub(str,"\t",rep(" ",d),1) else @@ -307,7 +321,7 @@ end function string:topattern(lowercase,strict) if lowercase then - self = self:lower() + self = lower(self) end self = gsub(self,".",simple_escapes) if self == "" then @@ -334,6 +348,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -386,15 +401,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -425,7 +440,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -438,7 +453,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1365,7 +1380,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1523,7 +1538,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1536,7 +1551,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -1557,14 +1572,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -1590,7 +1607,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) @@ -1885,7 +1902,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1943,12 +1961,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -2023,27 +2041,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -2052,7 +2070,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -2063,9 +2081,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -2074,11 +2092,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -2112,11 +2130,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -2129,7 +2147,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -2203,7 +2221,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end @@ -2231,7 +2249,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -2324,14 +2343,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -2412,13 +2431,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -2426,11 +2445,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -2465,33 +2484,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -2512,7 +2531,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -2550,8 +2569,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end @@ -2682,6 +2701,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -2719,7 +2741,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -2737,7 +2759,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -2747,8 +2769,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -2758,7 +2780,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -2784,15 +2806,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) @@ -2860,6 +2882,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -2909,9 +2932,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -2922,7 +2945,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -2932,7 +2955,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -2951,7 +2974,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -2963,7 +2986,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -3015,7 +3038,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -3051,11 +3074,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables @@ -3164,7 +3187,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end @@ -3456,8 +3479,9 @@ xml = xml or { } local concat, remove, insert = table.concat, table.remove, table.insert local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber -local format, lower, find = string.format, string.lower, string.find +local format, lower, find, match = string.format, string.lower, string.find, string.match local utfchar = unicode.utf8.char +local lpegmatch = lpeg.match --[[ldx--

First a hack to enable namespace resolving. A namespace is characterized by @@ -3497,7 +3521,7 @@ xml.checkns("m","http://www.w3.org/mathml") --ldx]]-- function xml.checkns(namespace,url) - local ns = parse:match(lower(url)) + local ns = lpegmatch(parse,lower(url)) if ns and namespace ~= ns then xml.xmlns[namespace] = ns end @@ -3515,7 +3539,7 @@ This returns mml. --ldx]]-- function xml.resolvens(url) - return parse:match(lower(url)) or "" + return lpegmatch(parse,lower(url)) or "" end --[[ldx-- @@ -3782,7 +3806,7 @@ local function handle_any_entity(str) if trace_entities then logs.report("xml","resolved entity &%s; -> %s (internal)",str,a) end - a = parsedentity:match(a) or a + a = lpegmatch(parsedentity,a) or a else if xml.unknown_any_entity_format then a = xml.unknown_any_entity_format(str) or "" @@ -3961,13 +3985,13 @@ local function xmlconvert(data, settings) if not data or data == "" then errorstr = "empty xml file" elseif utfize or resolve then - if grammar_parsed_text:match(data) then + if lpegmatch(grammar_parsed_text,data) then errorstr = "" else errorstr = "invalid xml file - parsed text" end else - if grammar_unparsed_text:match(data) then + if lpegmatch(grammar_unparsed_text,data) then errorstr = "" else errorstr = "invalid xml file - unparsed text" @@ -4018,7 +4042,7 @@ function xml.is_valid(root) end function xml.package(tag,attributes,data) - local ns, tg = tag:match("^(.-):?([^:]+)$") + local ns, tg = match(tag,"^(.-):?([^:]+)$") local t = { ns = ns, tg = tg, dt = data or "", at = attributes or {} } setmetatable(t, mt) return t @@ -4487,6 +4511,7 @@ if not modules then modules = { } end modules ['lxml-pth'] = { local concat, remove, insert = table.concat, table.remove, table.insert local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep +local lpegmatch = lpeg.match -- beware, this is not xpath ... e.g. position is different (currently) and -- we have reverse-sibling as reversed preceding sibling @@ -4865,6 +4890,7 @@ local function apply_nodes(list,directive,nodes) if ltg then local lns = ll.rn or ll.ns local ok = ltg == ntg and lns == nns +--~ if lns ~= "" then logs.report("!",ltg .. " < " .. (lns or "?")) end if directive then if ok then local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end @@ -4890,6 +4916,9 @@ local function apply_nodes(list,directive,nodes) for n=1,maxn,3 do local nns, ntg = nodes[n+1], nodes[n+2] ok = (not ntg or ltg == ntg) and (not nns or lns == nns) +--~ if lns ~= "" and ntg == "mo" then +--~ logs.report("!",n .. "< ".. maxn .. " < ".. (lns or "?") .. ":" .. ltg .. "< " .. (nns or "?") .. ":" .. ntg .. "==>".. tostring(ok)) +--~ end if ok then break end @@ -4984,8 +5013,7 @@ local cleaner local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s) if expressions[t] then - s = s and s ~= "" and cleaner:match(s) ---~ print("!!!",t,s) + s = s and s ~= "" and lpegmatch(cleaner,s) if s and s ~= "" then return "expr." .. t .. "(ll," .. s ..")" else @@ -5056,7 +5084,7 @@ local function register_nodes(nodetest,nodes) end local function register_expression(expression) - local converted = converter:match(expression) + local converted = lpegmatch(converter,expression) local runner = loadstring(format(template_e,converted)) runner = (runner and runner()) or function() errorrunner_e(expression,converted) end return { kind = "expression", expression = expression, converted = converted, evaluator = runner } @@ -5220,6 +5248,8 @@ end xml.nodesettostring = nodesettostring +local parse_pattern -- we have a harmless kind of circular reference + local function lshow(parsed) if type(parsed) == "string" then parsed = parse_pattern(parsed) @@ -5232,7 +5262,7 @@ end xml.lshow = lshow -local function parse_pattern(pattern) -- the gain of caching is rather minimal +parse_pattern = function (pattern) -- the gain of caching is rather minimal lpathcalls = lpathcalls + 1 if type(pattern) == "table" then return pattern @@ -5241,7 +5271,7 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal if parsed then lpathcached = lpathcached + 1 else - parsed = parser:match(pattern) + parsed = lpegmatch(parser,pattern) if parsed then parsed.pattern = pattern local np = #parsed @@ -5666,7 +5696,8 @@ if not modules then modules = { } end modules ['lxml-mis'] = { local concat = table.concat local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring -local format, gsub = string.format, string.gsub +local format, gsub, match = string.format, string.gsub, string.match +local lpegmatch = lpeg.match --[[ldx--

The following helper functions best belong to the lxml-ini @@ -5740,9 +5771,9 @@ xml.escaped_pattern = escaped xml.unescaped_pattern = unescaped xml.cleansed_pattern = cleansed -function xml.escaped (str) return escaped :match(str) end -function xml.unescaped(str) return unescaped:match(str) end -function xml.cleansed (str) return cleansed :match(str) end +function xml.escaped (str) return lpegmatch(escaped,str) end +function xml.unescaped(str) return lpegmatch(unescaped,str) end +function xml.cleansed (str) return lpegmatch(cleansed,str) end -- this might move @@ -6562,7 +6593,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -6598,11 +6630,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -6637,8 +6669,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -6664,16 +6696,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -6690,13 +6722,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument @@ -7009,7 +7041,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -7263,7 +7296,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end @@ -7354,6 +7387,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -8131,7 +8165,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -8897,7 +8931,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -8918,7 +8952,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -8928,7 +8962,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -9385,7 +9419,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" @@ -9899,7 +9933,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -9955,9 +9989,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end @@ -10031,7 +10065,7 @@ if not modules then modules = { } end modules ['data-zip'] = { license = "see context related readme files" } -local format, find = string.format, string.find +local format, find, match = string.format, string.find, string.match local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -10247,7 +10281,7 @@ function resolvers.register_zip_file(z,tree) end local register, n = resolvers.register_file, 0 for i in z:files() do - local path, name = i.filename:match(filter) + local path, name = match(i.filename,filter) if path then if name and name ~= '' then register(files, name, path) @@ -10277,6 +10311,8 @@ if not modules then modules = { } end modules ['data-crl'] = { license = "see context related readme files" } +local gsub = string.gsub + curl = curl or { } curl.cached = { } @@ -10285,9 +10321,9 @@ curl.cachepath = caches.definepath("curl") local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders function curl.fetch(protocol, name) - local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-") --- cachename = cachename:gsub("[\\/]", io.fileseparator) - cachename = cachename:gsub("[\\]", "/") -- cleanup + local cachename = curl.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") +-- cachename = gsub(cachename,"[\\/]", io.fileseparator) + cachename = gsub(cachename,"[\\]", "/") -- cleanup if not curl.cached[name] then if not io.exists(cachename) then curl.cached[name] = cachename @@ -10639,19 +10675,22 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local find, gsub, match = string.find, string.gsub, string.match +local getenv, setenv = os.getenv, os.setenv + -- loads *.tmf files in minimal tree roots (to be optimized and documented) function resolvers.check_environment(tree) logs.simpleline() - os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) - os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) - os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) + setenv('TMP', getenv('TMP') or getenv('TEMP') or getenv('TMPDIR') or getenv('HOME')) + setenv('TEXOS', getenv('TEXOS') or ("texmf-" .. os.platform)) + setenv('TEXPATH', gsub(tree or "tex","\/+$",'')) + setenv('TEXMFOS', getenv('TEXPATH') .. "/" .. getenv('TEXOS')) logs.simpleline() - logs.simple("preset : TEXPATH => %s", os.getenv('TEXPATH')) - logs.simple("preset : TEXOS => %s", os.getenv('TEXOS')) - logs.simple("preset : TEXMFOS => %s", os.getenv('TEXMFOS')) - logs.simple("preset : TMP => %s", os.getenv('TMP')) + logs.simple("preset : TEXPATH => %s", getenv('TEXPATH')) + logs.simple("preset : TEXOS => %s", getenv('TEXOS')) + logs.simple("preset : TEXMFOS => %s", getenv('TEXMFOS')) + logs.simple("preset : TMP => %s", getenv('TMP')) logs.simple('') end @@ -10659,27 +10698,27 @@ function resolvers.load_environment(name) -- todo: key=value as well as lua local f = io.open(name) if f then for line in f:lines() do - if line:find("^[%%%#]") then + if find(line,"^[%%%#]") then -- skip comment else - local key, how, value = line:match("^(.-)%s*([<=>%?]+)%s*(.*)%s*$") + local key, how, value = match(line,"^(.-)%s*([<=>%?]+)%s*(.*)%s*$") if how then - value = value:gsub("%%(.-)%%", function(v) return os.getenv(v) or "" end) + value = gsub(value,"%%(.-)%%", function(v) return getenv(v) or "" end) if how == "=" or how == "<<" then - os.setenv(key,value) + setenv(key,value) elseif how == "?" or how == "??" then - os.setenv(key,os.getenv(key) or value) + setenv(key,getenv(key) or value) elseif how == "<" or how == "+=" then - if os.getenv(key) then - os.setenv(key,os.getenv(key) .. io.fileseparator .. value) + if getenv(key) then + setenv(key,getenv(key) .. io.fileseparator .. value) else - os.setenv(key,value) + setenv(key,value) end elseif how == ">" or how == "=+" then - if os.getenv(key) then - os.setenv(key,value .. io.pathseparator .. os.getenv(key)) + if getenv(key) then + setenv(key,value .. io.pathseparator .. getenv(key)) else - os.setenv(key,value) + setenv(key,value) end end end @@ -10718,6 +10757,9 @@ if not modules then modules = { } end modules ['luat-sta'] = { -- this code is used in the updater +local gmatch, match = string.gmatch, string.match +local type = type + states = states or { } states.data = states.data or { } states.hash = states.hash or { } @@ -10746,9 +10788,9 @@ function states.set_by_tag(tag,key,value,default,persistent) if d then if type(d) == "table" then local dkey, hkey = key, key - local pre, post = key:match("(.+)%.([^%.]+)$") + local pre, post = match(key,"(.+)%.([^%.]+)$") if pre and post then - for k in pre:gmatch("[^%.]+") do + for k in gmatch(pre,"[^%.]+") do local dk = d[k] if not dk then dk = { } @@ -10780,7 +10822,7 @@ function states.get_by_tag(tag,key,default) else local d = states.data[tag] if d then - for k in key:gmatch("[^%.]+") do + for k in gmatch(key,"[^%.]+") do local dk = d[k] if dk then d = dk @@ -11693,4 +11735,5 @@ end if ok == false then ok = 1 elseif ok == true then ok = 0 end + os.exit(ok) diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua index 8b64ead8d..c975c715a 100644 --- a/tex/context/base/anch-pos.lua +++ b/tex/context/base/anch-pos.lua @@ -14,6 +14,7 @@ more efficient.

local concat, format = table.concat, string.format local texprint, ctxcatcodes = tex.print, tex.ctxcatcodes +local lpegmatch = lpeg.match jobpositions = jobpositions or { } jobpositions.collected = jobpositions.collected or { } @@ -150,7 +151,7 @@ function jobpositions.MPplus(id,n,default) else local split = jpi[0] if not split then - split = splitter:match(jpi[7]) + split = lpegmatch(splitter,jpi[7]) jpi[0] = split end texprint(ctxcatcodes,split[n] or default) diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua index b9e6b74ad..3b46db0b4 100644 --- a/tex/context/base/back-pdf.lua +++ b/tex/context/base/back-pdf.lua @@ -54,7 +54,7 @@ end function nodeinjections.spotcolor(n,f,d,p) if type(p) == "string" then - p = p:gsub(","," ") -- brr misuse of spot + p = gsub(p,","," ") -- brr misuse of spot end return register(pdfliteral(format("/%s cs /%s CS %s SCN %s scn",n,n,p,p))) end diff --git a/tex/context/base/bibl-bib.lua b/tex/context/base/bibl-bib.lua index 028202ec2..4172e2408 100644 --- a/tex/context/base/bibl-bib.lua +++ b/tex/context/base/bibl-bib.lua @@ -14,6 +14,7 @@ in a convenient way. Actually handling the data takes place elsewhere.

local lower, format = string.lower, string.format local next = next +local lpegmatch = lpeg.match bibtex = bibtex or { } @@ -101,7 +102,7 @@ function bibtex.convert(session,content) data, shortcuts, entries = session.data, session.shortcuts, session.entries -- session.size = session.size + #content bibtex.size = bibtex.size + #content - grammar:match(content or "") + lpegmatch(grammar,content or "") statistics.stoptiming(bibtex) end @@ -138,7 +139,7 @@ function bibtex.toxml(session) if not entries or entries[name] then result[#result+1] = format(" ",name) for key, value in next, entry do - value = escaped_pattern:match(value) + value = lpegmatch(escaped_pattern,value) if value ~= "" then result[#result+1] = format(" %s",key,value) end diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index 753c4a326..1199b47cf 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -28,10 +28,11 @@ local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.prin local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub local type, next = type, next local huge = math.huge -local byte, sub, find, char, gsub, rep, lower, format = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format +local byte, sub, find, char, gsub, rep, lower, format, gmatch = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower, string.format, string.gmatch local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables +local lpegmatch = lpeg.match local data, flags, hooks, visualizers = buffers.data, buffers.flags, buffers.hooks, buffers.visualizers @@ -70,11 +71,11 @@ function buffers.grab(name,begintag,endtag,bufferdata) buffers.level = buffers.level - 1 else if dn == "" then - dn = bufferdata:sub(1,#bufferdata-1) + dn = sub(bufferdata,1,#bufferdata-1) else - dn = dn .. "\n" .. bufferdata:sub(1,#bufferdata-1) + dn = dn .. "\n" .. sub(bufferdata,1,#bufferdata-1) end - dn = dn:gsub("[\010\013]$","") + dn = gsub(dn,"[\010\013]$","") if flags.store_as_table then dn = dn:splitlines() end @@ -185,7 +186,7 @@ end function buffers.typeline(str,n,m,line) n = n + 1 buffers.verbatimbreak(n,m) - if str:find("%S") then + if find(str,"%S") then line = line + 1 hooks.begin_of_line(line) hooks.flush_line(hooks.line(str)) @@ -252,7 +253,7 @@ function buffers.get(name) texprint(b[i]) end else - printer:match(b) + lpegmatch(printer,b) end end end @@ -284,7 +285,7 @@ function buffers.collect(names,separator) -- no print end end else - for name in names:gmatch("[^,%s]+") do + for name in gmatch(names,"[^,%s]+") do local c = content(name,separator) if c ~= "" then t[#t+1] = c @@ -453,7 +454,7 @@ function default.line(str) end function default.flush_line(str) - str = str:gsub(" *[\n\r]+ *"," ") + str = gsub(str," *[\n\r]+ *"," ") if visualizers.obeyspace then for c in utfcharacters(str) do if c == " " then @@ -493,7 +494,7 @@ buffers.commands.nested = "\\switchslantedtype " -- todo : utf + faster, direct print and such. no \\char, vrb catcodes, see end function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess - str = str:gsub(" *[\n\r]+ *"," ") + str = gsub(str," *[\n\r]+ *"," ") local result, c, nested, i = "", "", 0, 1 local commands = buffers.commands -- otherwise wrong commands while i < #str do -- slow @@ -516,7 +517,7 @@ function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess c = sub(str,i,i) if c == " " then result = result .. "\\obs " - elseif c:find("%a") then + elseif find(c,"%a") then result = result .. c else result = result .. "\\char" .. byte(c) .. " " @@ -661,6 +662,6 @@ end --~ str = [[test 123 test $oeps$]] ---~ pattern:match(str) +--~ lpegmatch(pattern,str) diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua index a4af57256..908749092 100644 --- a/tex/context/base/chem-ini.lua +++ b/tex/context/base/chem-ini.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['chem-ini'] = { } local format, texsprint = string.format, tex.sprint +local lpegmatch = lpeg.match local trace_molecules = false trackers.register("chemistry.molecules", function(v) trace_molecules = v end) @@ -60,15 +61,15 @@ local parser = lpeg.Cs((csname + lowhigh + highlow + low + high + sign + any chemicals.moleculeparser = parser -- can be used to avoid functioncall function chemicals.molecule(str) - return parser:match(str) + return lpegmatch(parser,str) end function commands.molecule(str) if trace_molecules then - local rep = parser:match(str) + local rep = lpegmatch(parser,str) logs.report("chemistry", "molecule %s => %s",str,rep) texsprint(ctxcatcodes,rep) else - texsprint(ctxcatcodes,parser:match(str)) + texsprint(ctxcatcodes,lpegmatch(parser,str)) end end diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua index 1a68450f9..b151ab2a0 100644 --- a/tex/context/base/chem-str.lua +++ b/tex/context/base/chem-str.lua @@ -17,6 +17,7 @@ local format, gmatch, match, lower, gsub = string.format, string.gmatch, string. local concat, insert, remove = table.concat, table.insert, table.remove local apply = structure.processors.apply local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local lpegmatch = lpeg.match local variables = interfaces.variables @@ -154,7 +155,7 @@ function chemicals.define(name,spec,text) end local metacode, kind, keys, bonds, max, txt, textsize, rot, pstack -local molecule = chemicals.molecule -- or use chemicals.moleculeparser:match(...) +local molecule = chemicals.molecule -- or use lpegmatch(chemicals.moleculeparser,...) local function fetch(txt) local st = stack[txt] @@ -197,12 +198,12 @@ local pattern = lpeg.Cc(false) * lpeg.Cc(false) * lpeg.Cc(false) * text ) ---~ local n, operation, index, upto, set, text = pattern:match("RZ1357") +--~ local n, operation, index, upto, set, text = lpegmatch(pattern,"RZ1357") ---~ print(pattern:match("RZ=x")) 1 RZ false false false x ---~ print(pattern:match("RZ1=x")) 1 RZ 1 false false x ---~ print(pattern:match("RZ1..3=x")) 1 RZ 1 3 false x ---~ print(pattern:match("RZ13=x")) 1 RZ false false table x +--~ print(lpegmatch(pattern,"RZ=x")) 1 RZ false false false x +--~ print(lpegmatch(pattern,"RZ1=x")) 1 RZ 1 false false x +--~ print(lpegmatch(pattern,"RZ1..3=x")) 1 RZ 1 3 false x +--~ print(lpegmatch(pattern,"RZ13=x")) 1 RZ false false table x local function process(spec,text,n,rulethickness,rulecolor,offset) insert(stack,{ spec=spec, text=text, n=n }) @@ -216,7 +217,7 @@ local function process(spec,text,n,rulethickness,rulecolor,offset) process(di.spec,di.text,1,rulethickness,rulecolor) end else - local rep, operation, special, index, upto, set, text = pattern:match(s) + local rep, operation, special, index, upto, set, text = lpegmatch(pattern,s) if operation == "pb" then insert(pstack,kind) metacode[#metacode+1] = syntax.pb.direct diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index 9f4331a1b..ac68df495 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['colo-ini'] = { } local concat = table.concat -local format, gmatch, gsub, lower, match = string.format, string.gmatch, string.gsub, string.lower, string.match +local format, gmatch, gsub, lower, match, find = string.format, string.gmatch, string.gsub, string.lower, string.match, string.find local texsprint = tex.sprint local ctxcatcodes = tex.ctxcatcodes @@ -232,7 +232,7 @@ function colors.isblack(ca) -- maybe commands end function colors.definespotcolor(name,parent,str,global) - if parent == "" or parent:find("=") then + if parent == "" or find(parent,"=") then colors.registerspotcolor(name, parent) elseif name ~= parent then local cp = attributes_list[a_color][parent] diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index a4157ada6..f256094f7 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -63,12 +63,6 @@ % \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath())}} % \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}} -\startluacode - statistics.register("result saved in file", function() - return string.format( "%s.%s", "\outputfilename", (tex.pdfoutput>0 and "pdf") or "dvi") - end) -\stopluacode - %D For the moment we report some statistics. Later this will become an option, %D but for now we need this information. diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 663a96ab3..9e7e2cd50 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2009.12.26 22:23} +\newcontextversion{2009.12.29 22:32} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 51f5d92d4..36f4f375d 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -315,6 +315,8 @@ \loadmarkfile{page-app} \loadmarkfile{meta-fig} +\loadmarkfile{node-bck} % overloads anch-pgr (experimental and undocumented) + \loadcorefile{lang-spa} \loadmarkfile{bibl-bib} diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 14cbe60b3..25374601e 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2009.12.26 22:23} +\edef\contextversion{2009.12.29 22:32} %D For those who want to use this: diff --git a/tex/context/base/core-def.mkiv b/tex/context/base/core-def.mkiv index 04bd7c09e..9f9d5b927 100644 --- a/tex/context/base/core-def.mkiv +++ b/tex/context/base/core-def.mkiv @@ -48,7 +48,7 @@ %appendtoks \page[\v!last] \page \to \everybye % moved to core-job, we need to do this cleaner \appendtoks \ifarrangingpages\poparrangedpages\fi \to \everybye -\appendtoks \registerfileinfo[end]\jobname \to \everybye +%appendtoks \registerfileinfo[end]\jobfilename \to \everybye \appendtoks \MPLIBallocate{1000} \to \everydump diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv index 941914272..2d717df9a 100644 --- a/tex/context/base/core-env.mkiv +++ b/tex/context/base/core-env.mkiv @@ -193,8 +193,11 @@ \fi \endcsname\empty} % takes one argument -\def\setupwithargument#1% - {\csname\??su:\ifcsname\??su:#1\endcsname#1\else\letterpercent\fi\endcsname} +% \def\setupwithargument#1% +% {\csname\??su:\ifcsname\??su:#1\endcsname#1\else\letterpercent\fi\endcsname} + +\edef\setupwithargument#1% saves a few expansions + {\noexpand\csname\??su:\noexpand\ifcsname\??su:#1\endcsname#1\noexpand\else\letterpercent\noexpand\fi\endcsname} \let\directsetup\dosetups diff --git a/tex/context/base/core-job.lua b/tex/context/base/core-job.lua index df334573a..d557818bb 100644 --- a/tex/context/base/core-job.lua +++ b/tex/context/base/core-job.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['core-job'] = { local texsprint, texprint, texwrite = tex.sprint, tex.print, tex.write local ctxcatcodes, texcatcodes = tex.ctxcatcodes, tex.texcatcodes -local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch +local lower, format, find, gmatch, gsub, match = string.lower, string.format, string.find, string.gmatch, string.gsub, string.match local concat = table.concat -- main code @@ -102,11 +102,11 @@ local function convertexamodes(str) local label = e.at and e.at.label if label and label ~= "" then local data = xml.text(e) - local mode = label:match("^mode:(.+)$") + local mode = match(label,"^mode:(.+)$") if mode then texsprint(ctxcatcodes,format("\\enablemode[%s:%s]",mode,data)) end - texsprint(ctxcatcodes,format("\\setvariable{exa:variables}{%s}{%s}",label,data:gsub("([{}])","\\%1"))) + texsprint(ctxcatcodes,format("\\setvariable{exa:variables}{%s}{%s}",label,gsub(data,"([{}])","\\%1"))) end end end diff --git a/tex/context/base/core-job.mkiv b/tex/context/base/core-job.mkiv index 131d15578..acf96c7a8 100644 --- a/tex/context/base/core-job.mkiv +++ b/tex/context/base/core-job.mkiv @@ -117,7 +117,7 @@ \def\starttext {\doateverystarttext \ifcase\textlevel - \registerfileinfo[begin]\jobname + \registerfileinfo[begin]\jobfilename \fi \global\advance\textlevel\plusone} @@ -130,6 +130,9 @@ %\the\everybye % %\the\everygoodbye % == \end (new) %\expandafter\normalend % +\ifcase\textlevel + \registerfileinfo[end]\jobfilename +\fi \expandafter\finalend \fi} diff --git a/tex/context/base/core-sys.lua b/tex/context/base/core-sys.lua index f530896fa..c5aa89d98 100644 --- a/tex/context/base/core-sys.lua +++ b/tex/context/base/core-sys.lua @@ -16,3 +16,7 @@ function commands.updatefilenames(inputfilename,outputfilename) environment.inputfilebarename = removesuffix(basename(inputfilename)) environment.inputfilesuffix = lower(extname(inputfilename)) end + +statistics.register("result saved in file", function() + return string.format( "%s.%s", environment.outputfilename, (tex.pdfoutput>0 and "pdf") or "dvi") +end) diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index c20e7b274..c1cf0627c 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -17,7 +17,7 @@ utility file under different setups, we now load a table once. This saves much runtime but at the cost of more memory usage.

--ldx]]-- -local sort, concat, format = table.sort, table.concat, string.format +local sort, concat, format, match = table.sort, table.concat, string.format, string.match local next, type, tostring = next, type, tostring local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes @@ -236,7 +236,7 @@ function job.load(filename) statistics.starttiming(job._load_) local data = io.loaddata(filename) if data and data ~= "" then - local version = tonumber(data:match("^-- version: ([%d%.]+)")) + local version = tonumber(match(data,"^-- version: ([%d%.]+)")) if version ~= jobs.version then logs.report("job","version mismatch with jobfile: %s <> %s", version or "?", jobs.version) else diff --git a/tex/context/base/data-crl.lua b/tex/context/base/data-crl.lua index bc9ff98b5..55b1a8fad 100644 --- a/tex/context/base/data-crl.lua +++ b/tex/context/base/data-crl.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['data-crl'] = { license = "see context related readme files" } +local gsub = string.gsub + curl = curl or { } curl.cached = { } @@ -14,9 +16,9 @@ curl.cachepath = caches.definepath("curl") local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders function curl.fetch(protocol, name) - local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-") --- cachename = cachename:gsub("[\\/]", io.fileseparator) - cachename = cachename:gsub("[\\]", "/") -- cleanup + local cachename = curl.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") +-- cachename = gsub(cachename,"[\\/]", io.fileseparator) + cachename = gsub(cachename,"[\\]", "/") -- cleanup if not curl.cached[name] then if not io.exists(cachename) then curl.cached[name] = cachename diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index be4193e6a..67bb7cf88 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -36,6 +36,7 @@ if not modules then modules = { } end modules ['data-inp'] = { local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys local next, type = next, type +local lpegmatch = lpeg.match local trace_locating, trace_detail, trace_expansions = false, false, false @@ -813,7 +814,7 @@ function resolvers.generators.tex(specification) full = spec end for name in directory(full) do - if not weird:match(name) then + if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') if mode == 'file' then if path then @@ -1579,7 +1580,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- try to find in tree (no suffix manipulation), here we search for the -- matching last part of the name local basename = file.basename(filename) - local pattern = (filename .. "$"):gsub("([%.%-])","%%%1") + local pattern = gsub(filename .. "$","([%.%-])","%%%1") local savedformat = instance.format local format = savedformat or "" if format == "" then @@ -1600,7 +1601,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- for r=1,#resolved do local rr = resolved[r] - if rr:find(pattern) then + if find(rr,pattern) then result[#result+1], ok = rr, true end end @@ -1610,7 +1611,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan -- local filelist = collect_files({basename}) -- for f=1,#filelist do -- local ff = filelist[f][3] or "" - -- if ff:find(pattern) then + -- if find(ff,pattern) then -- result[#result+1], ok = ff, true -- end -- end @@ -2067,7 +2068,7 @@ function resolvers.with_files(pattern,handle) end function resolvers.locate_format(name) - local barename, fmtname = name:gsub("%.%a+$",""), "" + local barename, fmtname = gsub(name,"%.%a+$",""), "" if resolvers.usecache then local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" diff --git a/tex/context/base/data-tex.lua b/tex/context/base/data-tex.lua index e0f6c8019..0f2be3962 100644 --- a/tex/context/base/data-tex.lua +++ b/tex/context/base/data-tex.lua @@ -32,6 +32,7 @@ function finders.generic(tag,filename,filetype) end end +--~ local lpegmatch = lpeg.match --~ local getlines = lpeg.Ct(lpeg.linebyline) local input_translator, utf_translator, user_translator = nil, nil, nil @@ -102,7 +103,7 @@ function openers.text_opener(filename,file_handle,tag) logs.report("fileio","%s opener, file '%s' opened",tag,filename) end -- todo: file;name -> freeze / eerste regel scannen -> freeze - --~ local data = getlines:match(file_handle:read("*a")) + --~ local data = lpegmatch(getlines,file_handle:read("*a")) --~ local n = 0 t = { reader = function() -- self diff --git a/tex/context/base/data-tmf.lua b/tex/context/base/data-tmf.lua index e02f7f866..7421eacfc 100644 --- a/tex/context/base/data-tmf.lua +++ b/tex/context/base/data-tmf.lua @@ -6,19 +6,22 @@ if not modules then modules = { } end modules ['data-tmf'] = { license = "see context related readme files" } +local find, gsub, match = string.find, string.gsub, string.match +local getenv, setenv = os.getenv, os.setenv + -- loads *.tmf files in minimal tree roots (to be optimized and documented) function resolvers.check_environment(tree) logs.simpleline() - os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME')) - os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.platform)) - os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",'')) - os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS')) + setenv('TMP', getenv('TMP') or getenv('TEMP') or getenv('TMPDIR') or getenv('HOME')) + setenv('TEXOS', getenv('TEXOS') or ("texmf-" .. os.platform)) + setenv('TEXPATH', gsub(tree or "tex","\/+$",'')) + setenv('TEXMFOS', getenv('TEXPATH') .. "/" .. getenv('TEXOS')) logs.simpleline() - logs.simple("preset : TEXPATH => %s", os.getenv('TEXPATH')) - logs.simple("preset : TEXOS => %s", os.getenv('TEXOS')) - logs.simple("preset : TEXMFOS => %s", os.getenv('TEXMFOS')) - logs.simple("preset : TMP => %s", os.getenv('TMP')) + logs.simple("preset : TEXPATH => %s", getenv('TEXPATH')) + logs.simple("preset : TEXOS => %s", getenv('TEXOS')) + logs.simple("preset : TEXMFOS => %s", getenv('TEXMFOS')) + logs.simple("preset : TMP => %s", getenv('TMP')) logs.simple('') end @@ -26,27 +29,27 @@ function resolvers.load_environment(name) -- todo: key=value as well as lua local f = io.open(name) if f then for line in f:lines() do - if line:find("^[%%%#]") then + if find(line,"^[%%%#]") then -- skip comment else - local key, how, value = line:match("^(.-)%s*([<=>%?]+)%s*(.*)%s*$") + local key, how, value = match(line,"^(.-)%s*([<=>%?]+)%s*(.*)%s*$") if how then - value = value:gsub("%%(.-)%%", function(v) return os.getenv(v) or "" end) + value = gsub(value,"%%(.-)%%", function(v) return getenv(v) or "" end) if how == "=" or how == "<<" then - os.setenv(key,value) + setenv(key,value) elseif how == "?" or how == "??" then - os.setenv(key,os.getenv(key) or value) + setenv(key,getenv(key) or value) elseif how == "<" or how == "+=" then - if os.getenv(key) then - os.setenv(key,os.getenv(key) .. io.fileseparator .. value) + if getenv(key) then + setenv(key,getenv(key) .. io.fileseparator .. value) else - os.setenv(key,value) + setenv(key,value) end elseif how == ">" or how == "=+" then - if os.getenv(key) then - os.setenv(key,value .. io.pathseparator .. os.getenv(key)) + if getenv(key) then + setenv(key,value .. io.pathseparator .. getenv(key)) else - os.setenv(key,value) + setenv(key,value) end end end diff --git a/tex/context/base/data-tre.lua b/tex/context/base/data-tre.lua index 74630b69b..a56040ccc 100644 --- a/tex/context/base/data-tre.lua +++ b/tex/context/base/data-tre.lua @@ -8,6 +8,8 @@ if not modules then modules = { } end modules ['data-tre'] = { -- \input tree://oeps1/**/oeps.tex +local find, gsub = string.find, string.gsub + local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders local done, found = { }, { } @@ -25,9 +27,9 @@ function finders.tree(specification,filetype) hash = dir.glob(pattern) done[path] = hash end - local pattern = "/" .. name:gsub("([%.%-%+])", "%%%1") .. "$" + local pattern = "/" .. gsub(name,"([%.%-%+])", "%%%1") .. "$" for k, v in pairs(hash) do - if v:find(pattern) then + if find(v,pattern) then found[specification] = v return v end diff --git a/tex/context/base/data-use.lua b/tex/context/base/data-use.lua index 4e5aa553c..123cc0eb8 100644 --- a/tex/context/base/data-use.lua +++ b/tex/context/base/data-use.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['data-use'] = { license = "see context related readme files" } -local format, lower, gsub = string.format, string.lower, string.gsub +local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -62,9 +62,9 @@ function resolvers.automount(usecache) if f then for line in f:lines() do if line then - if line:find("^[%%#%-]") then -- or %W + if find(line,"^[%%#%-]") then -- or %W -- skip - elseif line:find("^zip://") then + elseif find(line,"^zip://") then if trace_locating then logs.report("fileio","mounting %s",line) end diff --git a/tex/context/base/data-zip.lua b/tex/context/base/data-zip.lua index 16d56ce8b..7d2fc8664 100644 --- a/tex/context/base/data-zip.lua +++ b/tex/context/base/data-zip.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['data-zip'] = { license = "see context related readme files" } -local format, find = string.format, string.find +local format, find, match = string.format, string.find, string.match local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -222,7 +222,7 @@ function resolvers.register_zip_file(z,tree) end local register, n = resolvers.register_file, 0 for i in z:files() do - local path, name = i.filename:match(filter) + local path, name = match(i.filename,filter) if path then if name and name ~= '' then register(files, name, path) diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua index 7ad3801dd..60da808bb 100644 --- a/tex/context/base/font-afm.lua +++ b/tex/context/base/font-afm.lua @@ -21,7 +21,8 @@ local trace_features = false trackers.register("afm.features", function(v) trac local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) -local format, match, gmatch, lower = string.format, string.match, string.gmatch, string.lower +local format, match, gmatch, lower, gsub = string.format, string.match, string.gmatch, string.lower, string.gsub +local lpegmatch = lpeg.match fonts = fonts or { } fonts.afm = fonts.afm or { } @@ -88,7 +89,7 @@ local pattern = ( c * s^1 * ( local function scan_comment(str) fd = { } - pattern:match(str) + lpegmatch(pattern,str) return fd end @@ -219,21 +220,21 @@ function afm.read_afm(filename) filename = file.removesuffix(file.basename(filename)) } } - afmblob = afmblob:gsub("StartCharMetrics(.-)EndCharMetrics", function(charmetrics) + afmblob = gsub(afmblob,"StartCharMetrics(.-)EndCharMetrics", function(charmetrics) if trace_loading then logs.report("load afm","loading char metrics") end get_charmetrics(data,charmetrics,vector) return "" end) - afmblob = afmblob:gsub("StartKernPairs(.-)EndKernPairs", function(kernpairs) + afmblob = gsub(afmblob,"StartKernPairs(.-)EndKernPairs", function(kernpairs) if trace_loading then logs.report("load afm","loading kern pairs") end get_kernpairs(data,kernpairs) return "" end) - afmblob = afmblob:gsub("StartFontMetrics%s+([%d%.]+)(.-)EndFontMetrics", function(version,fontmetrics) + afmblob = gsub(afmblob,"StartFontMetrics%s+([%d%.]+)(.-)EndFontMetrics", function(version,fontmetrics) if trace_loading then logs.report("load afm","loading variables") end diff --git a/tex/context/base/font-cid.lua b/tex/context/base/font-cid.lua index 57bfcd378..d1c727af2 100644 --- a/tex/context/base/font-cid.lua +++ b/tex/context/base/font-cid.lua @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['font-cid'] = { local format, match, lower = string.format, string.match, string.lower local tonumber = tonumber +local lpegmatch = lpeg.match local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -61,7 +62,7 @@ function fonts.cid.load(filename) local data = io.loaddata(filename) if data then unicodes, names = { }, { } - grammar:match(data) + lpegmatch(grammar,data) local supplement, registry, ordering = match(filename,"^(.-)%-(.-)%-()%.(.-)$") return { supplement = supplement, diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua index 596a4946c..d313357a2 100644 --- a/tex/context/base/font-col.lua +++ b/tex/context/base/font-col.lua @@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['font-col'] = { local format, gmatch, texsprint, type = string.format, string.gmatch, tex.sprint, type local traverse_id, first_character = node.traverse_id, node.first_character +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes @@ -166,7 +167,7 @@ function collections.prepare(name) local f = d[i] local name = f.font local scale = f.rscale or 1 - if okay:match(name) then + if lpegmatch(okay,name) then texsprint(ctxcatcodes,format("\\doclonefonta{%s}{%s}",name,scale)) -- define with unique specs else texsprint(ctxcatcodes,format("\\doclonefontb{%s}{%s}",name,scale)) -- define with inherited specs diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 2f63b3a8d..1233f075d 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['font-ctx'] = { local texsprint, count = tex.sprint, tex.count local format, concat, gmatch, match, find, lower, gsub = string.format, table.concat, string.gmatch, string.match, string.find, string.lower, string.gsub local tostring, next, type = tostring, next, type +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes @@ -48,7 +49,7 @@ name*context specification function specify.predefined(specification) local detail = specification.detail if detail ~= "" then - -- detail = detail:gsub("["..define.splitsymbols.."].*$","") -- get rid of *whatever specs and such + -- detail = gsub(detail,"["..define.splitsymbols.."].*$","") -- get rid of *whatever specs and such if define.methods[detail] then -- since these may be appended at the specification.features.vtf = { preset = detail } -- tex end by default end @@ -295,7 +296,7 @@ local get_specification = define.get_specification function define.command_1(str) statistics.starttiming(fonts) - local fullname, size = splitpattern:match(str) + local fullname, size = lpegmatch(splitpattern,str) local lookup, name, sub, method, detail = get_specification(fullname) if not name then logs.report("define font","strange definition '%s'",str) @@ -307,7 +308,7 @@ function define.command_1(str) end -- we can also use a count for the size if size and size ~= "" then - local mode, size = sizepattern:match(size) + local mode, size = lpegmatch(sizepattern,size) if size and mode then count.scaledfontmode = mode texsprint(ctxcatcodes,"\\def\\somefontsize{",size,"}") diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index 65c74d48f..9a007b991 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['font-def'] = { local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next +local lpegmatch = lpeg.match local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end) local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end) @@ -108,7 +109,7 @@ define.add_lookup("name") define.add_lookup("spec") function define.get_specification(str) - return splitter:match(str) + return lpegmatch(splitter,str) end function define.register_split(symbol,action) diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua index f13408efd..efbe50e89 100644 --- a/tex/context/base/font-ext.lua +++ b/tex/context/base/font-ext.lua @@ -100,6 +100,8 @@ only used with files.

--~ smallcaps = lpeg.Cs((1-smallcaps)^1) * smallcaps^1 --~ oldstyle = lpeg.Cs((1-oldstyle )^1) * oldstyle ^1 --~ +--~ local lpegmatch = lpeg.match +--~ --~ function initializers.common.encoding(tfmdata,value) --~ if value then --~ local afmdata = tfmdata.shared.afmdata @@ -111,7 +113,7 @@ only used with files.

--~ local characters = tfmdata.characters --~ local unicodes = afmdata.luatex.unicodes --~ local function remap(pattern,name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ local oldchr, newchr = unicodes[p], unicodes[name] --~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then @@ -145,7 +147,7 @@ only used with files.

--~ for u, _ in next, characters do --~ local name = descriptions[u].name --~ if name then ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ local oldchr, newchr = unicodes[p], unicodes[name] --~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then diff --git a/tex/context/base/font-map.lua b/tex/context/base/font-map.lua index 4cb4976db..9e85516d6 100644 --- a/tex/context/base/font-map.lua +++ b/tex/context/base/font-map.lua @@ -6,7 +6,8 @@ if not modules then modules = { } end modules ['font-map'] = { license = "see context related readme files" } -local match, format, find, concat = string.match, string.format, string.find, table.concat +local match, format, find, concat, gsub = string.match, string.format, string.find, table.concat, string.gsub +local lpegmatch = lpeg.match local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -88,7 +89,7 @@ function fonts.map.load_file(filename, entries, encodings) -- print(line) else local extend, slant, name, fullname, fontfile, encoding - line = line:gsub('"(.+)"', function(s) + line = gsub(line,'"(.+)"', function(s) extend = find(s,'"([^"]+) ExtendFont"') slant = find(s,'"([^"]+) SlantFont"') return "" @@ -169,7 +170,7 @@ end --~ local parser = fonts.map.make_name_parser("Japan1") --~ local parser = fonts.map.make_name_parser() --~ local function test(str) ---~ local b, a = parser:match(str) +--~ local b, a = lpegmatch(parser,str) --~ print((a and table.serialize(b)) or b) --~ end --~ test("a.sc") diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua index 2c809bc3d..043560565 100644 --- a/tex/context/base/font-mis.lua +++ b/tex/context/base/font-mis.lua @@ -11,7 +11,7 @@ local lower, strip = string.lower, string.strip fonts.otf = fonts.otf or { } -fonts.otf.version = fonts.otf.version or 2.641 +fonts.otf.version = fonts.otf.version or 2.642 fonts.otf.pack = true fonts.otf.cache = containers.define("fonts", "otf", fonts.otf.version, true) diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua index 127d4c218..675c124e1 100644 --- a/tex/context/base/font-otb.lua +++ b/tex/context/base/font-otb.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['font-otb'] = { local concat = table.concat local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match local otf = fonts.otf local tfm = fonts.tfm @@ -69,7 +70,7 @@ local function resolve_ligatures(tfmdata,ligatures,kind) for k,v in next, ligatures do local lig = v[1] if not done[lig] then - local ligs = split_at_space:match(lig) + local ligs = lpegmatch(split_at_space,lig) if #ligs == 2 then local uc = v[2] local c, f, s = characters[uc], ligs[1], ligs[2] @@ -177,9 +178,84 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod local characters = tfmdata.characters local descriptions = tfmdata.descriptions local changed = tfmdata.changed + -- + local actions = { + substitution = function(p,lookup,k,glyph,unicode) + local pv = p[2] -- p.variant + if pv then + local upv = unicodes[pv] + if upv then + if type(upv) == "table" then + upv = upv[1] + end + if characters[upv] then + if trace_baseinit and trace_singles then + logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv)) + end + changed[k] = upv + end + end + end + end, + alternate = function(p,lookup,k,glyph,unicode) + local pc = p[2] -- p.components + if pc then + -- a bit optimized ugliness + if value == 1 then + pc = lpegmatch(splitter,pc) + elseif value == 2 then + local a, b = lpegmatch(splitter,pc) + pc = b or a + else + pc = { lpegmatch(splitter,pc) } + pc = pc[value] or pc[#pc] + end + if pc then + local upc = unicodes[pc] + if upc then + if type(upc) == "table" then + upc = upc[1] + end + if characters[upc] then + if trace_baseinit and trace_alternatives then + logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc)) + end + changed[k] = upc + end + end + end + end + end, + ligature = function(p,lookup,k,glyph,unicode) + local pc = p[2] + if pc then + if trace_baseinit and trace_ligatures then + local upc = { lpegmatch(splitter,pc) } + for i=1,#upc do upc[i] = unicodes[upc[i]] end + -- we assume that it's no table + logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k)) + end + ligatures[#ligatures+1] = { pc, k } + end + end, + } + -- for k,c in next, characters do local glyph = descriptions[k] - local lookups = glyph.lookups + local lookups = glyph.slookups + if lookups then + for l=1,#lookuplist do + local lookup = lookuplist[l] + local p = lookups[lookup] + if p then + local a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) + end + end + end + end + local lookups = glyph.mlookups if lookups then for l=1,#lookuplist do local lookup = lookuplist[l] @@ -187,62 +263,9 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod if ps then for i=1,#ps do local p = ps[i] - local t = p[1] - if t == 'substitution' then - local pv = p[2] -- p.variant - if pv then - local upv = unicodes[pv] - if upv then - if type(upv) == "table" then - upv = upv[1] - end - if characters[upv] then - if trace_baseinit and trace_singles then - logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv)) - end - changed[k] = upv - end - end - end - elseif t == 'alternate' then - local pc = p[2] -- p.components - if pc then - -- a bit optimized ugliness - if value == 1 then - pc = splitter:match(pc) - elseif value == 2 then - local a, b = splitter:match(pc) - pc = b or a - else - pc = { splitter:match(pc) } - pc = pc[value] or pc[#pc] - end - if pc then - local upc = unicodes[pc] - if upc then - if type(upc) == "table" then - upc = upc[1] - end - if characters[upc] then - if trace_baseinit and trace_alternatives then - logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc)) - end - changed[k] = upc - end - end - end - end - elseif t == 'ligature' and not changed[k] then - local pc = p[2] - if pc then - if trace_baseinit and trace_ligatures then - local upc = { splitter:match(pc) } - for i=1,#upc do upc[i] = unicodes[upc[i]] end - -- we assume that it's no table - logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k)) - end - ligatures[#ligatures+1] = { pc, k } - end + local a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) end end end diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index e2f0f5b62..bf5acadcd 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -11,6 +11,7 @@ local utf = unicode.utf8 local concat, getn, utfbyte = table.concat, table.getn, utf.byte local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match local trace_private = false trackers.register("otf.private", function(v) trace_private = v end) local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -83,7 +84,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.641 -- beware: also sync font-mis.lua +otf.version = 2.642 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -207,6 +208,7 @@ local enhancers = { "reorganize mark classes", "reorganize kerns", -- moved here "flatten glyph lookups", "flatten anchor tables", "flatten feature tables", + "simplify glyph lookups", -- some saving "prepare luatex tables", "analyse features", "rehash features", "analyse anchors", "analyse marks", "analyse unicodes", "analyse subtables", @@ -503,11 +505,11 @@ local separator = lpeg.S("_.") local other = lpeg.C((1 - separator)^1) local ligsplitter = lpeg.Ct(other * (separator * other)^0) ---~ print(table.serialize(ligsplitter:match("this"))) ---~ print(table.serialize(ligsplitter:match("this.that"))) ---~ print(table.serialize(ligsplitter:match("japan1.123"))) ---~ print(table.serialize(ligsplitter:match("such_so_more"))) ---~ print(table.serialize(ligsplitter:match("such_so_more.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"japan1.123"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more.that"))) otf.enhancers["analyse unicodes"] = function(data,filename) local tounicode16, tounicode16sequence = fonts.map.tounicode16, fonts.map.tounicode16sequence @@ -545,13 +547,13 @@ otf.enhancers["analyse unicodes"] = function(data,filename) -- cidmap heuristics, beware, there is no guarantee for a match unless -- the chain resolves if (not unicode) and usedmap then - local foundindex = oparser:match(name) + local foundindex = lpegmatch(oparser,name) if foundindex then unicode = cidcodes[foundindex] -- name to number if not unicode then local reference = cidnames[foundindex] -- number to name if reference then - local foundindex = oparser:match(reference) + local foundindex = lpegmatch(oparser,reference) if foundindex then unicode = cidcodes[foundindex] if unicode then @@ -559,7 +561,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end end if not unicode then - local foundcodes, multiple = uparser:match(reference) + local foundcodes, multiple = lpegmatch(uparser,reference) if foundcodes then if multiple then originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true @@ -574,7 +576,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end -- a.whatever or a_b_c.whatever or a_b_c (no numbers) if not unicode then - local split = ligsplitter:match(name) + local split = lpegmatch(ligsplitter,name) local nplit = (split and #split) or 0 if nplit == 0 then -- skip @@ -607,7 +609,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end -- last resort if not unicode then - local foundcodes, multiple = uparser:match(name) + local foundcodes, multiple = lpegmatch(uparser,name) if foundcodes then if multiple then originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true @@ -1193,8 +1195,9 @@ end otf.enhancers["flatten glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do - if v.lookups then - for kk, vv in next, v.lookups do + local lookups = v.lookups + if lookups then + for kk, vv in next, lookups do for kkk=1,#vv do local vvv = vv[kkk] local s = vvv.specification @@ -1244,6 +1247,31 @@ otf.enhancers["flatten glyph lookups"] = function(data,filename) end end +otf.enhancers["simplify glyph lookups"] = function(data,filename) + for k, v in next, data.glyphs do + local lookups = v.lookups + if lookups then + local slookups, mlookups + for kk, vv in next, lookups do + if #vv == 1 then + if not slookups then + slookups = { } + v.slookups = slookups + end + slookups[kk] = vv[1] + else + if not mlookups then + mlookups = { } + v.mlookups = mlookups + end + mlookups[kk] = vv + end + end + v.lookups = nil + end + end +end + otf.enhancers["flatten anchor tables"] = function(data,filename) for k, v in next, data.glyphs do if v.anchors then @@ -1484,7 +1512,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th local variants = m.horiz_variants if variants then local c = char - for n in variants:gmatch("[^ ]+") do + for n in gmatch(variants,"[^ ]+") do local un = unicodes[n] if un and u ~= un then c.next = un @@ -1496,7 +1524,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th local variants = m.vert_variants if variants then local c = char - for n in variants:gmatch("[^ ]+") do + for n in gmatch(variants,"[^ ]+") do local un = unicodes[n] if un and u ~= un then c.next = un diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index e58d7730d..efafa30c6 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -2275,142 +2275,153 @@ local function prepare_lookups(tfmdata) -- we can change the otf table after loading but then we need to adapt base mode -- as well (no big deal) -- - for unicode, glyph in next, descriptions do - local lookups = glyph.lookups - if lookups then - for lookup, whatever in next, lookups do - for i=1,#whatever do -- normaly one - local p = whatever[i] - local what = p[1] - if what == 'substitution' then - local old, new = unicode, unicodes[p[2]] - if type(new) == "table" then - new = new[1] - end - local s = single[lookup] - if not s then s = { } single[lookup] = s end - s[old] = new ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new) ---~ end - break - elseif what == 'multiple' then - local old, new = unicode, { } - local m = multiple[lookup] - if not m then m = { } multiple[lookup] = m end - m[old] = new - for pc in gmatch(p[2],"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - new[#new+1] = upc - else - new[#new+1] = upc[1] - end - end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," ")) ---~ end + local action = { + substitution = function(p,lookup,k,glyph,unicode) + local old, new = unicode, unicodes[p[2]] + if type(new) == "table" then + new = new[1] + end + local s = single[lookup] + if not s then s = { } single[lookup] = s end + s[old] = new + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new) + --~ end + end, + multiple = function (p,lookup,k,glyph,unicode) + local old, new = unicode, { } + local m = multiple[lookup] + if not m then m = { } multiple[lookup] = m end + m[old] = new + for pc in gmatch(p[2],"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + new[#new+1] = upc + else + new[#new+1] = upc[1] + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," ")) + --~ end + end, + alternate = function(p,lookup,k,glyph,unicode) + local old, new = unicode, { } + local a = alternate[lookup] + if not a then a = { } alternate[lookup] = a end + a[old] = new + for pc in gmatch(p[2],"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + new[#new+1] = upc + else + new[#new+1] = upc[1] + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|")) + --~ end + end, + ligature = function (p,lookup,k,glyph,unicode) + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name) + --~ end + local first = true + local t = ligature[lookup] + if not t then t = { } ligature[lookup] = t end + for s in gmatch(p[2],"[^ ]+") do + if first then + local u = unicodes[s] + if not u then + logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name) break - elseif what == 'alternate' then - local old, new = unicode, { } - local a = alternate[lookup] - if not a then a = { } alternate[lookup] = a end - a[old] = new - for pc in gmatch(p[2],"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - new[#new+1] = upc - else - new[#new+1] = upc[1] - end + elseif type(u) == "number" then + if not t[u] then + t[u] = { { } } end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|")) ---~ end - break - elseif what == "ligature" then ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name) ---~ end - local first = true - local t = ligature[lookup] - if not t then t = { } ligature[lookup] = t end - for s in gmatch(p[2],"[^ ]+") do - if first then - local u = unicodes[s] - if not u then - logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name) - break - elseif type(u) == "number" then - if not t[u] then - t[u] = { { } } - end - t = t[u] - else - local tt = t - local tu - for i=1,#u do - local u = u[i] - if i==1 then - if not t[u] then - t[u] = { { } } - end - tu = t[u] - t = tu - else - if not t[u] then - tt[u] = tu - end - end - end + t = t[u] + else + local tt = t + local tu + for i=1,#u do + local u = u[i] + if i==1 then + if not t[u] then + t[u] = { { } } end - first = false + tu = t[u] + t = tu else - s = unicodes[s] - local t1 = t[1] - if not t1[s] then - t1[s] = { { } } + if not t[u] then + tt[u] = tu end - t = t1[s] end end - t[2] = unicode - elseif what == 'position' then - -- not used - local s = position[lookup] - if not s then s = { } position[lookup] = s end - s[unicode] = p[2] -- direct pointer to kern spec - elseif what == 'pair' then - local s = pair[lookup] - if not s then s = { } pair[lookup] = s end - local others = s[unicode] - if not others then others = { } s[unicode] = others end - -- todo: fast check for space - local two = p[2] - local upc = unicodes[two] - if not upc then - for pc in gmatch(two,"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - others[upc] = p -- direct pointer to main table - else - for i=1,#upc do - others[upc[i]] = p -- direct pointer to main table - end - end - end - elseif type(upc) == "number" then - others[upc] = p -- direct pointer to main table - else - for i=1,#upc do - others[upc[i]] = p -- direct pointer to main table - end + end + first = false + else + s = unicodes[s] + local t1 = t[1] + if not t1[s] then + t1[s] = { { } } + end + t = t1[s] + end + end + t[2] = unicode + end, + position = function(p,lookup,k,glyph,unicode) + -- not used + local s = position[lookup] + if not s then s = { } position[lookup] = s end + s[unicode] = p[2] -- direct pointer to kern spec + end, + pair = function(p,lookup,k,glyph,unicode) + local s = pair[lookup] + if not s then s = { } pair[lookup] = s end + local others = s[unicode] + if not others then others = { } s[unicode] = others end + -- todo: fast check for space + local two = p[2] + local upc = unicodes[two] + if not upc then + for pc in gmatch(two,"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + others[upc] = p -- direct pointer to main table + else + for i=1,#upc do + others[upc[i]] = p -- direct pointer to main table end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode) ---~ end end end + elseif type(upc) == "number" then + others[upc] = p -- direct pointer to main table + else + for i=1,#upc do + others[upc[i]] = p -- direct pointer to main table + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode) + --~ end + end, + } + -- + for unicode, glyph in next, descriptions do + local lookups = glyph.slookups + if lookups then + for lookup, p in next, lookups do + action[p[1]](p,lookup,k,glyph,unicode) + end + end + local lookups = glyph.mlookups + if lookups then + for lookup, whatever in next, lookups do + for i=1,#whatever do -- normaly one + local p = whatever[i] + action[p[1]](p,lookup,k,glyph,unicode) + end end end local list = glyph.mykerns @@ -2419,9 +2430,9 @@ local function prepare_lookups(tfmdata) local k = kerns[lookup] if not k then k = { } kerns[lookup] = k end k[unicode] = krn -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode) + --~ end end end local oanchor = glyph.anchors @@ -2435,9 +2446,9 @@ local function prepare_lookups(tfmdata) local f = mark[lookup] if not f then f = { } mark[lookup] = f end f[unicode] = anchors -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode) + --~ end end end end @@ -2449,9 +2460,9 @@ local function prepare_lookups(tfmdata) local f = cursive[lookup] if not f then f = { } cursive[lookup] = f end f[unicode] = anchors -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode) + --~ end end end end diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua index 3cdc80737..6c4ad0f8c 100644 --- a/tex/context/base/font-otp.lua +++ b/tex/context/base/font-otp.lua @@ -98,7 +98,13 @@ function fonts.otf.enhancers.pack(data) local pack = (pass == 1 and pack_1) or pack_2 for k, v in next, data.glyphs do v.boundingbox = pack(v.boundingbox) - local l = v.lookups + local l = v.slookups + if l then + for k,v in next, l do + l[k] = pack(v) + end + end + local l = v.mlookups if l then for k,v in next, l do for kk=1,#v do @@ -250,7 +256,7 @@ function fonts.otf.enhancers.pack(data) if a then v.anchors = pack(a) end - local l = v.lookups + local l = v.mlookups if l then for k,v in next, l do for kk=1,#v do @@ -279,7 +285,13 @@ function fonts.otf.enhancers.unpack(data) if t then for k, v in next, data.glyphs do local tv = t[v.boundingbox] if tv then v.boundingbox = tv end - local l = v.lookups + local l = v.slookups + if l then + for k,v in next, l do + local tv = t[v] if tv then l[k] = tv end + end + end + local l = v.mlookups if l then for k,v in next, l do for i=1,#v do @@ -418,3 +430,208 @@ function fonts.otf.enhancers.unpack(data) end end end + + + +function fonts.otf.enhancers.unpack(data) + if data then + local t = data.tables + if t then + local unpacked = { } + for k, v in next, data.glyphs do + local tv = t[v.boundingbox] if tv then v.boundingbox = tv end + local l = v.slookups + if l then + for k,v in next, l do + local tv = t[v] if tv then l[k] = tv end + end + end + local l = v.mlookups + if l then + for k,v in next, l do + for i=1,#v do + local vi = v[i] + local tv = t[vi] + if tv then + v[i] = tv + if unpacked[tv] then + vi = false + else + unpacked[tv], vi = true, tv + end + end + if vi then + local what = vi[1] + if what == "pair" then + local tv = t[vi[3]] if tv then vi[3] = tv end + local tv = t[vi[4]] if tv then vi[4] = tv end + elseif what == "position" then + local tv = t[vi[2]] if tv then vi[2] = tv end + end + end + end + end + end + local m = v.mykerns + if m then + local tm = t[m] + if tm then + v.mykerns = tm + if unpacked[tm] then + m = false + else + unpacked[tm], m = true, tm + end + end + if m then + for k,v in next, m do + local tv = t[v] if tv then m[k] = tv end + end + end + end + local m = v.math + if m then + local mk = m.kerns + if mk then + local tm = t[mk] + if tm then + m.kerns = tm + if unpacked[tm] then + mk = false + else + unpacked[tm], mk = true, tm + end + end + if mk then + for k,v in next, mk do + local tv = t[v] if tv then mk[k] = tv end + end + end + end + end + local a = v.anchors + if a then + local ta = t[a] + if ta then + v.anchors = ta + if not unpacked[ta] then + unpacked[ta], a = true, ta + else + a = false + end + end + if a then + for k,v in next, a do + if k == "baselig" then + for kk, vv in next, v do + for kkk=1,#vv do + local tv = t[vv[kkk]] if tv then vv[kkk] = tv end + end + end + else + for kk, vv in next, v do + local tv = t[vv] if tv then v[kk] = tv end + end + end + end + end + end + end + if data.lookups then + for k, v in next, data.lookups do + local r = v.rules + if r then + for kk, vv in next, r do + local l = vv.lookups + if l then + local tv = t[l] if tv then vv.lookups = tv end + end + local c = vv.coverage + if c then + local cc = c.before if cc then local tv = t[cc] if tv then c.before = tv end end + cc = c.after if cc then local tv = t[cc] if tv then c.after = tv end end + cc = c.current if cc then local tv = t[cc] if tv then c.current = tv end end + end + local c = vv.reversecoverage + if c then + local cc = c.before if cc then local tv = t[cc] if tv then c.before = tv end end + cc = c.after if cc then local tv = t[cc] if tv then c.after = tv end end + cc = c.current if cc then local tv = t[cc] if tv then c.current = tv end end + end + end + end + end + end + local luatex = data.luatex + if luatex then + local la = luatex.anchor_to_lookup + if la then + for lookup, ldata in next, la do + local tv = t[ldata] if tv then la[lookup] = tv end + end + end + local la = luatex.lookup_to_anchor + if la then + for lookup, ldata in next, la do + local tv = t[ldata] if tv then la[lookup] = tv end + end + end + local ls = luatex.sequences + if ls then + for feature, fdata in next, ls do + local flags = fdata.flags + if flags then + local tv = t[flags] if tv then fdata.flags = tv end + end + local subtables = fdata.subtables + if subtables then + local tv = t[subtables] if tv then fdata.subtables = tv end + end + local features = fdata.features + if features then + local tv = t[features] + if tv then + fdata.features = tv + if not unpacked[tv] then + unpacked[tv], features = true, tv + else + features = false + end + end + if features then + for script, sdata in next, features do + local tv = t[sdata] if tv then features[script] = tv end + end + end + end + end + end + local ls = luatex.lookups + if ls then + for lookups, fdata in next, ls do + local flags = fdata.flags + if flags then + local tv = t[flags] if tv then fdata.flags = tv end + end + local subtables = fdata.subtables + if subtables then + local tv = t[subtables] if tv then fdata.subtables = tv end + end + end + end + local lf = luatex.features + if lf then + for _, g in next, fonts.otf.glists do + local gl = lf[g] + if gl then + for feature, spec in next, gl do + local tv = t[spec] if tv then gl[feature] = tv end + end + end + end + end + end + data.tables = nil + end + end +end diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index 9f84c2637..a3b61af31 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -12,6 +12,7 @@ local next, tonumber = next, tonumber local gsub, lower, match, find, lower, upper = string.gsub, string.lower, string.match, string.find, string.lower, string.upper local find, gmatch = string.find, string.gmatch local concat, sort, format = table.concat, table.sort, string.format +local lpegmatch = lpeg.match local trace_names = false trackers.register("fonts.names", function(v) trace_names = v end) local trace_warnings = false trackers.register("fonts.warnings", function(v) trace_warnings = v end) @@ -106,10 +107,10 @@ local analyser = Cs ( local splitter = lpeg.splitat("-") function names.splitspec(askedname) - local name, weight, style, width = splitter:match(askedname) - weight = weight and weights:match(weight) or weight - style = style and styles :match(style) or style - width = width and widths :match(width) or width + local name, weight, style, width = lpegmatch(splitter,askedname) + weight = weight and lpegmatch(weights,weight) or weight + style = style and lpegmatch(styles, style) or style + width = width and lpegmatch(widths, width) or width if trace_names then logs.report("fonts","requested name '%s' split in name '%s', weight '%s', style '%s' and width '%s'",askedname,name or '',weight or '',style or '',width or '') end @@ -125,7 +126,7 @@ end local function analysespec(somename) if somename then analysed_table = { } - local name = analyser:match(somename) + local name = lpegmatch(analyser,somename) return name, analysed_table[1], analysed_table[2],analysed_table[3] end end diff --git a/tex/context/base/font-xtx.lua b/tex/context/base/font-xtx.lua index 8aecae8d9..574221b5d 100644 --- a/tex/context/base/font-xtx.lua +++ b/tex/context/base/font-xtx.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['font-xtx'] = { local texsprint, count = tex.sprint, tex.count local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next +local lpegmatch = lpeg.match local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) @@ -88,7 +89,7 @@ local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0 function fonts.define.specify.colonized(specification) -- xetex mode list = { } - pattern:match(specification.specification) + lpegmatch(pattern,specification.specification) for k, v in next, list do list[k] = v:is_boolean() if type(list[a]) == "nil" then diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index 5d2f1bab7..d605168c8 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -33,7 +33,8 @@ The TeX-Lua mix is suboptimal. This has to do with the fact that we cannot run TeX code from within Lua. Some more functionality will move to Lua. ]]-- -local texsprint, format, lower, find, match = tex.sprint, string.format, string.lower, string.find, string.match +local format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch +local texsprint = tex.sprint local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables @@ -70,7 +71,7 @@ local validtypes = table.tohash(img.types()) function img.check_size(size) if size then - size = size:gsub("box","") + size = gsub(size,"box","") return (validsizes[size] and size) or "crop" else return "crop" @@ -184,7 +185,7 @@ function figures.setpaths(locationset,pathlist) last_locationset = locationset end if h[iv["global"]] then - for s in pathlist:gmatch("([^, ]+)") do + for s in gmatch(pathlist,"([^, ]+)") do if not table.contains(t,s) then t[#t+1] = s end diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua index 9e3679bbf..f64a8a18f 100644 --- a/tex/context/base/java-ini.lua +++ b/tex/context/base/java-ini.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['java-ini'] = { } local format = string.format +local lpegmatch = lpeg.match javascripts = javascripts or { } javascripts.codes = javascripts.codes or { } @@ -42,18 +43,18 @@ local parsepreamble = name * ((used * name) + lpeg.Cc("")) * spaces * script local parsefunctions = (fname + any)^0 function javascripts.storecode(str) - local name, uses, script = parsecode:match(str) + local name, uses, script = lpegmatch(parsecode,str) if name and name ~= "" then javascripts.codes[name] = { uses, script } end end function javascripts.storepreamble(str) -- now later - local name, used, script = parsepreamble:match(str) + local name, used, script = lpegmatch(parsepreamble,str) if name and name ~= "" then preambles[#preambles+1] = { name, used, script } preambled[name] = #preambles - parsefunctions:match(script) + lpegmatch(parsefunctions,script) end end @@ -61,7 +62,7 @@ function javascripts.setpreamble(name,script) -- now later if name and name ~= "" then preambles[#preambles+1] = { name, "now", script } preambled[name] = #preambles - parsefunctions:match(script) + lpegmatch(parsefunctions,script) end end @@ -73,7 +74,7 @@ function javascripts.addtopreamble(name,script) -- now later else preambles[#preambles+1] = { name, "now", script } preambled[name] = #preambles - parsefunctions:match(script) + lpegmatch(parsefunctions,script) end end end diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua index e422a2313..1ff5c086e 100644 --- a/tex/context/base/l-aux.lua +++ b/tex/context/base/l-aux.lua @@ -10,6 +10,7 @@ aux = aux or { } local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type = tostring, type +local lpegmatch = lpeg.match local space = lpeg.P(' ') local equal = lpeg.P("=") @@ -59,9 +60,9 @@ function aux.settings_to_hash(str,existing) if str and str ~= "" then hash = existing or { } if moretolerant then - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) else - pattern_a_s:match(str) + lpegmatch(pattern_a_s,str) end return hash else @@ -72,7 +73,7 @@ end function aux.settings_to_hash_tolerant(str,existing) if str and str ~= "" then hash = existing or { } - pattern_b_s:match(str) + lpegmatch(pattern_b_s,str) return hash else return { } @@ -82,7 +83,7 @@ end function aux.settings_to_hash_strict(str,existing) if str and str ~= "" then hash = existing or { } - pattern_c_s:match(str) + lpegmatch(pattern_c_s,str) return next(hash) and hash else return nil @@ -101,7 +102,7 @@ function aux.settings_to_array(str) if not str or str == "" then return { } else - return pattern:match(str) + return lpegmatch(pattern,str) end end @@ -113,7 +114,7 @@ local value = lpeg.P(lpeg.Carg(1)*value) / set local pattern = value*(separator*value)^0 * lpeg.Carg(1) function aux.add_settings_to_array(t,str) - return pattern:match(str, nil, t) + return lpegmatch(pattern,str,nil,t) end function aux.hash_to_string(h,separator,yes,no,strict,omit) @@ -165,7 +166,7 @@ local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace local pattern = lpeg.Ct((space + value)^0) function aux.arguments_to_table(str) - return pattern:match(str) + return lpegmatch(pattern,str) end -- temporary here @@ -201,11 +202,11 @@ local stripper = lpeg.Cs((number + 1)^0) --~ collectgarbage("collect") --~ str = string.rep(sample,10000) --~ local ts = os.clock() ---~ stripper:match(str) ---~ print(#str, os.clock()-ts, stripper:match(sample)) +--~ lpegmatch(stripper,str) +--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) function aux.strip_zeros(str) - return stripper:match(str) + return lpegmatch(stripper,str) end function aux.definetable(target) -- defines undefined tables diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua index 00e96586f..e15e29463 100644 --- a/tex/context/base/l-dimen.lua +++ b/tex/context/base/l-dimen.lua @@ -16,6 +16,7 @@ table.

--ldx]]-- local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable +local lpegmatch = lpeg.match number = number or { } @@ -145,7 +146,7 @@ function string:todimen() if type(self) == "number" then return self else - local value, unit = pattern:match(self) + local value, unit = lpegmatch(pattern,self) print(value,unit) return value/unit end @@ -193,7 +194,7 @@ function dimen(a) if a then local ta= type(a) if ta == "string" then - local value, unit = pattern:match(a) + local value, unit = lpegmatch(pattern,a) if type(unit) == "function" then k = value/unit() else @@ -360,7 +361,7 @@ function dimen(a) if k then a = k else - local value, unit = pattern:match(a) + local value, unit = lpegmatch(pattern,a) if type(unit) == "function" then k = value/unit() else @@ -384,7 +385,7 @@ function string:todimen() else local k = known[self] if not k then - local value, unit = pattern:match(self) + local value, unit = lpegmatch(pattern,self) if value and unit then k = value/unit else diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua index 7ee565b30..3760db2c1 100644 --- a/tex/context/base/l-dir.lua +++ b/tex/context/base/l-dir.lua @@ -7,7 +7,8 @@ if not modules then modules = { } end modules ['l-dir'] = { } local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } @@ -100,14 +101,14 @@ local function glob(str,t) t[#t+1] = str return t else - local split = pattern:match(str) + local split = lpegmatch(pattern,str) if split then 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 start = root .. path - local result = filter:match(start .. base) + local result = lpegmatch(filter,start .. base) glob_pattern(start,result,recurse,action) return t else @@ -188,13 +189,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -202,11 +203,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -241,33 +242,33 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("a/bbb//ccc/")) function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then first = lfs.currentdir() - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end lfs.chdir(d) end end if not first then first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first = gsub(first,"\\","/") end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -288,7 +289,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -326,8 +327,8 @@ else if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua index be42727c0..c95ef658c 100644 --- a/tex/context/base/l-file.lua +++ b/tex/context/base/l-file.lua @@ -11,7 +11,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -69,12 +70,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -149,27 +150,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -178,7 +179,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -189,9 +190,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -200,11 +201,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -238,11 +239,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -255,7 +256,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua index 0d0357039..5a126da7b 100644 --- a/tex/context/base/l-io.lua +++ b/tex/context/base/l-io.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -164,7 +164,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -177,7 +177,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index d1e0dfafb..9e761e4b3 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -61,15 +62,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -100,7 +101,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -113,7 +114,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) diff --git a/tex/context/base/l-md5.lua b/tex/context/base/l-md5.lua index 8640ad54e..27955ef9b 100644 --- a/tex/context/base/l-md5.lua +++ b/tex/context/base/l-md5.lua @@ -57,7 +57,7 @@ end function file.loadchecksum(name) if md5 then local data = io.loaddata(name .. ".md5") - return data and data:gsub("%s","") + return data and (gsub(data,"%s","")) end return nil end diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua index 39ca2c6b6..a1249f055 100644 --- a/tex/context/base/l-number.lua +++ b/tex/context/base/l-number.lua @@ -6,14 +6,16 @@ if not modules then modules = { } end modules ['l-number'] = { license = "see context related readme files" } -local format, foor, insert = string.format, math.floor, table.insert +local tostring = tostring +local format, floor, insert, match = string.format, math.floor, table.insert, string.match +local lpegmatch = lpeg.match number = number or { } -- a,b,c,d,e,f = number.toset(100101) function number.toset(n) - return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") + return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)") end function number.toevenhex(n) @@ -39,7 +41,7 @@ end local one = lpeg.C(1-lpeg.S(''))^1 function number.toset(n) - return one:match(tostring(n)) + return lpegmatch(one,tostring(n)) end function number.bits(n,zero) diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua index d9ae41af7..25b8f8e98 100644 --- a/tex/context/base/l-string.lua +++ b/tex/context/base/l-string.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['l-string'] = { } local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match -- some functions may disappear as they are not used anywhere @@ -77,9 +78,19 @@ function string:limit(n,sentinel) end end -function string:strip() -- the .- is quite efficient --- return match(self,"^%s*(.-)%s*$") or "" - return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -216,7 +227,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua index 5d899e69e..1d282a178 100644 --- a/tex/context/base/l-url.lua +++ b/tex/context/base/l-url.lua @@ -6,8 +6,9 @@ if not modules then modules = { } end modules ['l-url'] = { license = "see context related readme files" } -local char, gmatch = string.char, string.gmatch +local char, gmatch, gsub = string.char, string.gmatch, string.gsub local tonumber, type = tonumber, type +local lpegmatch = lpeg.match -- from the spec (on the web): -- @@ -40,7 +41,7 @@ local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0 local parser = lpeg.Ct(scheme * authority * path * query * fragment) function url.split(str) - return (type(str) == "string" and parser:match(str)) or str + return (type(str) == "string" and lpegmatch(parser,str)) or str end function url.hashed(str) @@ -57,7 +58,7 @@ end function url.filename(filename) local t = url.hashed(filename) - return (t.scheme == "file" and t.path:gsub("^/([a-zA-Z])([:|])/)","%1:")) or filename + return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename end function url.query(str) diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua index 313381065..a5bc9d796 100644 --- a/tex/context/base/l-utils.lua +++ b/tex/context/base/l-utils.lua @@ -8,6 +8,9 @@ if not modules then modules = { } end modules ['l-utils'] = { -- hm, quite unreadable +local gsub = string.gsub +local concat = table.concat + if not utils then utils = { } end if not utils.merger then utils.merger = { } end if not utils.lua then utils.lua = { } end @@ -45,7 +48,7 @@ function utils.merger._self_load_(name) end if data and utils.merger.strip_comment then -- saves some 20K - data = data:gsub("%-%-~[^\n\r]*[\r\n]", "") + data = gsub(data,"%-%-~[^\n\r]*[\r\n]", "") end return data or "" end @@ -63,7 +66,7 @@ end function utils.merger._self_swap_(data,code) if data ~= "" then - return (data:gsub(utils.merger.pattern, function(s) + return (gsub(data,utils.merger.pattern, function(s) return "\n\n" .. "-- "..utils.merger.m_begin .. "\n" .. code .. "\n" .. "-- "..utils.merger.m_end .. "\n\n" end, 1)) else @@ -73,8 +76,8 @@ end --~ stripper: --~ ---~ data = string.gsub(data,"%-%-~[^\n]*\n","") ---~ data = string.gsub(data,"\n\n+","\n") +--~ data = gsub(data,"%-%-~[^\n]*\n","") +--~ data = gsub(data,"\n\n+","\n") function utils.merger._self_libs_(libs,list) local result, f, frozen = { }, nil, false @@ -84,7 +87,7 @@ function utils.merger._self_libs_(libs,list) local foundpath = nil for _, lib in ipairs(libs) do for _, pth in ipairs(list) do - pth = string.gsub(pth,"\\","/") -- file.clean_path + pth = gsub(pth,"\\","/") -- file.clean_path utils.report("checking library path %s",pth) local name = pth .. "/" .. lib if lfs.isfile(name) then @@ -110,15 +113,15 @@ function utils.merger._self_libs_(libs,list) end end if #right > 0 then - utils.report("merged libraries: %s",table.concat(right," ")) + utils.report("merged libraries: %s",concat(right," ")) end if #wrong > 0 then - utils.report("skipped libraries: %s",table.concat(wrong," ")) + utils.report("skipped libraries: %s",concat(wrong," ")) end else utils.report("no valid library path found") end - return table.concat(result, "\n\n") + return concat(result, "\n\n") end function utils.merger.selfcreate(libs,list,target) diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua index c251ab1a6..505c0a00e 100644 --- a/tex/context/base/lang-ini.lua +++ b/tex/context/base/lang-ini.lua @@ -10,8 +10,9 @@ if not modules then modules = { } end modules ['lang-ini'] = { local utf = unicode.utf8 -local find, lower, format, utfchar = string.find, string.lower, string.format, utf.char +local find, lower, format, match, utfchar = string.find, string.lower, string.format, string.match, utf.char local concat = table.concat +local lpegmatch = lpeg.match if lang.use_new then lang.use_new(true) end @@ -36,8 +37,8 @@ local langdata = languages.hyphenation.data --~ local function filter(filename,what) --~ local data = io.loaddata(resolvers.find_file(filename)) ---~ local data = data:match(string.format("\\%s%%s*(%%b{})",what or "patterns")) ---~ return data:match("{%s*(.-)%s*}") or "" +--~ local data = match(data,string.format("\\%s%%s*(%%b{})",what or "patterns")) +--~ return match(data,"{%s*(.-)%s*}") or "" --~ end -- loading the 26 languages that we normally load in mkiv, the string based variant @@ -59,7 +60,7 @@ local function filterpatterns(filename) if find(filename,"%.rpl") then return io.loaddata(resolvers.find_file(filename)) or "" else - return parser:match(io.loaddata(resolvers.find_file(filename)) or "") + return lpegmatch(parser,io.loaddata(resolvers.find_file(filename)) or "") end end @@ -70,7 +71,7 @@ local function filterexceptions(filename) if find(filename,"%.rhl") then return io.loaddata(resolvers.find_file(filename)) or "" else - return parser:match(io.loaddata(resolvers.find_file(filename)) or {}) -- "" ? + return lpegmatch(parser,io.loaddata(resolvers.find_file(filename)) or {}) -- "" ? end end @@ -304,7 +305,7 @@ do local data = io.loaddata(filename) or "" local words = languages.words.data[tag] or {} parser = (spacing + word/function(s) words[s] = true end)^0 - parser:match(data) + lpegmatch(parser,data) languages.words.data[tag] = words statistics.stoptiming(languages) end diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua index b0823b478..9c82d04ac 100644 --- a/tex/context/base/lpdf-fld.lua +++ b/tex/context/base/lpdf-fld.lua @@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['lpdf-fld'] = { -- some optimizations removed (will come bakc if needed) local gmatch, lower, format = string.gmatch, string.lower, string.format +local lpegmatch = lpeg.match local trace_fields = false trackers.register("widgets.fields", function(v) trace_fields = v end) @@ -237,12 +238,12 @@ local function fieldstates(specification,forceyes,values,default) else yes, off = v[1], v[2] end - local yesshown, yesvalue = splitter:match(yes) + local yesshown, yesvalue = lpegmatch(splitter,yes) if not (yesshown and yesvalue) then yesshown = yes, yes end yes = aux.settings_to_array(yesshown) - local offshown, offvalue = splitter:match(off) + local offshown, offvalue = lpegmatch(splitter,off) if not (offshown and offvalue) then offshown = off, off end @@ -293,7 +294,7 @@ local function fieldoptions(specification) local v = aux.settings_to_array(values) for i=1,#v do local vi = v[i] - local shown, value = splitter:match(vi) + local shown, value = lpegmatch(splitter,vi) if shown and value then v[i] = pdfarray { pdfunicode(value), shown } else @@ -364,7 +365,7 @@ end local function predefinesymbols(specification) local values = specification.values if values then - local a, b = splitter:match(values) + local a, b = lpegmatch(splitter,values) codeinjections.presetsymbollist(a or values) end end @@ -375,7 +376,7 @@ function codeinjections.getdefaultfieldvalue(name) local values = f.values local default = f.default if not default or default == "" then - local a, b = splitter:match(values) + local a, b = lpegmatch(splitter,values) values = a or values for name in gmatch(list,"[^, ]+") do default = name diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index 437fa4c8a..d71bfc6d7 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -13,6 +13,7 @@ local char, byte, format, gsub, concat = string.char, string.byte, string.format local utfvalues = string.utfvalues local texwrite = tex.write local sind, cosd = math.sind, math.cosd +local lpegmatch = lpeg.match local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) @@ -54,7 +55,7 @@ local function toeight(str) -- if not str or str == "" then -- return "()" -- else - -- return escaped:match(str) + -- return lpegmatch(escaped,str) -- end -- -- no need for escaping .. just use unicode instead @@ -71,7 +72,7 @@ local function cleaned(str) if not str or str == "" then return "()" else - return escaped:match(str) + return lpegmatch(escaped,str) end end diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua index bbb00509a..ae132e4e6 100644 --- a/tex/context/base/luat-cnf.lua +++ b/tex/context/base/luat-cnf.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['luat-cnf'] = { license = "see context related readme files" } -local format, concat = string.format, table.concat +local format, concat, find = string.format, table.concat, string.find luatex = luatex or { } @@ -26,7 +26,7 @@ function luatex.variables() local t, x = { }, nil for _,v in next, luatex.variablenames do x = resolvers.var_value(v) - if x and x:find("^%d+$") then + if x and find(x,"^%d+$") then t[v] = tonumber(x) end end diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua index f06e61867..0be764e7c 100644 --- a/tex/context/base/luat-env.lua +++ b/tex/context/base/luat-env.lua @@ -14,7 +14,8 @@ if not modules then modules = { } end modules ['luat-env'] = { local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) -local format = string.format +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquote, quote = string.unquote, string.quote -- precautions @@ -50,11 +51,11 @@ function environment.initialize_arguments(arg) environment.arguments, environment.files, environment.sortedflags = arguments, files, nil for index, argument in pairs(arg) do if index > 0 then - local flag, value = argument:match("^%-+(.-)=(.-)$") + local flag, value = match(argument,"^%-+(.-)=(.-)$") if flag then - arguments[flag] = string.unquote(value or "") + arguments[flag] = unquote(value or "") else - flag = argument:match("^%-+(.+)") + flag = match(argument,"^%-+(.+)") if flag then arguments[flag] = true else @@ -89,8 +90,8 @@ function environment.argument(name,partial) end -- example of potential clash: ^mode ^modefile for _,v in ipairs(sortedflags) do - if name:find(v) then - return arguments[v:sub(2,#v)] + if find(name,v) then + return arguments[sub(v,2,#v)] end end end @@ -116,16 +117,16 @@ function environment.reconstruct_commandline(arg,noquote) if noquote and #arg == 1 then local a = arg[1] a = resolvers.resolve(a) - a = a:unquote() + a = unquote(a) return a elseif next(arg) then local result = { } for _,a in ipairs(arg) do -- ipairs 1 .. #n a = resolvers.resolve(a) - a = a:unquote() - a = a:gsub('"','\\"') -- tricky - if a:find(" ") then - result[#result+1] = a:quote() + a = unquote(a) + a = gsub(a,'"','\\"') -- tricky + if find(a," ") then + result[#result+1] = quote(a) else result[#result+1] = a end @@ -142,13 +143,13 @@ if arg then local newarg, instring = { }, false for index, argument in ipairs(arg) do - if argument:find("^\"") then - newarg[#newarg+1] = argument:gsub("^\"","") - if not argument:find("\"$") then + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then instring = true end - elseif argument:find("\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","") + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") instring = false elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument diff --git a/tex/context/base/luat-exe.lua b/tex/context/base/luat-exe.lua index 721e90c73..10cb6678b 100644 --- a/tex/context/base/luat-exe.lua +++ b/tex/context/base/luat-exe.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['luat-exe'] = { license = "see context related readme files" } +local match, find = string.match, string.find +local concat = table.concat + if not executer then executer = { } end executer.permitted = { } @@ -24,18 +27,18 @@ function executer.finalize() -- todo: os.exec, todo: report ipv print local t, name, arguments = {...}, "", "" if #t == 1 then if type(t[1]) == 'table' then - name, arguments = t[1], table.concat(t," ",2,#t) + name, arguments = t[1], concat(t," ",2,#t) else - name, arguments = t[1]:match("^(.-)%s+(.+)$") + name, arguments = match(t[1],"^(.-)%s+(.+)$") if not (name and arguments) then name, arguments = t[1], "" end end else - name, arguments = t[1], table.concat(t," ",2,#t) + name, arguments = t[1], concat(t," ",2,#t) end for _,v in pairs(executer.permitted) do - if name:find(v) then + if find(name,v) then execute(name .. " " .. arguments) -- print("executed: " .. name .. " " .. arguments) else diff --git a/tex/context/base/luat-sta.lua b/tex/context/base/luat-sta.lua index 12fa18219..cc78851a9 100644 --- a/tex/context/base/luat-sta.lua +++ b/tex/context/base/luat-sta.lua @@ -7,6 +7,9 @@ if not modules then modules = { } end modules ['luat-sta'] = { -- this code is used in the updater +local gmatch, match = string.gmatch, string.match +local type = type + states = states or { } states.data = states.data or { } states.hash = states.hash or { } @@ -35,9 +38,9 @@ function states.set_by_tag(tag,key,value,default,persistent) if d then if type(d) == "table" then local dkey, hkey = key, key - local pre, post = key:match("(.+)%.([^%.]+)$") + local pre, post = match(key,"(.+)%.([^%.]+)$") if pre and post then - for k in pre:gmatch("[^%.]+") do + for k in gmatch(pre,"[^%.]+") do local dk = d[k] if not dk then dk = { } @@ -69,7 +72,7 @@ function states.get_by_tag(tag,key,default) else local d = states.data[tag] if d then - for k in key:gmatch("[^%.]+") do + for k in gmatch(key,"[^%.]+") do local dk = d[k] if dk then d = dk diff --git a/tex/context/base/lxml-ctx.lua b/tex/context/base/lxml-ctx.lua index 0ac12ab3c..d6aeca8d4 100644 --- a/tex/context/base/lxml-ctx.lua +++ b/tex/context/base/lxml-ctx.lua @@ -11,7 +11,6 @@ if not modules then modules = { } end modules ['lxml-ctx'] = { xml.ctx = { } xml.ctx.enhancers = { } - -- hashen function xml.ctx.enhancers.compound(root,lpath,before,tokens,after) -- todo lpeg @@ -48,13 +47,18 @@ function xml.ctx.tshow(specification) context[titlecommand]("pattern: " .. pattern) end context.starttabulate({ "|Tr|Tl|Tp|" } ) - if specification.warning and parsed.comment then - context.NC() - context("!") - context.NC() - context.rlap(parsed.comment) - context.NR() - context.TB() + if specification.warning then + local comment = parsed.comment + if comment then + for k, v in ipairs(comment) do + context.NC() + context("!") + context.NC() + context.rlap(v) + context.NR() + end + context.TB() + end end for p=1,#parsed do local pp = parsed[p] @@ -73,8 +77,8 @@ function xml.ctx.tshow(specification) context(pp.expression) elseif kind == "finalizer" then context("%s(%s)",pp.name,pp.arguments) - elseif kind == "error" and pp.comment then - context(pp.comment) + elseif kind == "error" and pp.error then + context(pp.error) end context.NC() context.NR() diff --git a/tex/context/base/lxml-ent.lua b/tex/context/base/lxml-ent.lua index ee6077a76..193611937 100644 --- a/tex/context/base/lxml-ent.lua +++ b/tex/context/base/lxml-ent.lua @@ -11,6 +11,7 @@ local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local utf = unicode.utf8 local byte, format = string.byte, string.format local utfupper, utfchar = utf.upper, utf.char +local lpegmatch = lpeg.match --[[ldx--

We provide (at least here) two entity handlers. The more extensive @@ -52,7 +53,7 @@ function xml.resolved_entity(str) else -- resolve hex and dec, todo: escape # & etc for ctxcatcodes -- normally this is already solved while loading the file - local chr, err = parsedentity:match(str) + local chr, err = lpegmatch(parsedentity,str) if chr then texsprint(ctxcatcodes,chr) elseif err then diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv index 90e60d513..ac30cd129 100644 --- a/tex/context/base/lxml-ini.mkiv +++ b/tex/context/base/lxml-ini.mkiv @@ -63,6 +63,8 @@ \def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}} \def\xmlnonspace #1#2{\ctxlua{lxml.nonspace("#1","#2")}} \def\xmlraw #1#2{\ctxlua{lxml.raw("#1","#2")}} +\def\xmlcontext #1#2{\ctxlua{lxml.context("#1","#2")}} +\def\xmlflushcontext #1{\ctxlua{lxml.context("#1")}} \def\xmlsnippet #1#2{\ctxlua{lxml.snippet("#1",#2)}} \def\xmlelement #1#2{\ctxlua{lxml.element("#1",#2)}} \def\xmlregisterns #1#2{\ctxlua{xml.registerns("#1","#2")}} % document diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua index 936288d34..8f7d60d9e 100644 --- a/tex/context/base/lxml-lpt.lua +++ b/tex/context/base/lxml-lpt.lua @@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['lxml-pth'] = { local concat, remove, insert = table.concat, table.remove, table.insert local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep +local lpegmatch = lpeg.match -- beware, this is not xpath ... e.g. position is different (currently) and -- we have reverse-sibling as reversed preceding sibling @@ -508,8 +509,7 @@ local cleaner local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * value / function(t,s) if expressions[t] then - s = s and s ~= "" and cleaner:match(s) ---~ print("!!!",t,s) + s = s and s ~= "" and lpegmatch(cleaner,s) if s and s ~= "" then return "expr." .. t .. "(ll," .. s ..")" else @@ -566,6 +566,31 @@ local template_f_n = [[ -- +local register_self = { kind = "axis", axis = "self" } -- , apply = apply_axis["self"] } +local register_parent = { kind = "axis", axis = "parent" } -- , apply = apply_axis["parent"] } +local register_descendant = { kind = "axis", axis = "descendant" } -- , apply = apply_axis["descendant"] } +local register_child = { kind = "axis", axis = "child" } -- , apply = apply_axis["child"] } +local register_descendant_or_self = { kind = "axis", axis = "descendant-or-self" } -- , apply = apply_axis["descendant-or-self"] } +local register_root = { kind = "axis", axis = "root" } -- , apply = apply_axis["root"] } +local register_ancestor = { kind = "axis", axis = "ancestor" } -- , apply = apply_axis["ancestor"] } +local register_ancestor_or_self = { kind = "axis", axis = "ancestor-or-self" } -- , apply = apply_axis["ancestor-or-self"] } +local register_attribute = { kind = "axis", axis = "attribute" } -- , apply = apply_axis["attribute"] } +local register_namespace = { kind = "axis", axis = "namespace" } -- , apply = apply_axis["namespace"] } +local register_following = { kind = "axis", axis = "following" } -- , apply = apply_axis["following"] } +local register_following_sibling = { kind = "axis", axis = "following-sibling" } -- , apply = apply_axis["following-sibling"] } +local register_preceding = { kind = "axis", axis = "preceding" } -- , apply = apply_axis["preceding"] } +local register_preceding_sibling = { kind = "axis", axis = "preceding-sibling" } -- , apply = apply_axis["preceding-sibling"] } +local register_reverse_sibling = { kind = "axis", axis = "reverse-sibling" } -- , apply = apply_axis["reverse-sibling"] } + +local register_auto_descendant_or_self = { kind = "axis", axis = "auto-descendant-or-self" } -- , apply = apply_axis["auto-descendant-or-self"] } +local register_auto_descendant = { kind = "axis", axis = "auto-descendant" } -- , apply = apply_axis["auto-descendant"] } +local register_auto_self = { kind = "axis", axis = "auto-self" } -- , apply = apply_axis["auto-self"] } +local register_auto_child = { kind = "axis", axis = "auto-child" } -- , apply = apply_axis["auto-child"] } + +local register_initial_child = { kind = "axis", axis = "initial-child" } -- , apply = apply_axis["initial-child"] } + +local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } } + local function errorrunner_e(str,cnv) logs.report("lpath","error in expression: %s => %s",str,cnv) return false @@ -580,7 +605,7 @@ local function register_nodes(nodetest,nodes) end local function register_expression(expression) - local converted = converter:match(expression) + local converted = lpegmatch(converter,expression) local runner = loadstring(format(template_e,converted)) runner = (runner and runner()) or function() errorrunner_e(expression,converted) end return { kind = "expression", expression = expression, converted = converted, evaluator = runner } @@ -612,39 +637,22 @@ local arguments = P { "ar", -- todo: better arg parser -local register_self = { kind = "axis", axis = "self" } -- , apply = apply_axis["self"] } -local register_parent = { kind = "axis", axis = "parent" } -- , apply = apply_axis["parent"] } -local register_descendant = { kind = "axis", axis = "descendant" } -- , apply = apply_axis["descendant"] } -local register_child = { kind = "axis", axis = "child" } -- , apply = apply_axis["child"] } -local register_descendant_or_self = { kind = "axis", axis = "descendant-or-self" } -- , apply = apply_axis["descendant-or-self"] } -local register_root = { kind = "axis", axis = "root" } -- , apply = apply_axis["root"] } -local register_ancestor = { kind = "axis", axis = "ancestor" } -- , apply = apply_axis["ancestor"] } -local register_ancestor_or_self = { kind = "axis", axis = "ancestor-or-self" } -- , apply = apply_axis["ancestor-or-self"] } -local register_attribute = { kind = "axis", axis = "attribute" } -- , apply = apply_axis["attribute"] } -local register_namespace = { kind = "axis", axis = "namespace" } -- , apply = apply_axis["namespace"] } -local register_following = { kind = "axis", axis = "following" } -- , apply = apply_axis["following"] } -local register_following_sibling = { kind = "axis", axis = "following-sibling" } -- , apply = apply_axis["following-sibling"] } -local register_preceding = { kind = "axis", axis = "preceding" } -- , apply = apply_axis["preceding"] } -local register_preceding_sibling = { kind = "axis", axis = "preceding-sibling" } -- , apply = apply_axis["preceding-sibling"] } -local register_reverse_sibling = { kind = "axis", axis = "reverse-sibling" } -- , apply = apply_axis["reverse-sibling"] } - -local register_auto_descendant_or_self = { kind = "axis", axis = "auto-descendant-or-self" } -- , apply = apply_axis["auto-descendant-or-self"] } -local register_auto_descendant = { kind = "axis", axis = "auto-descendant" } -- , apply = apply_axis["auto-descendant"] } -local register_auto_self = { kind = "axis", axis = "auto-self" } -- , apply = apply_axis["auto-self"] } -local register_auto_child = { kind = "axis", axis = "auto-child" } -- , apply = apply_axis["auto-child"] } - -local register_initial_child = { kind = "axis", axis = "initial-child" } -- , apply = apply_axis["initial-child"] } - -local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } } - local function register_error(str) - return { kind = "error", comment = format("unparsed: %s",str) } + return { kind = "error", error = format("unparsed: %s",str) } end +-- there is a difference in * and /*/ and so we need to catch a few special cases + +local special_1 = P("*") * Cc(register_auto_descendant) * Cc(register_all_nodes) -- last one not needed +local special_2 = P("/") * Cc(register_auto_self) +local special_3 = P("") * Cc(register_auto_self) + local parser = Ct { "patterns", -- can be made a bit faster by moving pattern outside - patterns = spaces * V("protocol") * spaces * V("initial") * spaces * V("step") * spaces * - (P("/") * spaces * V("step") * spaces)^0, + patterns = spaces * V("protocol") * spaces * ( + ( V("special") * spaces * P(-1) ) + + ( V("initial") * spaces * V("step") * spaces * (P("/") * spaces * V("step") * spaces)^0 ) + ), protocol = Cg(V("letters"),"protocol") * P("://") + Cg(Cc(nil),"protocol"), @@ -657,6 +665,8 @@ local parser = Ct { "patterns", -- can be made a bit faster by moving pattern ou V("reverse_sibling") + V("preceding_sibling") + V("preceding") + V("ancestor_or_self") + #(1-P(-1)) * Cc(register_auto_child), + special = special_1 + special_2 + special_3, + initial = (P("/") * spaces * Cc(register_initial_child))^-1, error = (P(1)^1) / register_error, @@ -668,7 +678,8 @@ local parser = Ct { "patterns", -- can be made a bit faster by moving pattern ou s_descendant_or_self = (P("***/") + P("/")) * Cc(register_descendant_or_self), --- *** is a bonus -- s_descendant_or_self = P("/") * Cc(register_descendant_or_self), s_descendant = P("**") * Cc(register_descendant), - s_child = P("*") * #(1-P(":")) * Cc(register_child ), + s_child = P("*") * #(1-P(":")) * Cc(register_child ), +-- s_child = P("*") * #(P("/")+P(-1)) * Cc(register_child ), s_parent = P("..") * Cc(register_parent ), s_self = P("." ) * Cc(register_self ), s_root = P("^^") * Cc(register_root ), @@ -744,6 +755,8 @@ end xml.nodesettostring = nodesettostring +local parse_pattern -- we have a harmless kind of circular reference + local function lshow(parsed) if type(parsed) == "string" then parsed = parse_pattern(parsed) @@ -756,7 +769,16 @@ end xml.lshow = lshow -local function parse_pattern(pattern) -- the gain of caching is rather minimal +local function add_comment(p,str) + local pc = p.comment + if not pc then + p.comment = { str } + else + pc[#pc+1] = str + end +end + +parse_pattern = function (pattern) -- the gain of caching is rather minimal lpathcalls = lpathcalls + 1 if type(pattern) == "table" then return pattern @@ -765,7 +787,7 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal if parsed then lpathcached = lpathcached + 1 else - parsed = parser:match(pattern) + parsed = lpegmatch(parser,pattern) if parsed then parsed.pattern = pattern local np = #parsed @@ -774,18 +796,32 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal logs.report("lpath","parsing error in '%s'",pattern) lshow(parsed) else - -- we could have done this with a more complex parsed but this + -- we could have done this with a more complex parser but this -- is cleaner local pi = parsed[1] if pi.axis == "auto-child" then - parsed.comment = "auto-child replaced by auto-descendant-or-self" - parsed[1] = register_auto_descendant_or_self - --~ parsed.comment = "auto-child replaced by auto-descendant" - --~ parsed[1] = register_auto_descendant + if false then + add_comment(parsed, "auto-child replaced by auto-descendant-or-self") + parsed[1] = register_auto_descendant_or_self + else + add_comment(parsed, "auto-child replaced by auto-descendant") + parsed[1] = register_auto_descendant + end elseif pi.axis == "initial-child" and np > 1 and parsed[2].axis then - parsed.comment = "initial-child removed" -- we could also make it a auto-self + add_comment(parsed, "initial-child removed") -- we could also make it a auto-self remove(parsed,1) end +local np = #parsed -- can have changed +if np > 1 then + local pnp = parsed[np] + if pnp.kind == "nodes" and pnp.nodetest == true then + local nodes = pnp.nodes + if nodes[1] == true and nodes[2] == false and nodes[3] == false then + add_comment(parsed, "redundant final wildcard filter removed") + remove(parsed,np) + end + end +end end else parsed = { pattern = pattern } diff --git a/tex/context/base/lxml-mis.lua b/tex/context/base/lxml-mis.lua index 864ab75a1..480253205 100644 --- a/tex/context/base/lxml-mis.lua +++ b/tex/context/base/lxml-mis.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['lxml-mis'] = { local concat = table.concat local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring -local format, gsub = string.format, string.gsub +local format, gsub, match = string.format, string.gsub, string.match +local lpegmatch = lpeg.match --[[ldx--

The following helper functions best belong to the lxml-ini @@ -82,9 +83,9 @@ xml.escaped_pattern = escaped xml.unescaped_pattern = unescaped xml.cleansed_pattern = cleansed -function xml.escaped (str) return escaped :match(str) end -function xml.unescaped(str) return unescaped:match(str) end -function xml.cleansed (str) return cleansed :match(str) end +function xml.escaped (str) return lpegmatch(escaped,str) end +function xml.unescaped(str) return lpegmatch(unescaped,str) end +function xml.cleansed (str) return lpegmatch(cleansed,str) end -- this might move diff --git a/tex/context/base/lxml-sor.lua b/tex/context/base/lxml-sor.lua index f2bb756f2..daeb9ec7b 100644 --- a/tex/context/base/lxml-sor.lua +++ b/tex/context/base/lxml-sor.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['lxml-sor'] = { } local format, concat = string.format, table.concat +local lpegmatch = lpeg.match local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes lxml.sorters = lxml.sorters or { } @@ -14,7 +15,7 @@ lxml.sorters = lxml.sorters or { } if not lxml.splitid then local splitter = lpeg.C((1-lpeg.P(":"))^1) * lpeg.P("::") * lpeg.C(lpeg.P(1)^1) function lxml.splitid(id) - local d, i = splitter:match(id) + local d, i = lpegmatch(splitter,id) if d then return d, i else diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua index f38e5ad89..f4ab351e8 100644 --- a/tex/context/base/lxml-tab.lua +++ b/tex/context/base/lxml-tab.lua @@ -30,8 +30,9 @@ xml = xml or { } local concat, remove, insert = table.concat, table.remove, table.insert local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber -local format, lower, find = string.format, string.lower, string.find +local format, lower, find, match = string.format, string.lower, string.find, string.match local utfchar = unicode.utf8.char +local lpegmatch = lpeg.match --[[ldx--

First a hack to enable namespace resolving. A namespace is characterized by @@ -71,7 +72,7 @@ xml.checkns("m","http://www.w3.org/mathml") --ldx]]-- function xml.checkns(namespace,url) - local ns = parse:match(lower(url)) + local ns = lpegmatch(parse,lower(url)) if ns and namespace ~= ns then xml.xmlns[namespace] = ns end @@ -89,7 +90,7 @@ This returns mml. --ldx]]-- function xml.resolvens(url) - return parse:match(lower(url)) or "" + return lpegmatch(parse,lower(url)) or "" end --[[ldx-- @@ -356,7 +357,7 @@ local function handle_any_entity(str) if trace_entities then logs.report("xml","resolved entity &%s; -> %s (internal)",str,a) end - a = parsedentity:match(a) or a + a = lpegmatch(parsedentity,a) or a else if xml.unknown_any_entity_format then a = xml.unknown_any_entity_format(str) or "" @@ -535,13 +536,13 @@ local function xmlconvert(data, settings) if not data or data == "" then errorstr = "empty xml file" elseif utfize or resolve then - if grammar_parsed_text:match(data) then + if lpegmatch(grammar_parsed_text,data) then errorstr = "" else errorstr = "invalid xml file - parsed text" end else - if grammar_unparsed_text:match(data) then + if lpegmatch(grammar_unparsed_text,data) then errorstr = "" else errorstr = "invalid xml file - unparsed text" @@ -592,7 +593,7 @@ function xml.is_valid(root) end function xml.package(tag,attributes,data) - local ns, tg = tag:match("^(.-):?([^:]+)$") + local ns, tg = match(tag,"^(.-):?([^:]+)$") local t = { ns = ns, tg = tg, dt = data or "", at = attributes or {} } setmetatable(t, mt) return t diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index 1f0a5d3d2..9726a5661 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -10,8 +10,9 @@ local utf = unicode.utf8 local utfchar = utf.char local concat, insert, remove, gsub, find = table.concat, table.insert, table.remove -local format, sub, gsub, find, gmatch = string.format, string.sub, string.gsub, string.find, string.gmatch +local format, sub, gsub, find, gmatch, match = string.format, string.sub, string.gsub, string.find, string.gmatch, string.match local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match if not tex and not tex.sprint then tex = { @@ -79,6 +80,13 @@ local xmltextcapture = ( entity / xml.resolved_entity )^0 +local ctxtextcapture = ( + space^0 * newline^2 * lpeg.Cc("") / texprint + -- better ^-2 ? + space^0 * newline * space^0 * lpeg.Cc(" ") / texsprint + + content / function(str) return texsprint(ctxcatcodes,str) end + -- was just texsprint, current catcodes regime is notcatcodes + entity / xml.resolved_entity +)^0 + local forceraw, rawroot = false, nil function lxml.startraw() @@ -127,7 +135,7 @@ local xmlverbosecapture = ( local function toverbatim(str) if beforecommand then texsprint(texcatcodes,beforecommand,"{}") end - xmlverbosecapture:match(str) + lpegmatch(xmlverbosecapture,str) if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end end @@ -156,7 +164,7 @@ function lxml.toverbatim(str) -- todo: add this to capture str = gsub(str,"^[ \t]+[\n\r]+","") str = gsub(str,"[ \t\n\r]+$","") - xmlverbosecapture:match(str) + lpegmatch(xmlverbosecapture,str) if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end end @@ -176,7 +184,7 @@ local splitter = lpeg.splitat("::") lxml.idsplitter = splitter function lxml.splitid(id) - local d, i = splitter:match(id) + local d, i = lpegmatch(splitter,id) if d then return d, i else @@ -192,7 +200,7 @@ local function get_id(id, qualified) elseif type(id) == "table" then return id else - local d, i = splitter:match(id) + local d, i = lpegmatch(splitter,id) if d then local ld = loaded[d] if ld then @@ -299,7 +307,7 @@ function lxml.checkindex(name) end function lxml.withindex(name,n,command) -- will change as name is always there now - local i, p = splitter:match(n) + local i, p = lpegmatch(splitter,n) if p then texsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}") else @@ -308,7 +316,7 @@ function lxml.withindex(name,n,command) -- will change as name is always there n end function lxml.getindex(name,n) -- will change as name is always there now - local i, p = splitter:match(n) + local i, p = lpegmatch(splitter,n) if p then texsprint(ctxcatcodes,n) else @@ -484,9 +492,9 @@ local value = lpeg.C(lpeg.P(1-(space * -1))^0) local parser = kind * spaces * class * spaces * key * spaces * value pihandlers[#pihandlers+1] = function(str) --- local kind, class, key, value = parser:match(str) +-- local kind, class, key, value = lpegmatch(parser,str) if str then - local a, b, c, d = parser:match(str) + local a, b, c, d = lpegmatch(parser,str) if d then texsprint(ctxcatcodes,"\\xmlcontextdirective{",a",}{",b,"}{",c,"}{",d,"}") end @@ -506,8 +514,12 @@ local function tex_cdata(e,handlers) end end -local function tex_text(e,handlers) - xmltextcapture:match(e) +local function tex_text(e) + lpegmatch(xmltextcapture,e) +end + +local function ctx_text(e) + lpegmatch(ctxtextcapture,e) end local function tex_handle(...) @@ -548,7 +560,7 @@ local function sprint(root) local tr = type(root) if tr == "string" then -- can also be result of lpath -- rawroot = false - xmltextcapture:match(root) + lpegmatch(xmltextcapture,root) elseif tr == "table" then if forceraw then rawroot = root @@ -572,7 +584,7 @@ local function tprint(root) -- we can move sprint inline end end elseif tr == "string" then - xmltextcapture:match(root) + lpegmatch(xmltextcapture,root) end end @@ -582,7 +594,7 @@ local function cprint(root) -- content -- quit elseif type(root) == 'string' then -- rawroot = false - xmltextcapture:match(root) + lpegmatch(xmltextcapture,root) else local rootdt = root.dt if forceraw then @@ -616,7 +628,7 @@ end --~ --~ local xmllineshandler = table.copy(xmltexhandler) --~ ---~ xmllineshandler.handle = function(...) xmllinescapture:match(concat{ ... }) end +--~ xmllineshandler.handle = function(...) lpegmatch(xmllinescapture,concat{ ... }) end --~ --~ function lines(root) --~ if not root then @@ -624,7 +636,7 @@ end --~ -- quit --~ elseif type(root) == 'string' then --~ -- rawroot = false ---~ xmllinescapture:match(root) +--~ lpegmatch(xmllinescapture,root) --~ elseif next(root) then -- tr == 'table' --~ xmlserialize(root,xmllineshandler) --~ end @@ -782,7 +794,7 @@ function lxml.setsetup(id,pattern,setup) logs.report("lxml","no lpath matches for %s",pattern) end else - local a, b = setup:match("^(.+:)([%*%-])$") + local a, b = match(setup,"^(.+:)([%*%-])$") if a and b then local collected = lxmlparseapply(id,pattern) if collected then @@ -1140,6 +1152,19 @@ function lxml.raw(id,pattern) -- the content, untouched by commands end end +function lxml.context(id,pattern) -- the content, untouched by commands + if not pattern then + local collected = get_id(id) + -- texsprint(ctxcatcodes,collected.dt[1]) + ctx_text(collected.dt[1]) + else + local collected = lxmlparseapply(id,pattern) or get_id(id) + if collected then + texsprint(ctxcatcodes,collected[1].dt) + end + end +end + function lxml.text(id,pattern) local collected = (pattern and lxmlparseapply(id,pattern)) or get_id(id) if collected then diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua index b33d65bd9..23f8d4de0 100644 --- a/tex/context/base/meta-pdf.lua +++ b/tex/context/base/meta-pdf.lua @@ -10,10 +10,10 @@ if not modules then modules = { } end modules ['meta-pdf'] = { -- meta-pdh.lua but since we no longer want to overload functione we use -- more locals now. This module keeps changing as it is also a testbed. -local concat, format, gsub, find = table.concat, string.format, string.gsub, string.find -local byte, round = string.byte, math.round -local texsprint = tex.sprint -local ctxcatcodes = tex.ctxcatcodes +local concat, format, gsub, find, byte, gmatch, match = table.concat, string.format, string.gsub, string.find, string.byte, string.gmatch, string.match +local lpegmatch = lpeg.match +local round = math.round +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes local pdfrgbcode = lpdf.rgbcode local pdfcmykcode = lpdf.cmykcode @@ -390,7 +390,7 @@ local text = lpegCc("{") * ( local package = lpegCs(spec + text^0) function mps.fshow(str,font,scale) -- lpeg parser - mps.textext(font,scale,package:match(str)) + mps.textext(font,scale,lpegmatch(package,str)) end local cnumber = lpegC(number) @@ -510,9 +510,9 @@ local captures_new = ( space + verbose + procset + preamble )^0 local function parse(m_data) if find(m_data,"%%%%BeginResource: procset mpost") then - captures_new:match(m_data) + lpegmatch(captures_new,m_data) else - captures_old:match(m_data) + lpegmatch(captures_old,m_data) end end diff --git a/tex/context/base/meta-pdh.lua b/tex/context/base/meta-pdh.lua index f6fbbce5a..407b7e5e6 100644 --- a/tex/context/base/meta-pdh.lua +++ b/tex/context/base/meta-pdh.lua @@ -22,10 +22,10 @@ if not modules then modules = { } end modules ['meta-pdf'] = { -- only needed for mp output on disk -local concat, format = table.concat, string.format - -local texsprint = tex.sprint -local ctxcatcodes = tex.ctxcatcodes +local concat, format, find, gsub, gmatch = table.concat, string.format, string.find, string.gsub, string.gmatch +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local tostring, tonumber, select = tostring, tonumber, select +local lpegmatch = lpeg.match mptopdf = { } mptopdf.parsers = { } @@ -70,65 +70,65 @@ mptopdf.descapes = { } function mptopdf.descape(str) - str = str:gsub("\\(%d%d%d)",function(n) + str = gsub(str,"\\(%d%d%d)",function(n) return "\\char" .. tonumber(n,8) .. " " end) - return str:gsub("\\([%(%)\\])",mptopdf.descapes) + return gsub(str,"\\([%(%)\\])",mptopdf.descapes) end function mptopdf.steps.descape(str) - str = str:gsub("\\(%d%d%d)",function(n) + str = gsub(str,"\\(%d%d%d)",function(n) return "\\\\char" .. tonumber(n,8) .. " " end) - return str:gsub("\\([%(%)\\])",mptopdf.descapes) + return gsub(str,"\\([%(%)\\])",mptopdf.descapes) end function mptopdf.steps.strip() -- .3 per expr - mptopdf.data = mptopdf.data:gsub("^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic) + mptopdf.data = gsub(mptopdf.data,"^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic) local bbox = "0 0 0 0" - for b in preamble:gmatch("%%%%%a+oundingBox: +(.-)%c+") do + for b in gmatch(preamble,"%%%%%a+oundingBox: +(.-)%c+") do bbox = b end - local name, version = preamble:gmatch("%%%%Creator: +(.-) +(.-) ") + local name, version = gmatch(preamble,"%%%%Creator: +(.-) +(.-) ") mptopdf.version = tostring(version or "0") - if preamble:find("/hlw{0 dtransform") then + if find(preamble,"/hlw{0 dtransform") then mptopdf.shortcuts = true end -- the boundingbox specification needs to come before data, well, not really return bbox .. " boundingbox\n" .. "\nbegindata\n" .. graphic .. "\nenddata\n" end, 1) - mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1) - mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n") - mptopdf.data = mptopdf.data:gsub("%%.-%c+", "") + mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1) + mptopdf.data = gsub(mptopdf.data,"%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n") + mptopdf.data = gsub(mptopdf.data,"%%.-%c+", "") end function mptopdf.steps.cleanup() if not mptopdf.shortcuts then - mptopdf.data = mptopdf.data:gsub("gsave%s+fill%s+grestore%s+stroke", "both") - mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy) + mptopdf.data = gsub(mptopdf.data,"gsave%s+fill%s+grestore%s+stroke", "both") + mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy) if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end end) - mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy) + mptopdf.data = gsub(mptopdf.data,"([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy) if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end end) end end function mptopdf.steps.convert() - mptopdf.data = mptopdf.data:gsub("%c%((.-)%) (.-) (.-) fshow", function(str,font,scale) + mptopdf.data = gsub(mptopdf.data,"%c%((.-)%) (.-) (.-) fshow", function(str,font,scale) mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale} return "\n" .. #mptopdf.texts .. " textext" end) - mptopdf.data = mptopdf.data:gsub("%[%s*(.-)%s*%]", function(str) - return str:gsub("%s+"," ") + mptopdf.data = gsub(mptopdf.data,"%[%s*(.-)%s*%]", function(str) + return gsub(str,"%s+"," ") end) local t - mptopdf.data = mptopdf.data:gsub("%s*([^%a]-)%s*(%a+)", function(args,cmd) + mptopdf.data = gsub(mptopdf.data,"%s*([^%a]-)%s*(%a+)", function(args,cmd) if cmd == "textext" then t = mptopdf.texts[tonumber(args)] return "mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n" else - return "mps." .. cmd .. "(" .. args:gsub(" +",",") .. ")\n" + return "mps." .. cmd .. "(" .. gsub(args," +",",") .. ")\n" end end) end @@ -445,7 +445,7 @@ do -- assumes \let\c\char local package = lpeg.Cs(spec + text^0) function mps.fshow(str,font,scale) -- lpeg parser - mps.textext(font,scale,package:match(str)) + mps.textext(font,scale,lpegmatch(package,str)) end end @@ -579,10 +579,10 @@ do local captures_new = ( space + procset + preamble + verbose )^0 function mptopdf.parsers.lpeg() - if mptopdf.data:find("%%%%BeginResource: procset mpost") then - captures_new:match(mptopdf.data) + if find(mptopdf.data,"%%%%BeginResource: procset mpost") then + lpegmatch(captures_new,mptopdf.data) else - captures_old:match(mptopdf.data) + lpegmatch(captures_old,mptopdf.data) end end diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua index 5777bec92..ca405925f 100644 --- a/tex/context/base/mlib-pdf.lua +++ b/tex/context/base/mlib-pdf.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['mlib-pdf'] = { license = "see context related readme files", } -local format, concat = string.format, table.concat +local format, concat, gsub = string.format, table.concat, string.gsub local texsprint = tex.sprint local abs, sqrt, round = math.abs, math.sqrt, math.round @@ -119,7 +119,7 @@ function metapost.flushers.pdf.flushfigure(pdfliterals) -- table end function metapost.flushers.pdf.textfigure(font,size,text,width,height,depth) -- we could save the factor - text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost (i have to check if this is true for mplib) + text = gsub(text,".","\\hbox{%1}") -- kerning happens in metapost (i have to check if this is true for mplib) texsprint(ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*depth)) end diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua index f0ee1ec29..c1e1b71c0 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -12,6 +12,7 @@ if not modules then modules = { } end modules ['mlib-pps'] = { -- prescript, pos local format, gmatch, concat, round, match = string.format, string.gmatch, table.concat, math.round, string.match local sprint = tex.sprint local tonumber, type = tonumber, type +local lpegmatch = lpeg.match local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming @@ -119,7 +120,7 @@ function metapost.specials.register(str) -- only colors logs.report("mplib","problematic special: %s", str or "?") end end ---~ if str:match("^%%%%MetaPostOption: multipass") then +--~ if match(str,"^%%%%MetaPostOption: multipass") then --~ metapost.multipass = true --~ end end @@ -203,11 +204,11 @@ local colorsplitter = lpeg.Ct(lpeg.splitter(":",tonumber)) -- This is also an example of a simple plugin. --~ function metapost.specials.cc(specification,object,result) ---~ object.color = specificationsplitter:match(specification) +--~ object.color = lpegmatch(specificationsplitter,specification) --~ return object, nil, nil, nil --~ end --~ function metapost.specials.cc(specification,object,result) ---~ local c = specificationsplitter:match(specification) +--~ local c = lpegmatch(specificationsplitter,specification) --~ local o = object.color[1] --~ c[1],c[2],c[3],c[4] = o*c[1],o*c[2],o*c[3],o*c[4] --~ return object, nil, nil, nil @@ -276,10 +277,10 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color nofshades = nofshades + 1 flusher.flushfigure(result) result = { } - local t = specificationsplitter:match(specification) + local t = lpegmatch(specificationsplitter,specification) -- we need a way to move/scale - local ca = colorsplitter:match(t[4]) - local cb = colorsplitter:match(t[8]) + local ca = lpegmatch(colorsplitter,t[4]) + local cb = lpegmatch(colorsplitter,t[8]) if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end local name = format("MplSh%s",nofshades) @@ -348,10 +349,10 @@ function metapost.specials.ls(specification,object,result,flusher) nofshades = nofshades + 1 flusher.flushfigure(result) result = { } - local t = specificationsplitter:match(specification) + local t = lpegmatch(specificationsplitter,specification) -- we need a way to move/scale - local ca = colorsplitter:match(t[4]) - local cb = colorsplitter:match(t[7]) + local ca = lpegmatch(colorsplitter,t[4]) + local cb = lpegmatch(colorsplitter,t[7]) if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end local name = format("MpSh%s",nofshades) @@ -671,7 +672,7 @@ do function metapost.check_texts(str) found, forced = false, false - return parser:match(str), found, forced + return lpegmatch(parser,str), found, forced end end diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index a2026e865..73ce51c89 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -31,11 +31,10 @@ nears zero.

local trace_graphics = false trackers.register("metapost.graphics", function(v) trace_graphics = v end) -local format = string.format +local format, gsub, match = string.format, string.gsub, string.match local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming - metapost = metapost or { } metapost.showlog = false @@ -164,8 +163,8 @@ function metapost.checkformat(mpsinput, mpsformat, dirname) if not result.log then metapost.reporterror(result) else - local version = result.log:match(">> *(.-)[\n\r]") or "unknown" - version = version:gsub("[\'\"]","") + local version = match(result.log,">> *(.-)[\n\r]") or "unknown" + version = gsub(version,"[\'\"]","") if version ~= the_version then commands.writestatus("mplib","version mismatch: %s <> %s", version or "unknown", the_version) else diff --git a/tex/context/base/mult-chk.lua b/tex/context/base/mult-chk.lua index b0ee39a77..bdbd1dd22 100644 --- a/tex/context/base/mult-chk.lua +++ b/tex/context/base/mult-chk.lua @@ -7,9 +7,9 @@ if not modules then modules = { } end modules ['mult-chk'] = { } local format = string.format +local lpegmatch = lpeg.match local type = type -local texsprint = tex.sprint -local ctxcatcodes = tex.ctxcatcodes +local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes interfaces = interfaces or { } @@ -59,7 +59,7 @@ function commands.getcheckedparameters(k,p,s) if s and s ~= "" then prefix, kind = p, k keys = k and k ~= "" and interfaces.syntax[k].keys - pattern:match(s) + lpegmatch(pattern,s) end end diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index 1d3be3c87..a1dd5ecfd 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['mult-ini'] = { } local format, gmatch, gsub = string.format, string.gmatch, string.gsub +local lpegmatch = lpeg.match interfaces = interfaces or { } interfaces.messages = interfaces.messages or { } @@ -33,7 +34,7 @@ function interfaces.setmessage(category,tag,message) m = { } messages[category] = m end - m[tag] = message:gsub("%-%-","%%s") + m[tag] = gsub(message,"%-%-","%%s") end function interfaces.getmessage(category,tag,default) @@ -56,7 +57,7 @@ function interfaces.makemessage(category,tag,arguments) elseif not arguments then return m else - return format(m,messagesplitter:match(arguments)) + return format(m,lpegmatch(messagesplitter,arguments)) end end diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua index 1eb27a81b..8700cb00f 100644 --- a/tex/context/base/regi-ini.lua +++ b/tex/context/base/regi-ini.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['regi-ini'] = { } local utf = unicode.utf8 -local char, utfchar = string.char, utf.char +local char, utfchar, gsub = string.char, utf.char, string.gsub local texsprint = tex.sprint local ctxcatcodes = tex.ctxcatcodes @@ -63,7 +63,7 @@ function regimes.translate(line,regime) if regime and line then local rur = regimes.utf[regime] if rur then - return line:gsub("(.)", rur) -- () redundant + return (gsub(line,"(.)",rur)) -- () redundant end end return line diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index b1eac73ba..8700eccce 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -19,6 +19,7 @@ local next, type, tonumber = next, type, tonumber local format, gmatch, concat, match = string.format, string.gmatch, table.concat, string.match local ceil, floor, max, min, round = math.ceil, math.floor, math.max, math.min, math.round local texsprint, texlists, texdimen, texbox, texht, texdp = tex.sprint, tex.lists, tex.dimen, tex.box, tex.ht, tex.dp +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables @@ -96,7 +97,7 @@ local colonsplitter = lpeg.splitat(":") function interfaces.listtohash(str) local t = { } for s in gmatch(str,"[^, ]+") do - local key, fraction = colonsplitter:match(s) + local key, fraction = lpegmatch(colonsplitter,s) local v = variables[key] if v then t[v] = true @@ -295,7 +296,7 @@ do -- todo: interface.variables local function analyse(str,oldcategory,texsprint) -- we could use shorter names for s in gmatch(str,"([^ ,]+)") do - local amount, keyword, detail = splitter:match(s) + local amount, keyword, detail = lpegmatch(splitter,s) if not keyword then logs.report("vspacing","unknown directive: %s",s) else diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua index 825e32c67..301c76a0e 100644 --- a/tex/context/base/strc-blk.lua +++ b/tex/context/base/strc-blk.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['strc--blk'] = { -- this one runs on top of buffers and structure -local texprint, format, gmatch = tex.print, string.format, string.gmatch +local texprint, format, gmatch, find = tex.print, string.format, string.gmatch, string.find +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes @@ -42,7 +43,7 @@ function blocks.print(name,data,hide) texprint(data[i]) end else - printer:match(data) + lpegmatch(printer,data) end if hide then texprint(ctxcatcodes,"\\dostophiddenblock") @@ -76,7 +77,7 @@ end function blocks.select(state,name,tag,criterium) criterium = criterium or "text" - if tag:find("=") then tag = "" end + if find(tag,"=") then tag = "" end local names = aux.settings_to_set(name) local all = tag == "" local tags = not all and aux.settings_to_set(tag) diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index 02306f912..74a5cc21a 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['strc-doc'] = { } local next, type = next, type -local format, gsub, find, concat = string.format, string.gsub, string.find, table.concat +local format, gsub, find, concat, gmatch, match = string.format, string.gsub, string.find, table.concat, string.gmatch, string.match local texsprint, texwrite = tex.sprint, tex.write local ctxcatcodes = tex.ctxcatcodes @@ -314,7 +314,7 @@ end function sections.setnumber(depth,n) local forced, depth, new = data.forced, depth or data.depth, tonumber(n) if type(n) == "string" then - if n:find("^[%+%-]") then + if find(n,"^[%+%-]") then forced[depth] = { "add", new } else forced[depth] = { "set", new } @@ -362,7 +362,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp if not depth or depth == 0 then depth = data.depth end local data = data.status[depth] local d = data - for k in key:gmatch("([^.]+)") do + for k in gmatch(key,"([^.]+)") do if type(d) == "table" then d = d[k] if not d then @@ -489,7 +489,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref -- local firstprefix, lastprefix = 0, 16 if segments then - local f, l = (tostring(segments)):match("^(.-):(.+)$") + local f, l = match(tostring(segments),"^(.-):(.+)$") if f and l then -- 0:100, chapter:subsubsection firstprefix = tonumber(f) or sections.getlevel(f) or 0 diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua index 2d81cb9ab..61c26a20e 100644 --- a/tex/context/base/strc-ini.lua +++ b/tex/context/base/strc-ini.lua @@ -23,6 +23,7 @@ but it does not make sense to store all processdata. local format, concat, match = string.format, table.concat, string.match local count, texwrite, texprint, texsprint = tex.count, tex.write, tex.print, tex.sprint local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match local ctxcatcodes, xmlcatcodes, notcatcodes = tex.ctxcatcodes, tex.xmlcatcodes, tex.notcatcodes -- tricky as we're in notcatcodes @@ -198,7 +199,7 @@ end local splitter = lpeg.splitat("->",true) function processors.split(str) - local p, s = splitter:match(str) + local p, s = lpegmatch(splitter,str) if registered[p] then return p, s else @@ -207,7 +208,7 @@ function processors.split(str) end function processors.sprint(catcodes,str,fnc,...) - local p, s = splitter:match(str) + local p, s = lpegmatch(splitter,str) local code if registered[p] then code = format("\\applyprocessor{%s}{%s}",p,(fnc and fnc(s,...)) or s) @@ -221,7 +222,7 @@ function processors.sprint(catcodes,str,fnc,...) end function processors.apply(str) - local p, s = splitter:match(str) + local p, s = lpegmatch(splitter,str) if registered[p] then return format("\\applyprocessor{%s}{%s}",p,s) else diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index 12c0b8c45..73b20f9d2 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -11,7 +11,8 @@ if not modules then modules = { } end modules ['strc-lst'] = { -- section, metadata cache (internal then has to move up one level) or a -- shared cache [we can use a fast and stupid serializer] -local format, tonumber = string.format, tonumber +local format, gmatch = string.format, string.gmatch +local tonumber = tonumber local texsprint, texprint, texwrite, texcount = tex.sprint, tex.print, tex.write, tex.count local concat, insert, remove = table.concat, table.insert, table.remove @@ -139,7 +140,7 @@ local function filter_collected(names, criterium, number, collected, nested) local numbers, depth = documents.data.numbers, documents.data.depth local hash, result, all, detail = { }, { }, not names or names == "" or names == variables.all, nil if not all then - for s in names:gmatch("[^, ]+") do + for s in gmatch(names,"[^, ]+") do if trace_lists then logs.report("lists","filtering: %s",s) end diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 4c94fbbe7..001a52a75 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['strc-ref'] = { } local format, find, gmatch, match, concat = string.format, string.find, string.gmatch, string.match, table.concat +local lpegmatch = lpeg.match local texsprint, texwrite, texcount = tex.sprint, tex.write, tex.count local trace_referencing = false trackers.register("structure.referencing", function(v) trace_referencing = v end) @@ -133,11 +134,11 @@ local special_reference = special * lparent * (operation * optional_arguments + local scanner = (reset * outer_reference * (special_reference + inner_reference)^-1 * -1) / function() return result end --~ function jobreferences.analyse(str) -- overloaded ---~ return scanner:match(str) +--~ return lpegmatch(scanner,str) --~ end function jobreferences.split(str) - return scanner:match(str or "") + return lpegmatch(scanner,str or "") end --~ print(table.serialize(jobreferences.analyse(""))) @@ -502,7 +503,7 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere if d then resolve(prefix,d[2],nil,set) else - local var = scanner:match(ri) + local var = lpegmatch(scanner,ri) if var then var.reference = ri if not var.outer and var.inner then diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua index ba9c239c0..bce3b17ba 100644 --- a/tex/context/base/strc-reg.lua +++ b/tex/context/base/strc-reg.lua @@ -10,6 +10,7 @@ local next, type = next, type local texwrite, texsprint, texcount = tex.write, tex.sprint, tex.count local format, gmatch, concat = string.format, string.gmatch, table.concat local utfchar = utf.char +local lpegmatch = lpeg.match local trace_registers = false trackers.register("structure.registers", function(v) trace_registers = v end) @@ -215,8 +216,8 @@ local function preprocessentries(rawdata) local entries = rawdata.entries if entries then local e, k = entries[1] or "", entries[2] or "" - local et = (type(e) == "table" and e) or entrysplitter:match(e) - local kt = (type(k) == "table" and k) or entrysplitter:match(k) + local et = (type(e) == "table" and e) or lpegmatch(entrysplitter,e) + local kt = (type(k) == "table" and k) or lpegmatch(entrysplitter,k) entries = { } for k=1,#et do entries[k] = { et[k] or "", kt[k] or "" } diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua index 228765eea..23c5b05ef 100644 --- a/tex/context/base/syst-lua.lua +++ b/tex/context/base/syst-lua.lua @@ -7,7 +7,8 @@ if not modules then modules = { } end modules ['syst-lua'] = { } local texsprint, texprint, texwrite, texiowrite_nl = tex.sprint, tex.print, tex.write, texio.write_nl -local format = string.format +local format, find = string.format, string.find +local lpegmatch = lpeg.match local ctxcatcodes = tex.ctxcatcodes @@ -57,7 +58,7 @@ function commands.boolcase(b) end function commands.doifelsespaces(str) - return commands.doifelse(str:find("^ +$")) + return commands.doifelse(find(str,"^ +$")) end local s = lpeg.Ct(lpeg.splitat(",")) @@ -66,8 +67,8 @@ local h = { } function commands.doifcommonelse(a,b) local ha = h[a] local hb = h[b] - if not ha then ha = s:match(a) h[a] = ha end - if not hb then hb = s:match(b) h[b] = hb end + if not ha then ha = lpegmatch(s,a) h[a] = ha end + if not hb then hb = lpegmatch(s,b) h[b] = hb end for i=1,#ha do for j=1,#hb do if ha[i] == hb[j] then @@ -80,7 +81,7 @@ end function commands.doifinsetelse(a,b) local hb = h[b] - if not hb then hb = s:match(b) h[b] = hb end + if not hb then hb = lpegmatch(s,b) h[b] = hb end for i=1,#hb do if a == hb[i] then return commands.testcase(true) diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 08252c6c9..1a7c55594 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -18,8 +18,11 @@ if not tracers.strings then tracers.strings = { } end tracers.strings.undefined = "undefined" +local splitter = lpeg.splitat(":") +local lpegmatch = lpeg.match + function tracers.split(csname) - return csname:match("^(.+):(.+)$") + return lpegmatch(splitter,csname) end function tracers.type(csname) diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index 00af9895b..73ec0adb4 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -11,7 +11,8 @@ if not modules then modules = { } end modules ['trac-log'] = { --~ io.stdout:setvbuf("no") --~ io.stderr:setvbuf("no") -local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format +local write_nl, write = texio.write_nl or print, texio.write or io.write +local format, gmatch = string.format, string.gmatch local texcount = tex and tex.count if texlua then @@ -265,7 +266,7 @@ logs.report = logs.tex.report logs.simple = logs.tex.report function logs.reportlines(str) -- todo: - for line in str:gmatch("(.-)[\n\r]") do + for line in gmatch(str,"(.-)[\n\r]") do logs.report(line) end end diff --git a/tex/context/base/trac-tim.lua b/tex/context/base/trac-tim.lua index a896d767f..674abdf60 100644 --- a/tex/context/base/trac-tim.lua +++ b/tex/context/base/trac-tim.lua @@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['trac-tim'] = { license = "see context related readme files" } +local format, gsub = string.format, string.gsub +local concat, sort = table.concat, table.sort +local next, pairs, ipairs = next, pairs, ipairs + goodies = goodies or { } goodies.progress = goodies.progress or { } @@ -98,8 +102,8 @@ local function convert(name) end end local tagname = subtag or tag - top[tagname] = (string.format("%.3f",t)):gsub("%.000$","") - bot[tagname] = (string.format("%.3f",b)):gsub("%.000$","") + top[tagname] = gsub(format("%.3f",t),"%.000$","") + bot[tagname] = gsub(format("%.3f",b),"%.000$","") local delta = t-b if delta == 0 then delta = 1 @@ -109,7 +113,7 @@ local function convert(name) for k, v in ipairs(s) do s[k] = "(" .. k .. "," .. (v-b)*delta .. ")" end - paths[tagname] = table.concat(s,"--") + paths[tagname] = concat(s,"--") end for _, tag in pairs(params) do path(tag) @@ -121,7 +125,7 @@ local function convert(name) pages = pages - 1 end end - table.sort(names) + sort(names) processed[name] = { names = names, top = top, diff --git a/tex/context/base/trac-tra.lua b/tex/context/base/trac-tra.lua index 128cd63dc..63ce4233f 100644 --- a/tex/context/base/trac-tra.lua +++ b/tex/context/base/trac-tra.lua @@ -60,7 +60,7 @@ function debugger.showstats(printer,threshold) for func, count in pairs(counters) do if count > threshold then local name = getname(func) - if not name:find("for generator") then + if not find(name,"for generator") then printer(format("%8i %s", count, name)) total = total + count end diff --git a/tex/context/base/typo-mir.lua b/tex/context/base/typo-mir.lua index 6e5d8663c..d60af700e 100644 --- a/tex/context/base/typo-mir.lua +++ b/tex/context/base/typo-mir.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['typo-mir'] = { local utf = unicode.utf8 local next, type = next, type -local format, insert = string.format, table.insert +local format, insert, sub, find, match = string.format, table.insert, string.sub, string.find, string.match local utfchar = utf.char -- vertical space handler @@ -323,8 +323,8 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster local subtype = current.subtype if subtype == 6 then local dir = current.dir - local d = dir:sub(2,2) -- -- -- -- -- why is this not used - if dir:find(".R.") then -- -- d == "R" or just dir == "TRT" + local d = sub(dir,2,2) + if d == 'R' then -- find(dir,".R.") / dir == "TRT" autodir = -1 else autodir = 1 @@ -335,8 +335,9 @@ function mirroring.process(namespace,attribute,start) -- todo: make faster end elseif subtype == 7 then local dir = current.dir - local sign = dir:sub(1,1) - local dire = dir:sub(3,3) + -- local sign = sub(dir,1,1) + -- local dire = sub(dir,3,3) + local sign, dire = match(dir,"^(.).(.)") if dire == "R" then if sign == "+" then finish, autodir = "TRT", -1 diff --git a/tex/context/base/x-asciimath.lua b/tex/context/base/x-asciimath.lua index 55fe6c991..84a89ad44 100644 --- a/tex/context/base/x-asciimath.lua +++ b/tex/context/base/x-asciimath.lua @@ -14,6 +14,7 @@ local trace_mapping = false if trackers then trackers.register("asciimath.mappi local format = string.format local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local lpegmatch = lpeg.match local S, P, R, C, V, Cc, Ct, Cs = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct, lpeg.Cs @@ -165,17 +166,17 @@ local function converted(original,totex) if trace_mapping then logs.report("asciimath","original : %s",original) end - local premapped = premapper:match(original) + local premapped = lpegmatch(premapper,original) if premapped then if trace_mapping then logs.report("asciimath","prepared : %s",premapped) end - local parsed = parser:match(premapped) + local parsed = lpegmatch(parser,premapped) if parsed then if trace_mapping then logs.report("asciimath","parsed : %s",parsed) end - local postmapped = postmapper:match(parsed) + local postmapped = lpegmatch(postmapper,parsed) if postmapped then if trace_mapping then logs.report("asciimath","finalized : %s",postmapped) @@ -202,7 +203,7 @@ local function converted(original,totex) end local function onlyconverted(str) - local parsed = parser:match(str) + local parsed = lpegmatch(parser,str) return parsed or str end diff --git a/tex/context/base/x-calcmath.lua b/tex/context/base/x-calcmath.lua index 0939411be..e4d5da139 100644 --- a/tex/context/base/x-calcmath.lua +++ b/tex/context/base/x-calcmath.lua @@ -6,7 +6,8 @@ if not modules then modules = { } end modules ['x-calcmath'] = { license = "see context related readme files" } -local format, lower, upper, gsub = string.format, string.lower, string.upper, string.gsub +local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub +local lpegmatch = lpeg.match tex = tex or { } @@ -71,8 +72,8 @@ local symbols = { } local function nsub(str,tag,pre,post) - return (str:gsub(tag .. "(%b())", function(body) - return pre .. nsub(body:sub(2,-2),tag,pre,post) .. post + return (gsub(str,tag .. "(%b())", function(body) + return pre .. nsub(sub(body,2,-2),tag,pre,post) .. post end)) end @@ -80,87 +81,87 @@ function calcmath.totex(str,mode) if not frozen then freeze() end local n = 0 -- crap - str = str:gsub("%s+" , ' ') + str = gsub(str,"%s+",' ') -- xml - str = str:gsub("&(.-);", entities) + str = gsub(str,"&(.-);",entities) -- ...E... - str = str:gsub("([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}") + str = gsub(str,"([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}") -- ^-.. - str = str:gsub( "%^([%-%+]*%d+)", "^{%1}") + str = gsub(str,"%^([%-%+]*%d+)", "^{%1}") -- ^(...) - str = nsub(str, "%^", "^{", "}") + str = nsub(str,"%^", "^{", "}") -- 1/x^2 repeat - str, n = str:gsub("([%d%w%.]+)/([%d%w%.]+%^{[%d%w%.]+})", "\\frac{%1}{%2}") + str, n = gsub(str,"([%d%w%.]+)/([%d%w%.]+%^{[%d%w%.]+})", "\\frac{%1}{%2}") until n == 0 -- todo: autoparenthesis -- int(a,b,c) for k, v in next, list_2_1 do - repeat str, n = str:gsub(k,v) until n == 0 + repeat str, n = gsub(str,k,v) until n == 0 end -- int(a,b) for k, v in next, list_2_2 do - repeat str, n = str:gsub(k, v) until n == 0 + repeat str, n = gsub(str,k,v) until n == 0 end -- int(a) for k, v in next, list_2_3 do - repeat str, n = str:gsub(k, v) until n == 0 + repeat str, n = gsub(str,k,v) until n == 0 end -- sin(x) => {\\sin(x)} for k, v in next, list_1_1 do - repeat str, n = str:gsub(k, v) until n == 0 + repeat str, n = gsub(str,k,v) until n == 0 end -- mean str = nsub(str, "mean", "\\OVERLINE{", "}") -- (1+x)/(1+x) => \\FRAC{1+x}{1+x} repeat - str, n = str:gsub("(%b())/(%b())", function(a,b) - return "\\FRAC{" .. a:sub(2,-2) .. "}{" .. b:sub(2,-2) .. "}" + str, n = gsub(str,"(%b())/(%b())", function(a,b) + return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. sub(b,2,-2) .. "}" end ) until n == 0 -- (1+x)/x => \\FRAC{1+x}{x} repeat - str, n = str:gsub("(%b())/([%+%-]?[%.%d%w]+)", function(a,b) - return "\\FRAC{" .. a:sub(2,-2) .. "}{" .. b .. "}" + str, n = gsub(str,"(%b())/([%+%-]?[%.%d%w]+)", function(a,b) + return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. b .. "}" end ) until n == 0 -- 1/(1+x) => \\FRAC{1}{1+x} repeat - str, n = str:gsub("([%.%d%w]+)/(%b())", function(a,b) - return "\\FRAC{" .. a .. "}{" .. b:sub(2,-2) .. "}" + str, n = gsub(str,"([%.%d%w]+)/(%b())", function(a,b) + return "\\FRAC{" .. a .. "}{" .. sub(b,2,-2) .. "}" end ) until n == 0 -- 1/x => \\FRAC{1}{x} repeat - str, n = str:gsub("([%.%d%w]+)/([%+%-]?[%.%d%w]+)", "\\FRAC{%1}{%2}") + str, n = gsub(str,"([%.%d%w]+)/([%+%-]?[%.%d%w]+)", "\\FRAC{%1}{%2}") until n == 0 -- times - str = str:gsub("%*", " ") + str = gsub(str,"%*", " ") -- symbols -- we can use a table substitution here - str = str:gsub("([<>=][<>=]*)", symbols) + str = gsub(str,"([<>=][<>=]*)", symbols) -- functions - str = nsub(str, "sqrt", "\\SQRT{", "}") - str = nsub(str, "exp", "e^{", "}") - str = nsub(str, "abs", "\\left|", "\\right|") + str = nsub(str,"sqrt", "\\SQRT{", "}") + str = nsub(str,"exp", "e^{", "}") + str = nsub(str,"abs", "\\left|", "\\right|") -- d/D - str = nsub(str, "D", "{\\FRAC{\\MBOX{d}}{\\MBOX{d}x}{(", ")}}") - str = str:gsub("D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}") + str = nsub(str,"D", "{\\FRAC{\\MBOX{d}}{\\MBOX{d}x}{(", ")}}") + str = gsub(str,"D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}") -- f/g for k,v in next, list_3 do -- todo : prepare k,v - str = nsub(str, "D"..v,"{\\RM "..v.."}^{\\PRIME}(",")") - str = nsub(str, v,"{\\RM "..v.."}(",")") + str = nsub(str,"D"..v,"{\\RM "..v.."}^{\\PRIME}(",")") + str = nsub(str,v,"{\\RM "..v.."}(",")") end -- more symbols for k,v in next, list_4_1 do - str = str:gsub(k, v) + str = gsub(str,k,v) end -- parenthesis (optional) if mode == 2 then - str = str:gsub("%(", "\\left\(") - str = str:gsub("%)", "\\right\)") + str = gsub(str,"%(", "\\left\(") + str = gsub(str,"%)", "\\right\)") end -- csnames - str = str:gsub("(\\[A-Z]+)", lower) + str = gsub(str,"(\\[A-Z]+)", lower) -- trace --~ print(str) -- report @@ -351,11 +352,11 @@ if false then calcmath = { } function calcmath.parse(str) - return parser:match(str) + return lpegmatch(parser,str) end function calcmath.tex(str) - str = totex(parser:match(str)) + str = totex(lpegmatch(parser,str)) return (str == "" and "[error]") or str end diff --git a/tex/context/base/x-ct.lua b/tex/context/base/x-ct.lua index 7fe1795a8..222a127ce 100644 --- a/tex/context/base/x-ct.lua +++ b/tex/context/base/x-ct.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['x-ct'] = { local xmlsprint, xmlfilter, xmlcollected = xml.sprint, xml.filter, xml.collected local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes -local format, concat, rep = string.format, table.concat, string.rep +local format, concat, rep, find = string.format, table.concat, string.rep, string.find lxml.context = { } @@ -26,11 +26,11 @@ local halignments = { local function roottemplate(root) local rt = root.at.template if rt then - if not rt:find("|") then - rt = rt:gsub(",","|") + if not find(rt,"|") then + rt = gsub(rt,",","|") end - if not rt:find("^|") then rt = "|" .. rt end - if not rt:find("|$") then rt = rt .. "|" end + if not find(rt,"^|") then rt = "|" .. rt end + if not find(rt,"|$") then rt = rt .. "|" end end return rt end diff --git a/tex/context/base/x-ldx.tex b/tex/context/base/x-ldx.tex index eb242245c..398ca2345 100644 --- a/tex/context/base/x-ldx.tex +++ b/tex/context/base/x-ldx.tex @@ -2,7 +2,7 @@ \setupxml[method=mkiv,default=hidden] -\usemodule[mathml] +\usemodule[x][mathml] \xmlregisterdocumentsetup{ldx}{xml:mml:define} \xmlregisterdocumentsetup{ldx}{xml:ldx:define} @@ -10,7 +10,8 @@ \xmlregisterns{ldx}{ldx} \startxmlsetups xml:ldx:define - \xmlgrab {\xmldocument} {ldx:*} {*} +% \xmlgrab {\xmldocument} {ldx:*} {*} + \xmlsetsetup {#1} {ldx:*} {ldx:*} \stopxmlsetups % % % @@ -95,7 +96,7 @@ \dontleavehmode \hbox to \hsize \bgroup \strut \hskip.25\dimexpr\xmlattdef{#1}{n}{0}em\relax\relax % extra relax needed ! - \xmldoif {\xmlatt{#1}{comment}} {yes} {\tt} + \doif {\xmlatt{#1}{comment}} {yes} {\tt} \xmlflush{#1} \hss \egroup @@ -185,4 +186,6 @@ backspace=2cm, topspace=2cm] +% \usemodule[inf-02] + \endinput diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua index 166db30b6..fd73de6a0 100644 --- a/tex/context/base/x-mathml.lua +++ b/tex/context/base/x-mathml.lua @@ -9,11 +9,12 @@ if not modules then modules = { } end modules ['x-mathml'] = { local type, pairs = type, pairs local utf = unicode.utf8 local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes -local format, lower = string.format, string.lower -local utfchar, utffind, utfgmatch = utf.char, utf.find, utf.gmatch -local xmlsprint, xmlcprint, xmltext = xml.sprint, xml.cprint, xml.text +local format, lower, find, gsub = string.format, string.lower, string.find, string.gsub +local utfchar, utffind, utfgmatch, utfgsub = utf.char, utf.find, utf.gmatch, utf.gsub +local xmlsprint, xmlcprint, xmltext, xmlcontent = xml.sprint, xml.cprint, xml.text, xml.content local lxmltext, get_id = lxml.text, lxml.get_id local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues +local lpegmatch = lpeg.match lxml.mml = lxml.mml or { } @@ -442,53 +443,53 @@ function xml.functions.remapopenmath(e) end function lxml.mml.checked_operator(str) - texsprint(ctxcatcodes,(utf.gsub(str,".",o_replacements))) + texsprint(ctxcatcodes,(utfgsub(str,".",o_replacements))) end function lxml.mml.stripped(str) tex.sprint(ctxcatcodes,str:strip()) end -function lxml.mml.mn(id,pattern) - -- maybe at some point we need to interpret the number, but - -- currently we assume an upright font - local str = xmltext(get_id(id),pattern) or "" - str = str:gsub("(%s+)",utfchar(0x205F)) -- medspace e.g.: twenty one (nbsp is not seen) - texsprint(ctxcatcodes,(str:gsub(".",n_replacements))) +function table.keys_as_string(t) + local k = { } + for k,_ in pairs(t) do + k[#k+1] = k + end + return concat(k,"") end +--~ local leftdelimiters = "[" .. table.keys_as_string(l_replacements) .. "]" +--~ local rightdelimiters = "[" .. table.keys_as_string(r_replacements) .. "]" + function characters.remapentity(chr,slot) texsprint(format("{\\catcode%s=13\\xdef%s{\\string%s}}",slot,utfchar(slot),chr)) end -function lxml.mml.mo(id,pattern) - local str = xmltext(get_id(id),pattern) or "" - texsprint(ctxcatcodes,(utf.gsub(str,".",o_replacements))) +function lxml.mml.mn(id,pattern) + -- maybe at some point we need to interpret the number, but + -- currently we assume an upright font + local str = xmlcontent(get_id(id)) or "" + str = gsub(str,"(%s+)",utfchar(0x205F)) -- medspace e.g.: twenty one (nbsp is not seen) + texsprint(ctxcatcodes,(gsub(str,".",n_replacements))) +end + +function lxml.mml.mo(id) + local str = xmlcontent(get_id(id)) or "" + texsprint(ctxcatcodes,(utfgsub(str,".",o_replacements))) end -function lxml.mml.mi(id,pattern) - local str = xmltext(get_id(id),pattern) or "" - -- str = str:gsub("^%s*(.-)%s*$","%1") +function lxml.mml.mi(id) + local str = xmlcontent(get_id(id)) or "" + -- str = gsub(str,"^%s*(.-)%s*$","%1") local rep = i_replacements[str] if rep then texsprint(ctxcatcodes,rep) else - texsprint(ctxcatcodes,(str:gsub(".",i_replacements))) - end -end - -function table.keys_as_string(t) - local k = { } - for k,_ in pairs(t) do - k[#k+1] = k + texsprint(ctxcatcodes,(gsub(str,".",i_replacements))) end - return concat(k,"") end ---~ local leftdelimiters = "[" .. table.keys_as_string(l_replacements) .. "]" ---~ local rightdelimiters = "[" .. table.keys_as_string(r_replacements) .. "]" - -function lxml.mml.mfenced(id,pattern) -- multiple separators +function lxml.mml.mfenced(id) -- multiple separators id = get_id(id) local left, right, separators = id.at.open or "(", id.at.close or ")", id.at.separators or "," local l, r = l_replacements[left], r_replacements[right] @@ -500,13 +501,14 @@ function lxml.mml.mfenced(id,pattern) -- multiple separators texsprint(ctxcatcodes,left) end texsprint(ctxcatcodes,"\\disabledelimiter") - local collected = lxml.filter(id,pattern) + local collected = lxml.filter(id,"/*") -- check the * if collected then local n = #collected if n == 0 then -- skip elseif n == 1 then - lxml.all(id,pattern) + xmlsprint(collected[1]) -- to be checked +--~ lxml.all(id,"/*") else local t = { } for s in utfgmatch(separators,"[^%s]") do @@ -669,9 +671,9 @@ function lxml.mml.mcolumn(root) --~ if type(mc) ~= "string" then --~ n, p = false, false --~ break ---~ elseif mc:find("^[%d ]$") then -- rangecheck is faster +--~ elseif find(mc,"^[%d ]$") then -- rangecheck is faster --~ -- digit ---~ elseif not mc:find("^[%.%,]$") then -- rangecheck is faster +--~ elseif not find(mc,"^[%.%,]$") then -- rangecheck is faster --~ -- punctuation --~ else --~ n = false @@ -710,9 +712,9 @@ function lxml.mml.mtable(root) local rowalign = at.rowalign local columnalign = at.columnalign local frame = at.frame - local rowaligns = rowalign and spacesplitter:match(rowalign) - local columnaligns = columnalign and spacesplitter:match(columnalign) - local frames = frame and spacesplitter:match(frame) + local rowaligns = rowalign and lpegmatch(spacesplitter,rowalign) + local columnaligns = columnalign and lpegmatch(spacesplitter,columnalign) + local frames = frame and lpegmatch(spacesplitter,frame) local framespacing = at.framespacing or "0pt" local framespacing = at.framespacing or "-\\ruledlinewidth" -- make this an option @@ -777,6 +779,6 @@ function lxml.mml.menclosepattern(root) root = get_id(root) local a = root.at.notation if a and a ~= "" then - texsprint("mml:enclose:",a:gsub(" +",",mml:enclose:")) + texsprint("mml:enclose:",gsub(a," +",",mml:enclose:")) end end diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv index 6ddf00cac..a32009f06 100644 --- a/tex/context/base/x-mathml.mkiv +++ b/tex/context/base/x-mathml.mkiv @@ -1661,16 +1661,13 @@ %usemodule[x][asciimath] \startxmlsetups mml:annotation - \xmldoifelse {#1} {[oneof(@encoding,'TeX','tex','TEX','ConTeXt','context','CONTEXT','ctx')]} { - \begingroup - \setcatcodetable\ctxcatcodes - \xmlflush{#1} - \endgroup + \xmldoifelse {#1} {.[oneof(@encoding,'TeX','tex','TEX','ConTeXt','context','CONTEXT','ctx')]} { + \xmlflushcontext{#1} } { - \xmldoifelse {#1} {[oneof(@encoding,'calcmath','cm')]} { + \xmldoifelse {#1} {.[oneof(@encoding,'calcmath','cm')]} { \expanded{\calcmath{\xmlflush{#1}}} } { - \xmldoifelse {#1} {[oneof(@encoding,'asciimath','am')]} { + \xmldoifelse {#1} {.[oneof(@encoding,'asciimath','am')]} { \ifdefined\asciimath \expanded{\asciimath{\xmlflush{#1}}} \else @@ -1855,12 +1852,12 @@ % setups \startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground - \ctxlua{lxml.mml.mi("#1","/*")} + \ctxlua{lxml.mml.mi("#1")} \stopxmlsetups \startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground \begingroup - \mr \ctxlua{lxml.mml.mn("#1","/*")}% no \hbox, would be ok for . , but spoils rest + \mr \ctxlua{lxml.mml.mn("#1")}% no \hbox, would be ok for . , but spoils rest \endgroup \stopxmlsetups @@ -1871,7 +1868,7 @@ \startxmlsetups mml:mo \doif {\xmlatt{#1}{maxsize}} {1} {\settrue\mmlignoredelimiter} \doif {\xmlatt{#1}{stretchy}} {false} {\settrue\mmlignoredelimiter} - \ctxlua{lxml.mml.mo("#1","/*")} + \ctxlua{lxml.mml.mo("#1")} \setfalse\mmlignoredelimiter \stopxmlsetups @@ -1879,7 +1876,7 @@ \def\MMLleft {\left }% weird \def\MMLright {\right} \def\MMLmiddle{\middle} - \ctxlua{lxml.mml.mfenced("#1","/*")} + \ctxlua{lxml.mml.mfenced("#1")} \stopxmlsetups \defineoverlay [mml:enclose:box] [\useMPgraphic{mml:enclose:box}] diff --git a/tex/context/test/x-cals-test.cdx b/tex/context/test/x-cals-test.cdx deleted file mode 100644 index ce90883fa..000000000 --- a/tex/context/test/x-cals-test.cdx +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - diff --git a/tex/context/test/x-cals-test.tex b/tex/context/test/x-cals-test.tex deleted file mode 100644 index 30645c2bd..000000000 --- a/tex/context/test/x-cals-test.tex +++ /dev/null @@ -1,48 +0,0 @@ -% engine=luatex - -\usemodule[x][cals] - -\setupcolors[state=start] - -\startsetups cdx:cals:table:noframe - \setupTABLE[frame=off] -\stopsetups - -\startsetups cdx:cals:table:colors - \setupTABLE[row] [odd] [frame=off,background=color,backgroundcolor=red] - \setupTABLE[row] [even][frame=off,background=color,backgroundcolor=green] - \setupTABLE[column][2] [frame=off,background=color,backgroundcolor=blue] -\stopsetups - -\startsetups cdx:cals:table:vertical - \setupTABLE[row] [odd] [frame=off,background=color,backgroundcolor=lightblue] -\stopsetups - -\startsetups cdx:cals:table:horizontal - \setupTABLE[column] [odd] [frame=off,background=color,backgroundcolor=lightblue] -\stopsetups - -\startsetups cdx:cals:table:before:frame - \framed [offset=overlay,frame=off,topframe=on,bottomframe=on,rulethickness=2pt,framecolor=red,align=normal] \bgroup - \vskip2pt - \framed [offset=overlay,frame=off,leftframe=on,rightframe=on,rulethickness=1pt,framecolor=red,align=normal] \bgroup -\stopsetups - -\startsetups cdx:cals:table:after:frame - \egroup - \vskip2pt - \egroup -\stopsetups - -% \startxmlsetups xml:cals:process -% \xmlsetsetup {\xmldocument} {cals:table} {*} -% \stopxmlsetups -% \startxmlsetups cals:table -% \ctxlua{lxml.cals.table("#1")} -% \stopxmlsetups -% \xmlregistersetup{xml:cals:process} - -\starttext - \xmlloaddirectives{x-cals-test.cdx} - \xmlprocess{main}{x-cals-test.xml}{} -\stoptext diff --git a/tex/context/test/x-cals-test.xml b/tex/context/test/x-cals-test.xml deleted file mode 100644 index dc03668e3..000000000 --- a/tex/context/test/x-cals-test.xml +++ /dev/null @@ -1,522 +0,0 @@ - - - - - - - - - - - - - alpha - beta - gamma - - - - - one - two - three - - - four - five - six - - - - - - - - - - alpha - beta - gamma - - - - - one - two - three - - - four - five - six - - - - - - - - - - alpha - beta - gamma - - - - - one - two - three - - - four - five - six - - - - - - - - - - - - alpha - beta - gamma - - - - - one - two - three - - - four - five - - - - - - - - - - - - - alpha - beta - gamma - - - - - - one - two - three - - - four - five - - - - - - - - - - - - - alpha - beta - gamma - - - - - one - two - three - - - one - three - - - 4m - 5m - - - - - - - - - - alpha - - - - - one - three - - - 4 - 5 - - - - - - - one - two - - - -
- - - Cals tabel 3 met kolommen: header + footer + 3 rijen - - - - - - - h1 - h2 - h3 - - - - - f1 - f2 - f3 - - - - - a1 - a2 - a3 - - - b1 - b2 - b3 - - - c1 - c2 - c3 - - - - - - - Cals tabel 4 met kolommen: header + footer + 3 rijen - - - - - - - - h1 - h2 - h3 - h4 - - - - - f1 - f2 - f3 - f4 - - - - - a1 - a2 - a3 - a4 - - - b1 - b2 - b3 - b4 - - - c1 - c2 - c3 - c4 - - - - - - - Cals tabel 3 met kolommen: horizontal span - - - - - - - h1 - h2 - h3 - - - - - f1 - f2 - f3 - - - - - a1 - a2 - a3 - - - hs - - b3 - - - c1 - c2 - c3 - - - - - - - Cals tabel 3 met kolommen: verticale span - - - - - - - h1 - h2 - h3 - - - - - f1 - f2 - f3 - - - - - a1 - a2 - a3 - - - b1 - b2 -

vs

-
- - c1 - c2 - - -
-
-
- - - Cals tabel 3 met kolommen: verticale en horizontale span - - - - - - - h1 - h2 - h3 - - - - - f1 - f2 - f3 - - - - - a1 - a2 - a3 - - - b1 - vh - - - - c1 - - - - - - - - - - - - - - - - - - - - -

Grootheid

-
- -

Eenheid

-
- -

Symbool

-
- -

Meetwaarden

-
-
- - -

massa

-
- - - -

125

-
- -

195

-
- -

280

-
- -

380

-
- -

500

-
-
- - -

volume

-
- - - -

16

-
- -

25

-
- -

36

-
- -

49

-
- -

64

-
-
- - -

dichtheid

-
- - - -

7,8

-
- -

7,8

-
- -

7,8

-
- -

7,8

-
- -

7,8

-
-
-
-
-
- - -
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index f35c65e9f..e6cc18125 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua --- merge date : 12/26/09 22:27:58 +-- merge date : 12/29/09 22:36:24 do -- begin closure to overcome local limits and interference @@ -13,6 +13,7 @@ if not modules then modules = { } end modules ['l-string'] = { } local sub, gsub, find, match, gmatch, format, char, byte, rep, lower = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower +local lpegmatch = lpeg.match -- some functions may disappear as they are not used anywhere @@ -83,9 +84,19 @@ function string:limit(n,sentinel) end end -function string:strip() -- the .- is quite efficient --- return match(self,"^%s*(.-)%s*$") or "" - return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ function string:strip() -- the .- is quite efficient +--~ -- return match(self,"^%s*(.-)%s*$") or "" +--~ -- return match(self,'^%s*(.*%S)') or '' -- posted on lua list +--~ return find(s,'^%s*$') and '' or match(s,'^%s*(.*%S)') +--~ end + +do -- roberto's variant: + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return lpegmatch(stripper,str) or "" + end end function string:is_empty() @@ -222,7 +233,7 @@ end local pattern = lpeg.Ct(lpeg.C(1)^0) function string:totable() - return pattern:match(self) + return lpegmatch(pattern,self) end --~ for _, str in ipairs { @@ -294,6 +305,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = { lpeg = require("lpeg") local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local match = lpeg.match --~ l-lpeg.lua : @@ -346,15 +358,15 @@ local content = (empty + nonempty)^1 local capture = Ct(content^0) function string:splitlines() - return capture:match(self) + return match(capture,self) end lpeg.linebyline = content -- better make a sublibrary ---~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more ---~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more ---~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps ---~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps->what->more")) -- oeps what more +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps->what->more")) -- oeps what->more +--~ local p = lpeg.splitat("->",false) print(match(p,"oeps")) -- oeps +--~ local p = lpeg.splitat("->",true) print(match(p,"oeps")) -- oeps local splitters_s, splitters_m = { }, { } @@ -385,7 +397,7 @@ function string:split(separator) c = Ct(splitat(separator)) cache[separator] = c end - return c:match(self) + return match(c,self) end local cache = { } @@ -398,7 +410,7 @@ function string:checkedsplit(separator) c = Ct(separator^0 * other * (separator^1 * other)^0) cache[separator] = c end - return c:match(self) + return match(c,self) end --~ function lpeg.L(list,pp) @@ -1434,7 +1446,8 @@ if not modules then modules = { } end modules ['l-file'] = { file = file or { } local concat = table.concat -local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local lpegmatch = lpeg.match function file.removesuffix(filename) return (gsub(filename,"%.[%a%d]+$","")) @@ -1492,12 +1505,12 @@ end function file.iswritable(name) local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,".")) - return a and a.permissions:sub(2,2) == "w" + return a and sub(a.permissions,2,2) == "w" end function file.isreadable(name) local a = lfs.attributes(name) - return a and a.permissions:sub(1,1) == "r" + return a and sub(a.permissions,1,1) == "r" end file.is_readable = file.isreadable @@ -1572,27 +1585,27 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1 --~ function file.extname(name) ---~ return pattern:match(name) or "" +--~ return lpegmatch(pattern,name) or "" --~ end --~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1) --~ function file.removesuffix(name) ---~ return pattern:match(name) +--~ return lpegmatch(pattern,name) --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1 --~ function file.basename(name) ---~ return pattern:match(name) or name +--~ return lpegmatch(pattern,name) or name --~ end --~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1 --~ function file.dirname(name) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) +--~ return sub(name,1,p-2) --~ else --~ return "" --~ end @@ -1601,7 +1614,7 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.addsuffix(name, suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then --~ return name --~ else @@ -1612,9 +1625,9 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1 --~ function file.replacesuffix(name,suffix) ---~ local p = pattern:match(name) +--~ local p = lpegmatch(pattern,name) --~ if p then ---~ return name:sub(1,p-2) .. "." .. suffix +--~ return sub(name,1,p-2) .. "." .. suffix --~ else --~ return name .. "." .. suffix --~ end @@ -1623,11 +1636,11 @@ end --~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1 --~ function file.nameonly(name) ---~ local a, b = pattern:match(name) +--~ local a, b = lpegmatch(pattern,name) --~ if b then ---~ return name:sub(a,b-2) +--~ return sub(name,a,b-2) --~ elseif a then ---~ return name:sub(a) +--~ return sub(name,a) --~ else --~ return name --~ end @@ -1661,11 +1674,11 @@ local rootbased = lpeg.P("/") + letter*lpeg.P(":") -- ./name ../name /name c: :// name/name function file.is_qualified_path(filename) - return qualified:match(filename) ~= nil + return lpegmatch(qualified,filename) ~= nil end function file.is_rootbased_path(filename) - return rootbased:match(filename) ~= nil + return lpegmatch(rootbased,filename) ~= nil end local slash = lpeg.S("\\/") @@ -1678,7 +1691,7 @@ local base = lpeg.C((1-suffix)^0) local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc("")) function file.splitname(str) -- returns drive, path, base, suffix - return pattern:match(str) + return lpegmatch(pattern,str) end -- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end @@ -1700,7 +1713,7 @@ if not modules then modules = { } end modules ['l-io'] = { license = "see context related readme files" } -local byte = string.byte +local byte, find, gsub = string.byte, string.find, string.gsub if string.find(os.getenv("PATH"),";") then io.fileseparator, io.pathseparator = "\\", ";" @@ -1858,7 +1871,7 @@ function io.ask(question,default,options) end io.write(string.format(" ")) local answer = io.read() - answer = answer:gsub("^%s*(.*)%s*$","%1") + answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default elseif not options then @@ -1871,7 +1884,7 @@ function io.ask(question,default,options) end local pattern = "^" .. answer for _,v in pairs(options) do - if v:find(pattern) then + if find(v,pattern) then return v end end @@ -4182,6 +4195,7 @@ if not modules then modules = { } end modules ['font-cid'] = { local format, match, lower = string.format, string.match, string.lower local tonumber = tonumber +local lpegmatch = lpeg.match local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -4235,7 +4249,7 @@ function fonts.cid.load(filename) local data = io.loaddata(filename) if data then unicodes, names = { }, { } - grammar:match(data) + lpegmatch(grammar,data) local supplement, registry, ordering = match(filename,"^(.-)%-(.-)%-()%.(.-)$") return { supplement = supplement, @@ -5287,6 +5301,7 @@ local utf = unicode.utf8 local concat, getn, utfbyte = table.concat, table.getn, utf.byte local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match local trace_private = false trackers.register("otf.private", function(v) trace_private = v end) local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -5359,7 +5374,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.641 -- beware: also sync font-mis.lua +otf.version = 2.642 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -5483,6 +5498,7 @@ local enhancers = { "reorganize mark classes", "reorganize kerns", -- moved here "flatten glyph lookups", "flatten anchor tables", "flatten feature tables", + "simplify glyph lookups", -- some saving "prepare luatex tables", "analyse features", "rehash features", "analyse anchors", "analyse marks", "analyse unicodes", "analyse subtables", @@ -5779,11 +5795,11 @@ local separator = lpeg.S("_.") local other = lpeg.C((1 - separator)^1) local ligsplitter = lpeg.Ct(other * (separator * other)^0) ---~ print(table.serialize(ligsplitter:match("this"))) ---~ print(table.serialize(ligsplitter:match("this.that"))) ---~ print(table.serialize(ligsplitter:match("japan1.123"))) ---~ print(table.serialize(ligsplitter:match("such_so_more"))) ---~ print(table.serialize(ligsplitter:match("such_so_more.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"japan1.123"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more.that"))) otf.enhancers["analyse unicodes"] = function(data,filename) local tounicode16, tounicode16sequence = fonts.map.tounicode16, fonts.map.tounicode16sequence @@ -5821,13 +5837,13 @@ otf.enhancers["analyse unicodes"] = function(data,filename) -- cidmap heuristics, beware, there is no guarantee for a match unless -- the chain resolves if (not unicode) and usedmap then - local foundindex = oparser:match(name) + local foundindex = lpegmatch(oparser,name) if foundindex then unicode = cidcodes[foundindex] -- name to number if not unicode then local reference = cidnames[foundindex] -- number to name if reference then - local foundindex = oparser:match(reference) + local foundindex = lpegmatch(oparser,reference) if foundindex then unicode = cidcodes[foundindex] if unicode then @@ -5835,7 +5851,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end end if not unicode then - local foundcodes, multiple = uparser:match(reference) + local foundcodes, multiple = lpegmatch(uparser,reference) if foundcodes then if multiple then originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true @@ -5850,7 +5866,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end -- a.whatever or a_b_c.whatever or a_b_c (no numbers) if not unicode then - local split = ligsplitter:match(name) + local split = lpegmatch(ligsplitter,name) local nplit = (split and #split) or 0 if nplit == 0 then -- skip @@ -5883,7 +5899,7 @@ otf.enhancers["analyse unicodes"] = function(data,filename) end -- last resort if not unicode then - local foundcodes, multiple = uparser:match(name) + local foundcodes, multiple = lpegmatch(uparser,name) if foundcodes then if multiple then originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true @@ -6469,8 +6485,9 @@ end otf.enhancers["flatten glyph lookups"] = function(data,filename) for k, v in next, data.glyphs do - if v.lookups then - for kk, vv in next, v.lookups do + local lookups = v.lookups + if lookups then + for kk, vv in next, lookups do for kkk=1,#vv do local vvv = vv[kkk] local s = vvv.specification @@ -6520,6 +6537,31 @@ otf.enhancers["flatten glyph lookups"] = function(data,filename) end end +otf.enhancers["simplify glyph lookups"] = function(data,filename) + for k, v in next, data.glyphs do + local lookups = v.lookups + if lookups then + local slookups, mlookups + for kk, vv in next, lookups do + if #vv == 1 then + if not slookups then + slookups = { } + v.slookups = slookups + end + slookups[kk] = vv[1] + else + if not mlookups then + mlookups = { } + v.mlookups = mlookups + end + mlookups[kk] = vv + end + end + v.lookups = nil + end + end +end + otf.enhancers["flatten anchor tables"] = function(data,filename) for k, v in next, data.glyphs do if v.anchors then @@ -6760,7 +6802,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th local variants = m.horiz_variants if variants then local c = char - for n in variants:gmatch("[^ ]+") do + for n in gmatch(variants,"[^ ]+") do local un = unicodes[n] if un and u ~= un then c.next = un @@ -6772,7 +6814,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th local variants = m.vert_variants if variants then local c = char - for n in variants:gmatch("[^ ]+") do + for n in gmatch(variants,"[^ ]+") do local un = unicodes[n] if un and u ~= un then c.next = un @@ -7101,6 +7143,7 @@ if not modules then modules = { } end modules ['font-otb'] = { local concat = table.concat local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring +local lpegmatch = lpeg.match local otf = fonts.otf local tfm = fonts.tfm @@ -7161,7 +7204,7 @@ local function resolve_ligatures(tfmdata,ligatures,kind) for k,v in next, ligatures do local lig = v[1] if not done[lig] then - local ligs = split_at_space:match(lig) + local ligs = lpegmatch(split_at_space,lig) if #ligs == 2 then local uc = v[2] local c, f, s = characters[uc], ligs[1], ligs[2] @@ -7269,9 +7312,84 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod local characters = tfmdata.characters local descriptions = tfmdata.descriptions local changed = tfmdata.changed + -- + local actions = { + substitution = function(p,lookup,k,glyph,unicode) + local pv = p[2] -- p.variant + if pv then + local upv = unicodes[pv] + if upv then + if type(upv) == "table" then + upv = upv[1] + end + if characters[upv] then + if trace_baseinit and trace_singles then + logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv)) + end + changed[k] = upv + end + end + end + end, + alternate = function(p,lookup,k,glyph,unicode) + local pc = p[2] -- p.components + if pc then + -- a bit optimized ugliness + if value == 1 then + pc = lpegmatch(splitter,pc) + elseif value == 2 then + local a, b = lpegmatch(splitter,pc) + pc = b or a + else + pc = { lpegmatch(splitter,pc) } + pc = pc[value] or pc[#pc] + end + if pc then + local upc = unicodes[pc] + if upc then + if type(upc) == "table" then + upc = upc[1] + end + if characters[upc] then + if trace_baseinit and trace_alternatives then + logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc)) + end + changed[k] = upc + end + end + end + end + end, + ligature = function(p,lookup,k,glyph,unicode) + local pc = p[2] + if pc then + if trace_baseinit and trace_ligatures then + local upc = { lpegmatch(splitter,pc) } + for i=1,#upc do upc[i] = unicodes[upc[i]] end + -- we assume that it's no table + logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k)) + end + ligatures[#ligatures+1] = { pc, k } + end + end, + } + -- for k,c in next, characters do local glyph = descriptions[k] - local lookups = glyph.lookups + local lookups = glyph.slookups + if lookups then + for l=1,#lookuplist do + local lookup = lookuplist[l] + local p = lookups[lookup] + if p then + local a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) + end + end + end + end + local lookups = glyph.mlookups if lookups then for l=1,#lookuplist do local lookup = lookuplist[l] @@ -7279,62 +7397,9 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod if ps then for i=1,#ps do local p = ps[i] - local t = p[1] - if t == 'substitution' then - local pv = p[2] -- p.variant - if pv then - local upv = unicodes[pv] - if upv then - if type(upv) == "table" then - upv = upv[1] - end - if characters[upv] then - if trace_baseinit and trace_singles then - logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv)) - end - changed[k] = upv - end - end - end - elseif t == 'alternate' then - local pc = p[2] -- p.components - if pc then - -- a bit optimized ugliness - if value == 1 then - pc = splitter:match(pc) - elseif value == 2 then - local a, b = splitter:match(pc) - pc = b or a - else - pc = { splitter:match(pc) } - pc = pc[value] or pc[#pc] - end - if pc then - local upc = unicodes[pc] - if upc then - if type(upc) == "table" then - upc = upc[1] - end - if characters[upc] then - if trace_baseinit and trace_alternatives then - logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc)) - end - changed[k] = upc - end - end - end - end - elseif t == 'ligature' and not changed[k] then - local pc = p[2] - if pc then - if trace_baseinit and trace_ligatures then - local upc = { splitter:match(pc) } - for i=1,#upc do upc[i] = unicodes[upc[i]] end - -- we assume that it's no table - logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k)) - end - ligatures[#ligatures+1] = { pc, k } - end + local a = actions[p[1]] + if a then + a(p,lookup,k,glyph,unicode) end end end @@ -9743,142 +9808,153 @@ local function prepare_lookups(tfmdata) -- we can change the otf table after loading but then we need to adapt base mode -- as well (no big deal) -- - for unicode, glyph in next, descriptions do - local lookups = glyph.lookups - if lookups then - for lookup, whatever in next, lookups do - for i=1,#whatever do -- normaly one - local p = whatever[i] - local what = p[1] - if what == 'substitution' then - local old, new = unicode, unicodes[p[2]] - if type(new) == "table" then - new = new[1] - end - local s = single[lookup] - if not s then s = { } single[lookup] = s end - s[old] = new ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new) ---~ end - break - elseif what == 'multiple' then - local old, new = unicode, { } - local m = multiple[lookup] - if not m then m = { } multiple[lookup] = m end - m[old] = new - for pc in gmatch(p[2],"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - new[#new+1] = upc - else - new[#new+1] = upc[1] - end - end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," ")) ---~ end + local action = { + substitution = function(p,lookup,k,glyph,unicode) + local old, new = unicode, unicodes[p[2]] + if type(new) == "table" then + new = new[1] + end + local s = single[lookup] + if not s then s = { } single[lookup] = s end + s[old] = new + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new) + --~ end + end, + multiple = function (p,lookup,k,glyph,unicode) + local old, new = unicode, { } + local m = multiple[lookup] + if not m then m = { } multiple[lookup] = m end + m[old] = new + for pc in gmatch(p[2],"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + new[#new+1] = upc + else + new[#new+1] = upc[1] + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," ")) + --~ end + end, + alternate = function(p,lookup,k,glyph,unicode) + local old, new = unicode, { } + local a = alternate[lookup] + if not a then a = { } alternate[lookup] = a end + a[old] = new + for pc in gmatch(p[2],"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + new[#new+1] = upc + else + new[#new+1] = upc[1] + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|")) + --~ end + end, + ligature = function (p,lookup,k,glyph,unicode) + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name) + --~ end + local first = true + local t = ligature[lookup] + if not t then t = { } ligature[lookup] = t end + for s in gmatch(p[2],"[^ ]+") do + if first then + local u = unicodes[s] + if not u then + logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name) break - elseif what == 'alternate' then - local old, new = unicode, { } - local a = alternate[lookup] - if not a then a = { } alternate[lookup] = a end - a[old] = new - for pc in gmatch(p[2],"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - new[#new+1] = upc - else - new[#new+1] = upc[1] - end + elseif type(u) == "number" then + if not t[u] then + t[u] = { { } } end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|")) ---~ end - break - elseif what == "ligature" then ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name) ---~ end - local first = true - local t = ligature[lookup] - if not t then t = { } ligature[lookup] = t end - for s in gmatch(p[2],"[^ ]+") do - if first then - local u = unicodes[s] - if not u then - logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name) - break - elseif type(u) == "number" then - if not t[u] then - t[u] = { { } } - end - t = t[u] - else - local tt = t - local tu - for i=1,#u do - local u = u[i] - if i==1 then - if not t[u] then - t[u] = { { } } - end - tu = t[u] - t = tu - else - if not t[u] then - tt[u] = tu - end - end - end + t = t[u] + else + local tt = t + local tu + for i=1,#u do + local u = u[i] + if i==1 then + if not t[u] then + t[u] = { { } } end - first = false + tu = t[u] + t = tu else - s = unicodes[s] - local t1 = t[1] - if not t1[s] then - t1[s] = { { } } + if not t[u] then + tt[u] = tu end - t = t1[s] end end - t[2] = unicode - elseif what == 'position' then - -- not used - local s = position[lookup] - if not s then s = { } position[lookup] = s end - s[unicode] = p[2] -- direct pointer to kern spec - elseif what == 'pair' then - local s = pair[lookup] - if not s then s = { } pair[lookup] = s end - local others = s[unicode] - if not others then others = { } s[unicode] = others end - -- todo: fast check for space - local two = p[2] - local upc = unicodes[two] - if not upc then - for pc in gmatch(two,"[^ ]+") do - local upc = unicodes[pc] - if type(upc) == "number" then - others[upc] = p -- direct pointer to main table - else - for i=1,#upc do - others[upc[i]] = p -- direct pointer to main table - end - end - end - elseif type(upc) == "number" then - others[upc] = p -- direct pointer to main table - else - for i=1,#upc do - others[upc[i]] = p -- direct pointer to main table - end + end + first = false + else + s = unicodes[s] + local t1 = t[1] + if not t1[s] then + t1[s] = { { } } + end + t = t1[s] + end + end + t[2] = unicode + end, + position = function(p,lookup,k,glyph,unicode) + -- not used + local s = position[lookup] + if not s then s = { } position[lookup] = s end + s[unicode] = p[2] -- direct pointer to kern spec + end, + pair = function(p,lookup,k,glyph,unicode) + local s = pair[lookup] + if not s then s = { } pair[lookup] = s end + local others = s[unicode] + if not others then others = { } s[unicode] = others end + -- todo: fast check for space + local two = p[2] + local upc = unicodes[two] + if not upc then + for pc in gmatch(two,"[^ ]+") do + local upc = unicodes[pc] + if type(upc) == "number" then + others[upc] = p -- direct pointer to main table + else + for i=1,#upc do + others[upc[i]] = p -- direct pointer to main table end ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode) ---~ end end end + elseif type(upc) == "number" then + others[upc] = p -- direct pointer to main table + else + for i=1,#upc do + others[upc[i]] = p -- direct pointer to main table + end + end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode) + --~ end + end, + } + -- + for unicode, glyph in next, descriptions do + local lookups = glyph.slookups + if lookups then + for lookup, p in next, lookups do + action[p[1]](p,lookup,k,glyph,unicode) + end + end + local lookups = glyph.mlookups + if lookups then + for lookup, whatever in next, lookups do + for i=1,#whatever do -- normaly one + local p = whatever[i] + action[p[1]](p,lookup,k,glyph,unicode) + end end end local list = glyph.mykerns @@ -9887,9 +9963,9 @@ local function prepare_lookups(tfmdata) local k = kerns[lookup] if not k then k = { } kerns[lookup] = k end k[unicode] = krn -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode) + --~ end end end local oanchor = glyph.anchors @@ -9903,9 +9979,9 @@ local function prepare_lookups(tfmdata) local f = mark[lookup] if not f then f = { } mark[lookup] = f end f[unicode] = anchors -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode) + --~ end end end end @@ -9917,9 +9993,9 @@ local function prepare_lookups(tfmdata) local f = cursive[lookup] if not f then f = { } cursive[lookup] = f end f[unicode] = anchors -- ref to glyph, saves lookup ---~ if trace_lookups then ---~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode) ---~ end + --~ if trace_lookups then + --~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode) + --~ end end end end @@ -10657,6 +10733,7 @@ if not modules then modules = { } end modules ['font-def'] = { local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next +local lpegmatch = lpeg.match local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end) local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end) @@ -10757,7 +10834,7 @@ define.add_lookup("name") define.add_lookup("spec") function define.get_specification(str) - return splitter:match(str) + return lpegmatch(splitter,str) end function define.register_split(symbol,action) @@ -11310,6 +11387,7 @@ if not modules then modules = { } end modules ['font-xtx'] = { local texsprint, count = tex.sprint, tex.count local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next +local lpegmatch = lpeg.match local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) @@ -11389,7 +11467,7 @@ local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0 function fonts.define.specify.colonized(specification) -- xetex mode list = { } - pattern:match(specification.specification) + lpegmatch(pattern,specification.specification) for k, v in next, list do list[k] = v:is_boolean() if type(list[a]) == "nil" then @@ -11427,7 +11505,8 @@ if not modules then modules = { } end modules ['font-map'] = { license = "see context related readme files" } -local match, format, find, concat = string.match, string.format, string.find, table.concat +local match, format, find, concat, gsub = string.match, string.format, string.find, table.concat, string.gsub +local lpegmatch = lpeg.match local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -11509,7 +11588,7 @@ function fonts.map.load_file(filename, entries, encodings) -- print(line) else local extend, slant, name, fullname, fontfile, encoding - line = line:gsub('"(.+)"', function(s) + line = gsub(line,'"(.+)"', function(s) extend = find(s,'"([^"]+) ExtendFont"') slant = find(s,'"([^"]+) SlantFont"') return "" @@ -11590,7 +11669,7 @@ end --~ local parser = fonts.map.make_name_parser("Japan1") --~ local parser = fonts.map.make_name_parser() --~ local function test(str) ---~ local b, a = parser:match(str) +--~ local b, a = lpegmatch(parser,str) --~ print((a and table.serialize(b)) or b) --~ end --~ test("a.sc") diff --git a/tex/generic/context/luatex-mplib.lua b/tex/generic/context/luatex-mplib.lua index 09919af67..259a5e646 100644 --- a/tex/generic/context/luatex-mplib.lua +++ b/tex/generic/context/luatex-mplib.lua @@ -22,7 +22,7 @@ if metapost and metapost.version then else - local format, concat, abs = string.format, table.concat, math.abs + local format, concat, abs, match = string.format, table.concat, math.abs, string.match local mplib = require ('mplib') local kpse = require ('kpse') @@ -320,7 +320,7 @@ else metapost.report("flushing figure %s",f) local figure = figures[f] local objects = getobjects(result,figure,f) - local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0) + local fignum = match(tonumber((figure:filename())),"([%d]+)$") or figure:charcode() or 0) local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false local bbox = figure:boundingbox() local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack -- cgit v1.2.3