diff options
Diffstat (limited to 'tex')
65 files changed, 1272 insertions, 331 deletions
diff --git a/tex/context/base/cldf-bas.lua b/tex/context/base/cldf-bas.lua index dd6c575bf..9cf8dcd4a 100644 --- a/tex/context/base/cldf-bas.lua +++ b/tex/context/base/cldf-bas.lua @@ -34,6 +34,7 @@ local generics = context.generics local variables = interfaces.variables local new_rule = nodes.pool.rule +local texcount = tex.count function context.char(k) -- used as escape too, so don't change to utf if type(k) == "table" then @@ -142,3 +143,20 @@ end context.endvbox = context.egroup context.endhbox = context.egroup + +local function allocate(name,what,cmd) + local a = format("c_syst_last_allocated_%s",what) + local n = texcount[a] + 1 + if n <= texcount.c_syst_max_allocated_register then + texcount[a] = n + end + context("\\global\\expandafter\\%sdef\\csname %s\\endcsname %s\\relax",cmd or what,name,n) + return n +end + +function context.newdimen (name) return allocate(name,"dimen") end +function context.newskip (name) return allocate(name,"skip") end +function context.newcount (name) return allocate(name,"count") end +function context.newmuskip(name) return allocate(name,"muskip") end +function context.newtoks (name) return allocate(name,"toks") end +function context.newbox (name) return allocate(name,"box","mathchar") end diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 3c34ace37..7ed6ae120 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.08.16 22:20} +\newcontextversion{2012.08.25 12:53} %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/cont-new.mkiv b/tex/context/base/cont-new.mkiv index d2c59c9ad..a4f413280 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.08.16 22:20} +\newcontextversion{2012.08.25 12:53} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/cont-yes.mkiv b/tex/context/base/cont-yes.mkiv index 01ba88d49..ba6dc166d 100644 --- a/tex/context/base/cont-yes.mkiv +++ b/tex/context/base/cont-yes.mkiv @@ -20,11 +20,24 @@ -- When a style is loaded there is a good change that we never enter -- this code. - local arguments = environment.arguments - local filename = arguments.input or tex.jobname - local suffix = file.suffix(filename) + local arguments = environment.arguments - local filename = ctxrunner.resolve(filename) -- in case we're prepped + local jobname = arguments.jobname or tex.jobname + local fulljobname = arguments.fulljobname or jobname + local input = arguments.input or fulljobname + local result = arguments.result or file.removesuffix(jobname) + + local input = file.suffix(input) == "tex" and file.removesuffix(input) or input + + local filename = fulljobname + local suffix = file.suffix(filename) + + local filename = ctxrunner.resolve(filename) -- in case we're prepped + + commands.updatefilenames(jobname,input,result) -- job input output + +-- texio.write_nl(string.format("{jobname: %s, input: %s, result: %s}",jobname,input,result)) + commands.writestatus("files",string.format("jobname: %s, input: %s, result: %s",jobname,input,result)) if suffix == "xml" or arguments.forcexml then @@ -49,6 +62,12 @@ context.ctxlua(string.format('dofile("%s")',filename)) context.stoptext() + elseif suffix == "mp" or arguments.forcemp then + + context.starttext() + context.processMPfigurefile(filename) + context.stoptext() + -- elseif suffix == "prep" then -- -- -- Why do we wrap here. Because it can be xml? Let's get rid diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differdeleted file mode 100644 index e687c41b1..000000000 --- a/tex/context/base/context-version.pdf +++ /dev/null diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png Binary files differindex ca343017a..0933c9744 100644 --- a/tex/context/base/context-version.png +++ b/tex/context/base/context-version.png diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 5e210159a..7a6b5aa5b 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2012.08.16 22:20} +\edef\contextversion{2012.08.25 12:53} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index f33938f01..0f03278e3 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2012.08.16 22:20} +\edef\contextversion{2012.08.25 12:53} %D For those who want to use this: diff --git a/tex/context/base/core-sys.lua b/tex/context/base/core-sys.lua index ddcb6e938..8e4286cae 100644 --- a/tex/context/base/core-sys.lua +++ b/tex/context/base/core-sys.lua @@ -11,13 +11,28 @@ local suffix, basename, removesuffix = file.suffix, file.basename, file.removesu local environment = environment -function commands.updatefilenames(inputfilename,outputfilename) - environment.inputfilename = inputfilename or "" - environment.outputfilename = outputfilename or "" - environment.jobfilename = inputfilename or tex.jobname or "" +-- function commands.updatefilenames(inputfilename,outputfilename) +-- -- +-- environment.jobfilename = inputfilename or tex.jobname or "" +-- environment.jobfilesuffix = lower(suffix(environment.jobfilename)) +-- -- +-- environment.inputfilename = inputfilename or "" +-- environment.inputfilebarename = removesuffix(basename(inputfilename)) +-- environment.inputfilesuffix = lower(suffix(inputfilename)) +-- -- +-- environment.outputfilename = outputfilename or "" +-- end + +function commands.updatefilenames(jobname,inputfilename,outputfilename) + -- + environment.jobfilename = jobname or inputfilename or tex.jobname or "" environment.jobfilesuffix = lower(suffix(environment.jobfilename)) + -- + environment.inputfilename = inputfilename or "" environment.inputfilebarename = removesuffix(basename(inputfilename)) environment.inputfilesuffix = lower(suffix(inputfilename)) + -- + environment.outputfilename = outputfilename or environment.inputfilebarename or "" end statistics.register("result saved in file", function() diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv index 5a92ebf4f..25b656341 100644 --- a/tex/context/base/core-sys.mkiv +++ b/tex/context/base/core-sys.mkiv @@ -36,11 +36,21 @@ %D line ending. I hate this mess. \edef\operatingsystem {\cldcontext{os.platform}} + +%D The jobname is what gets loaded by the cont-yes stub file. This name +%D also determines the name of tuc etc files. + \def \jobfilename {\cldcontext{environment.jobfilename or ""}} \def \jobfilesuffix {\cldcontext{environment.jobfilesuffix or ""}} + +%D However, that one can itself load another file. + \def \inputfilebarename{\cldcontext{environment.inputfilebarename or ""}} \def \inputfilesuffix {\cldcontext{environment.inputfilesuffix or ""}} \def \inputfilename {\cldcontext{environment.inputfilename or ""}} + +%D The output name is only used for some checking. + \def \outputfilename {\cldcontext{environment.outputfilename or ""}} \installcorenamespace{system} @@ -48,9 +58,8 @@ \installdirectcommandhandler \??system {system} \appendtoks - \edef\outputresolution{\directsystemparameter\c!resolution}% - \edef\outputfilename {\directsystemparameter\c!file }% - \edef\inputfilename {\directsystemparameter\c!inputfile }% +% \edef\outputfilename {\directsystemparameter\c!file }% +% \edef\inputfilename {\directsystemparameter\c!inputfile }% \to \everysetupsystem \appendtoks @@ -75,9 +84,9 @@ \setsystemmode{suffix-\m_system_job_suffix}% \to \everysetupsystem -\appendtoks - \ctxcommand{updatefilenames("\inputfilename","\outputfilename")}% -\to \everysetupsystem +% \appendtoks +% \ctxcommand{updatefilenames("\jobame","\inputfilename","\outputfilename")}% +% \to \everysetupsystem % Some mechanisms (see x-res-01) use either \jobfilename or % \jobfilename.somesuffix, in which case we need to use the @@ -104,6 +113,10 @@ %D \NC \type{\operatingsystem} \NC \operatingsystem \NC \NR %D \stoptabulate +\appendtoks + \edef\outputresolution{\directsystemparameter\c!resolution}% +\to \everysetupsystem + %D The system modes set by the setup command can be used in %D situations like: %D @@ -138,9 +151,9 @@ [\c!directory=, \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run \c!resolution=600,% in dpi, no unit in mkiv - %c!random=, % obsolete here - \c!file=\jobname, - \c!inputfile=\outputfilename, + % \c!random=, % obsolete here + % \c!file=\jobname, + % \c!inputfile=\outputfilename, \c!type=unix, % windows is normally less sensitive to handle \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index ab64b99af..141f20cd3 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -30,7 +30,7 @@ local packers = utilities.packers local allocate = utilities.storage.allocate local mark = utilities.storage.mark -local report_jobcontrol = logs.reporter("jobcontrol") +local report_passes = logs.reporter("job","passes") job = job or { } local job = job @@ -176,7 +176,7 @@ local function load(filename) if data and data ~= "" then local version = tonumber(match(data,"^-- version: ([%d%.]+)")) if version ~= job.version then - report_jobcontrol("version mismatch with jobfile: %s <> %s", version or "?", job.version) + report_passes("version mismatch: %s <> %s", version or "?", job.version) else local data = loadstring(data) return data and data() diff --git a/tex/context/base/grph-epd.lua b/tex/context/base/grph-epd.lua index 130907d4e..4f9d46097 100644 --- a/tex/context/base/grph-epd.lua +++ b/tex/context/base/grph-epd.lua @@ -22,5 +22,4 @@ function figures.mergegoodies(optionlist) if all or options[variables.layer] then codeinjections.mergeviewerlayers() end - end diff --git a/tex/context/base/grph-fil.lua b/tex/context/base/grph-fil.lua index 1ec88b487..9cdda13e0 100644 --- a/tex/context/base/grph-fil.lua +++ b/tex/context/base/grph-fil.lua @@ -6,13 +6,13 @@ if not modules then modules = { } end modules ['grph-fil'] = { license = "see context related readme files" } -local format, concat = string.format, table.concat - -local trace_run = false trackers.register("graphic.runfile",function(v) trace_run = v end) +local type = type +local trace_run = false trackers.register("graphic.runfile",function(v) trace_run = v end) local report_run = logs.reporter("graphics","run") --- this code will move +-- Historically running files is part of graphics processing, so this is why it +-- sits here but is part of the job namespace. local allocate = utilities.storage.allocate @@ -22,6 +22,7 @@ local tobesaved = allocate() local jobfiles = { collected = collected, tobesaved = tobesaved, + forcerun = false, -- maybe a directive some day } job.files = jobfiles @@ -33,8 +34,6 @@ end job.register('job.files.collected', tobesaved, initializer) -jobfiles.forcerun = false - function jobfiles.run(name,action) local oldchecksum = collected[name] local newchecksum = file.checksum(name) diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index cb1fdbd8b..8ec319247 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -15,6 +15,7 @@ if not modules then modules = { } end modules ['grph-inc'] = { -- partly qualified -- dimensions -- consult rlx +-- use metatables -- figures.boxnumber can go as we now can use names @@ -68,7 +69,7 @@ local report_inclusion = logs.reporter("graphics","inclusion") local context, img = context, img ---- some extra img functions --- +--- some extra img functions --- can become luat-img.lua local imgkeys = img.keys() @@ -187,8 +188,7 @@ local magics = allocate { figures.formats = formats -- frozen figures.magics = magics -- frozen --- We can set the order but only indirectly so that we can --- check for support. +-- We can set the order but only indirectly so that we can check for support. function figures.setorder(list) -- can be table or string if type(list) == "string" then @@ -1190,6 +1190,7 @@ end local epsconverter = { } converters.eps = epsconverter +converters.ps = epsconverter programs.gs = { resolutions = { @@ -1471,12 +1472,11 @@ end -- end -- } - --- local fig = figures.push { name = pdffile } --- figures.identify() --- figures.check() --- local nofpages = fig.used.pages --- figures.pop() +-- local fig = figures.push { name = pdffile } +-- figures.identify() +-- figures.check() +-- local nofpages = fig.used.pages +-- figures.pop() -- interfacing diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv index e1f3b57e8..74f10b0b0 100644 --- a/tex/context/base/grph-inc.mkiv +++ b/tex/context/base/grph-inc.mkiv @@ -461,6 +461,12 @@ \let\figurescalexscale \figurexscale \let\figurescaleyscale \figureyscale +%D Abuse: +%D +%D \starttyping +%D \externalfigure[rubish.pdf] \ifcase\figurestatus\relax \ctxlua{os.exit(999)} \fi +%D \stoptyping + %D Calculating: % \enabletrackers[figures.conversion] diff --git a/tex/context/base/grph-raw.lua b/tex/context/base/grph-raw.lua index 361f6944d..4c5b031ea 100644 --- a/tex/context/base/grph-raw.lua +++ b/tex/context/base/grph-raw.lua @@ -10,9 +10,12 @@ if not modules then modules = { } end modules ['grph-raw'] = { -- her gnuplot project. It's somewhat premliminary code but it -- works ok for that purpose. +local tonumber = tonumber + local report_bitmap = logs.reporter("graphics","bitmaps") -local texsp = tex.sp +local context = context +local texsp = tex.sp function figures.bitmapimage(t) local data = t.data diff --git a/tex/context/base/grph-swf.lua b/tex/context/base/grph-swf.lua index 88eed021a..0d33d89aa 100644 --- a/tex/context/base/grph-swf.lua +++ b/tex/context/base/grph-swf.lua @@ -6,19 +6,20 @@ if not modules then modules = { } end modules ['grph-swf'] = { license = "see context related readme files" } +-- maybe: backends.codeinjections.insertswf + local sub, format, match, byte = string.sub, string.format, string.match, string.byte -local readstring, readnumber = io.readstring, io.readnumber local concat = table.concat local floor = math.floor local tonumber = tonumber -local tobitstring = number.tobitstring - -local todimen = number.todimen +local readstringr = io.readstring, io.readnumber +local readnumber = io.readstring, io.readnumber +local tobitstring = number.tobitstring +local todimen = number.todimen local nodeinjections = backends.nodeinjections - -local figures = figures -local context = context +local figures = figures +local context = context local function getheader(name) local f = io.open(name,"rb") diff --git a/tex/context/base/grph-trf.mkiv b/tex/context/base/grph-trf.mkiv index 128d28ac8..d907c1b0c 100644 --- a/tex/context/base/grph-trf.mkiv +++ b/tex/context/base/grph-trf.mkiv @@ -208,7 +208,7 @@ \def\grph_scale_rounded#1% {\expandafter\expandafter\expandafter\grph_scale_rounded_indeed - \expandafter\WITHOUTPT\the\dimexpr#1\points*100+32768sp\relax.\relax} + \expandafter\WITHOUTPT\the\dimexpr#1\points*100+32768\scaledpoint\relax.\relax} \def\grph_scale_rounded_indeed#1.#2\relax{#1} @@ -697,7 +697,7 @@ {\hbox} \def\grph_scale_fast_yes#1% - {\edef\finalscaleboxxscale{\withoutpt\the\dimexpr#1pt/1000\relax}% brrr + {\edef\finalscaleboxxscale{\withoutpt\the\dimexpr#1\onepoint/1000\relax}% brrr \let\finalscaleboxyscale\finalscaleboxxscale \dowithnextboxcs\grph_scale_fast_finish\hbox} @@ -706,6 +706,19 @@ \box\nextbox \endgroup} +\unexpanded\def\fastsxsy#1#2% + {\bgroup + \edef\p_sx{#1}% + \edef\p_sy{#2}% + \dowithnextboxcs\grph_scale_fast_sx_xy_finish\hbox} + +\def\grph_scale_fast_sx_xy_finish + {\grph_scale_check_sx_sy + \grph_scale_calculations_nop + \grph_scale_apply + \box\nextbox + \egroup} + %D \macros %D {clip, setupclipping} %D diff --git a/tex/context/base/grph-u3d.lua b/tex/context/base/grph-u3d.lua index f2baac2f3..529cd6188 100644 --- a/tex/context/base/grph-u3d.lua +++ b/tex/context/base/grph-u3d.lua @@ -8,17 +8,17 @@ if not modules then modules = { } end modules ['grph-u3d'] = { -- see lpdf-u3d.lua for comment +-- maybe: backends.codeinjections.insertu3d + local trace_inclusion = false trackers.register("figures.inclusion", function(v) trace_inclusion = v end) local report_u3d = logs.reporter("graphics","u3d") -local figures = figures - +local figures = figures +local context = context local nodeinjections = backends.nodeinjections local todimen = string.todimen --- maybe todo: backends.codeinjections.insertu3d - function figures.checkers.u3d(data) local dr, du, ds = data.request, data.used, data.status local width = todimen(dr.width or figures.defaultwidth) diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 652772d79..fee76ac4b 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -13,6 +13,8 @@ local lpeg = require("lpeg") -- tracing (only used when we encounter a problem in integration of lpeg in luatex) +-- some code will move to unicode and string + local report = texio and texio.write_nl or print -- Watch this: Lua does some juggling with replacement values and although lpeg itself is agnostic of @@ -75,7 +77,7 @@ local byte, char, gmatch, format = string.byte, string.char, string.gmatch, stri lpeg.patterns = lpeg.patterns or { } -- so that we can share local patterns = lpeg.patterns -local P, R, S, V, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local P, R, S, V, Ct, C, Cs, Cc, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp local lpegtype, lpegmatch = lpeg.type, lpeg.match local utfcharacters = string.utfcharacters @@ -304,6 +306,57 @@ function string.utfsplitlines(str) return lpegmatch(utflinesplitter,str or "") end +local utfcharsplitter_ows = utfbom^-1 * Ct(C(utf8char)^0) +local utfcharsplitter_iws = utfbom^-1 * Ct((whitespace^1 + C(utf8char))^0) + +function string.utfsplit(str,ignorewhitespace) -- new + if ignorewhitespace then + return lpegmatch(utfcharsplitter_iws,str or "") + else + return lpegmatch(utfcharsplitter_ows,str or "") + end +end + +-- inspect(string.utfsplit("a b c d")) +-- inspect(string.utfsplit("a b c d",true)) + +-- -- alternative 1: 0.77 +-- +-- local utfcharcounter = utfbom^-1 * Cs((utf8char/'!')^0) +-- +-- function string.utflength(str) +-- return #lpegmatch(utfcharcounter,str or "") +-- end +-- +-- -- alternative 2: 1.70 +-- +-- local n = 0 +-- +-- local utfcharcounter = utfbom^-1 * (utf8char/function() n = n + 1 end)^0 -- slow +-- +-- function string.utflength(str) +-- n = 0 +-- lpegmatch(utfcharcounter,str or "") +-- return n +-- end +-- +-- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047) + +local n = 0 + +local utfcharcounter = utfbom^-1 * Cs ( ( + Cp() * (lpeg.patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end + + Cp() * (lpeg.patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end + + Cp() * (lpeg.patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end + + Cp() * (lpeg.patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end +)^0 ) + +function string.utflength(str) + n = 0 + lpegmatch(utfcharcounter,str or "") + return n +end + --~ lpeg.splitters = cache -- no longer public local cache = { } @@ -392,33 +445,43 @@ function lpeg.replacer(one,two) if type(one) == "table" then local no = #one local p - if no > 0 then - for i=1,no do - local o = one[i] - local pp = P(o[1]) / o[2] + if no == 0 then + for k, v in next, one do + local pp = P(k) / v if p then p = p + pp else p = pp end end + return Cs((p + 1)^0) + elseif no == 1 then + local o = one[1] + one, two = P(o[1]), o[2] + return Cs(((1-one)^1 + one/two)^0) else - for k, v in next, one do - local pp = P(k) / v + for i=1,no do + local o = one[i] + local pp = P(o[1]) / o[2] if p then p = p + pp else p = pp end end + return Cs((p + 1)^0) end - return Cs((p + 1)^0) else + one = P(one) two = two or "" - return Cs((P(one)/two + 1)^0) + return Cs(((1-one)^1 + one/two)^0) end end +-- print(lpeg.match(lpeg.replacer("e","a"),"test test")) +-- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test")) +-- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test")) + local splitters_f, splitters_s = { }, { } function lpeg.firstofsplit(separator) -- always return value diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua index 7c9ce307b..04e849db1 100644 --- a/tex/context/base/l-os.lua +++ b/tex/context/base/l-os.lua @@ -25,6 +25,7 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute local os = os +local date = os.date local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch local concat = table.concat local random, ceil = math.random, math.ceil @@ -359,7 +360,7 @@ end local d function os.timezone(delta) - d = d or tonumber(tonumber(os.date("%H")-os.date("!%H"))) + d = d or tonumber(tonumber(date("%H")-date("!%H"))) if delta then if d > 0 then return format("+%02i:00",d) @@ -371,6 +372,13 @@ function os.timezone(delta) end end +local timeformat = format("%%s%s",os.timezone(true)) +local dateformat = "!%Y-%m-%d %H:%M:%S" + +function os.fulltime(t) + return format(timeformat,date(dateformat,t)) +end + local memory = { } local function which(filename) diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua index f4480e93c..4e68dc6e1 100644 --- a/tex/context/base/l-unicode.lua +++ b/tex/context/base/l-unicode.lua @@ -8,11 +8,27 @@ if not modules then modules = { } end modules ['l-unicode'] = { if not unicode then - unicode = { utf8 = { } } + unicode = { } + +end + +local unicode = unicode + +utf = utf or unicode.utf8 + +if not utf then + + utf8 = { } + unicode.utf8 = utf8 + utf = utf8 + +end + +if not utf.char then local floor, char = math.floor, string.char - function unicode.utf8.utfchar(n) + function utf.char(n) if n < 0x80 then return char(n) elseif n < 0x800 then @@ -47,10 +63,6 @@ if not unicode then end -local unicode = unicode - -utf = utf or unicode.utf8 - local concat = table.concat local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format @@ -481,3 +493,13 @@ patterns.validatedutf = validatedutf function string.validutf(str) return lpegmatch(validatedutf,str) end + + +utf.length = string.utflength +utf.split = string.utfsplit +utf.splitines = string.utfsplitlines +utf.valid = string.validutf + +if not utf.len then + utf.len = utf.length +end diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua index 9c7acce1f..ab5002881 100644 --- a/tex/context/base/l-url.lua +++ b/tex/context/base/l-url.lua @@ -77,9 +77,10 @@ setmetatable(escapes, { __index = function(t,k) return v end }) -local escaper = Cs((R("09","AZ","az") + P(" ")/"%%20" + S("-./_") + P(1) / escapes)^0) -- space happens most +local escaper = Cs((R("09","AZ","az")^1 + P(" ")/"%%20" + S("-./_")^1 + P(1) / escapes)^0) -- space happens most local unescaper = Cs((escapedchar + 1)^0) +lpegpatterns.urlunescaped = escapedchar lpegpatterns.urlescaper = escaper lpegpatterns.urlunescaper = unescaper diff --git a/tex/context/base/lang-frd.mkiv b/tex/context/base/lang-frd.mkiv new file mode 100644 index 000000000..716ff257d --- /dev/null +++ b/tex/context/base/lang-frd.mkiv @@ -0,0 +1,141 @@ +%D \module +%D [ file=lang-frd, +%D version=2004.01.15, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Language Frequency Table Data, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is experimental work! Old stuff, whenever I need it I might +%D do it in \LUA. + +% http://www.onzetaal.nl/advies/letterfreq.html + +\startcharactertable[nl] + \charfreq a 7.47 + \charfreq b 1.58 + \charfreq c 1.24 + \charfreq d 5.93 + \charfreq e 18.91 + \charfreq f .81 + \charfreq g 3.4 + \charfreq h 2.38 + \charfreq i 6.5 + \charfreq j 1.46 + \charfreq k 2.25 + \charfreq l 3.57 + \charfreq m 2.21 + \charfreq n 10.03 + \charfreq o 6.06 + \charfreq p 1.57 + \charfreq q .009 + \charfreq r 6.41 + \charfreq s 3.73 + \charfreq t 6.79 + \charfreq u 1.99 + \charfreq v 2.85 + \charfreq w 1.52 + \charfreq x .04 + \charfreq y .035 + \charfreq z 1.39 +\stopcharactertable + +% http://caislab.icu.ac.kr/course/2001/spring/ice605/down/010306.pdf + +% \startcharactertable[en] +% \charfreq a 8.2 +% \charfreq b 1.5 +% \charfreq c 2.8 +% \charfreq d 4.3 +% \charfreq e 12.7 +% \charfreq f 2.2 +% \charfreq g 2 +% \charfreq h 6.1 +% \charfreq i 7 +% \charfreq j .2 +% \charfreq k .8 +% \charfreq l 4 +% \charfreq m 2.4 +% \charfreq n 6.7 +% \charfreq o 7.5 +% \charfreq p 1.9 +% \charfreq q .1 +% \charfreq r 6 +% \charfreq s 6.3 +% \charfreq t 9.1 +% \charfreq u 2.8 +% \charfreq v 1 +% \charfreq w 2.3 +% \charfreq x .1 +% \charfreq y 2 +% \charfreq z .1 +% \stopcharactertable + +% http://www.blankenburg.de/gat/pages/fach/info/analyse2.htm + +\startcharactertable[en] + \charfreq a 8.04 + \charfreq b 1.54 + \charfreq c 3.06 + \charfreq d 3.99 + \charfreq e 12.51 + \charfreq f 2.3 + \charfreq g 1.96 + \charfreq h 5.49 + \charfreq i 7.26 + \charfreq j .16 + \charfreq k .67 + \charfreq l 4.14 + \charfreq m 2.53 + \charfreq n 7.09 + \charfreq o 7.6 + \charfreq p 2 + \charfreq q .11 + \charfreq r 6.12 + \charfreq s 6.54 + \charfreq t 9.25 + \charfreq u 2.71 + \charfreq v .99 + \charfreq w 1.92 + \charfreq x .19 + \charfreq y 1.73 + \charfreq z .09 +\stopcharactertable + +% http://www.blankenburg.de/gat/pages/fach/info/analyse2.htm + +\startcharactertable[de] + \charfreq a 6.47 + \charfreq b 1.93 + \charfreq c 2.68 + \charfreq d 4.83 + \charfreq e 17.48 + \charfreq f 1.65 + \charfreq g 3.06 + \charfreq h 4.23 + \charfreq i 7.73 + \charfreq j .27 + \charfreq k 1.46 + \charfreq l 3.49 + \charfreq m 2.58 + \charfreq n 9.84 + \charfreq o 2.98 + \charfreq p .96 + \charfreq q .02 + \charfreq r 7.54 + \charfreq s 6.83 + \charfreq t 6.13 + \charfreq u 4.17 + \charfreq v .94 + \charfreq w 1.48 + \charfreq x .04 + \charfreq y .08 + \charfreq z 1.14 +\stopcharactertable + +\endinput diff --git a/tex/context/base/lang-frq.mkiv b/tex/context/base/lang-frq.mkiv new file mode 100644 index 000000000..24f535296 --- /dev/null +++ b/tex/context/base/lang-frq.mkiv @@ -0,0 +1,233 @@ +%D \module +%D [ file=lang-frq, +%D version=2004.01.15, +%D title=\CONTEXT\ Language Macros, +%D subtitle=Frequency Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Language Macros / Frequency Tables} + +%D Some day I might redo this \LUA. But anyway, who uses it. It's rather +%D old code. + +\unprotect + +%M \usemodule[layout] + +%D \macros +%D {charwidthmethod} +%D +%D This module implements a method for determining the width of an +%D average character in a language. It uses the dimensions of the +%D current fonts. +%D +%D \def\ShwChrWd#1#2#3% +%D {\chardef\charwidthmethod#1\relax +%D \mainlanguage[#2#3]\the\dimexpr(\averagecharwidth)} +%D +%D \starttabulate[|c|c|c|c|c|c|] +%D \HL +%D \NC \NC\bf0=amount\NC\bf1=.5em\NC2=ex\NC\bf3=frequency\NC\bf4=list\NC\NR +%D \HL +%D \NC\bf en\NC\ShwChrWd0en\NC\ShwChrWd1en\NC\ShwChrWd2en\NC\ShwChrWd3en\NC\ShwChrWd4en\NC\NR +%D \NC\bf nl\NC\ShwChrWd0nl\NC\ShwChrWd1nl\NC\ShwChrWd2nl\NC\ShwChrWd3nl\NC\ShwChrWd4nl\NC\NR +%D \NC\bf de\NC\ShwChrWd0de\NC\ShwChrWd1de\NC\ShwChrWd2de\NC\ShwChrWd3de\NC\ShwChrWd4de\NC\NR +%D \HL +%D \stoptabulate +%D +%D Method~1 ignores the widths and assumes that each character has a +%D width of .5em, which is true for most monospaced fonts. Method~2 +%D takes the x as starting point, and assumes that it's height kind of +%D matches its width. Method~3 is the best one, and determines the +%D average width based on the language specific character table. +%D Method~4 is a mixture between the first two methods: character +%D specific widths applied to an equal distribution. Method~0 reports +%D the total count, which normally is~100. + +\chardef\charwidthmethod=3 % 0=amount 1=em 2=ex 3=frequency 4=flattened >4=ex + +%D \macros +%D {charwidthlanguage} +%D +%D The language used for the calculations is defined as: + +\def\charwidthlanguage{\currentmainlanguage} + +%D \macros +%D {charfreq} +%D +%D This method comes into action in the following macro: + +\def\charfreq#1 #2 % character fraction + {+(\ifcase\charwidthmethod + #2\dimexpr100\onepoint\relax + \or + #2\dimexpr\emwidth/2\relax + \or + #2\dimexpr\exheight\relax + \or + #2\fontcharwd\font`#1% + \or + \dimexpr100\fontcharwd\font`#1/\charactertsize\charwidthlanguage\relax % ugly hack + \else + #2\dimexpr\exheight\relax + \fi)} + +%D \macros +%D {startcharactertable} +%D +%D A frequency table is defined with the following macro. The \type +%D {charfreq} macro is used in this table. + +\installcorenamespace{frequencywidths} +\installcorenamespace{frequencycounts} + +\let\stopcharactertable\relax + +\unexpanded\def\startcharactertable[#1]#2\stopcharactertable % \dimexpr has fuzzy lookahead + {\startnointerference + \setgvalue{\??frequencywidths#1}{#2}% the width vector + \scratchcounter\zerocount \def\charfreq##1 ##2 {\advance\scratchcounter\plusone} #2% + \setxvalue{\??frequencycounts#1}{\the\scratchcounter}% the character count + \stopnointerference} + +%D \macros +%D {charactertable,charactertsize} +%D +%D The table content as well as the number of entries can be fetched with +%D the following two macros. The architecture of the table and calling +%D macro permits a fully expandable application. + +\def\charactertable#1% + {\csname\??frequencywidths\ifcsname\??frequencywidths#1\endcsname#1\else\s!en\fi\endcsname} + +\def\charactertsize#1% + {\csname\??frequencycounts\ifcsname\??frequencycounts#1\endcsname#1\else\s!en\fi\endcsname} + +%D Although it is of hardly any use, you can inherit a character table: +%D +%D \starttyping +%D \startcharactertable[cz] \charactertable{en} \stopcharactertable +%D \stoptyping + +\startcharactertable[en] + % empty +\stopcharactertable % kind of default + +%D \macros +%D {averagecharwidth} +%D +%D This macro reports the average width for the current main +%D language (\the \dimexpr (\averagecharwidth)). + +\def\averagecharwidth{\dimexpr(\zeropoint\charactertable\charwidthlanguage)/100\relax} + +\unexpanded\def\showcharfreq + {\hbox\bgroup + \charwidthlanguage:% + \dostepwiserecurse\zerocount\plusfour\plusone + {\chardef\charwidthmethod\recurselevel\relax + \enspace\recurselevel/\the\dimexpr(\averagecharwidth)}% + \egroup} + +%D Just for fun, we show a few frequency tables as graphic (\in {figure} +%D [fig:charfreq]). +%D +%D \startbuffer +%D \definepalet [charfreq] [en=darkred, nl=darkgreen, de=darkblue] +%D +%D \def\charfreq#1 #2 % +%D {\startMPdrawing +%D interim linejoin := butt ; +%D a := ASCII "#1" ; +%D if (a >= (ASCII "a")) and (a <= (ASCII "z")) : +%D draw ((0,#2*.25cm)--origin--(0,#2*.5cm)) +%D shifted (a*4mm+o,0) +%D withpen pencircle scaled .5mm +%D withcolor c; +%D fi ; +%D \stopMPdrawing} +%D +%D \resetMPdrawing +%D \startMPdrawing +%D numeric a, o ; a := o := 0 ; +%D color c ; c := .5white ; +%D string s ; s := "" ; +%D \stopMPdrawing +%D +%D \startMPdrawing o := 0mm ; c := \MPcolor{charfreq:en} ; \stopMPdrawing +%D \charactertable{en} +%D +%D \startMPdrawing o := 1mm ; c := \MPcolor{charfreq:nl} ; \stopMPdrawing +%D \charactertable{nl} +%D +%D \startMPdrawing o := 2mm ; c := \MPcolor{charfreq:de} ; \stopMPdrawing +%D \charactertable{de} +%D +%D \startMPdrawing +%D for a := ASCII "a" upto ASCII "z" : +%D draw textext.bot("\strut\tttf " & char a) shifted (a*4mm+1mm,-1mm) ; +%D endfor ; +%D \stopMPdrawing +%D +%D \MPdrawingdonetrue \getMPdrawing \resetMPdrawing +%D \stopbuffer +%D +%D \placefigure +%D [here] +%D [fig:charfreq] +%D {The character distributions for English, Dutch and German.} +%D {\getbuffer} +%D +%D A few samples of usage of this mechanism are shown below: +%D +%D \startbuffer +%D {\mainlanguage[en]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D {\mainlanguage[nl]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D {\mainlanguage[de]\hsize65\averagecharwidth\mainlanguage[en]\input ward \blank} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D Although the widthts differ, the consequenes for breaking the paragraph +%D into lines are minimal. + +%D \macros +%D {freezeaveragecharacterwidth} +%D +%D This macro can be used to make sure that the width does not change during a +%D page break when another font is used. + +\let\normalaveragecharacterwidth\averagecharacterwidth + +\unexpanded\def\freezeaveragecharacterwidth % global + {\xdef\averagecharacterwidth{\dimexpr\the\normalaveragecharacterwidth\relax}} + +%D Example: +%D +%D \starttyping +%D \input lang-frq.mkiv +%D \input lang-frd.mkiv +%D +%D \setupbodyfont +%D [dejavu] +%D +%D \setemeasure{textwidth}{\the\dimexpr70\averagecharwidth} +%D +%D \setuplayout +%D [width=\measure{textwidth}] +%D +%D \showframe +%D +%D \starttext +%D \input ward +%D \stoptext +%D \stoptyping + +\protect \endinput diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua index 01e226351..aee2c4edf 100644 --- a/tex/context/base/lpdf-ano.lua +++ b/tex/context/base/lpdf-ano.lua @@ -607,8 +607,8 @@ function executers.submitform(arguments) local flag = flags[formmethod] or flags.post flag = (flag and (flag[formformat] or flag.xml)) or 32 -- default: post, xml return pdfdictionary { - S = pdfconstant("ResetForm"), - F = fieldset(arguments[1]), + S = pdfconstant("SubmitForm"), + F = arguments[1], Field = fieldset(arguments[2]), Flags = flag, -- \PDFsubmitfiller diff --git a/tex/context/base/luat-bwc.lua b/tex/context/base/luat-bwc.lua index f893c7c5b..993de7bf3 100644 --- a/tex/context/base/luat-bwc.lua +++ b/tex/context/base/luat-bwc.lua @@ -27,6 +27,6 @@ if not tex.wd then __newindex = function(t,k,v) local bk = box[k] if bk then bk.depth = v end end, } ) ---~ tex.wd, tex.ht, tex.dp = wd, ht, dp + -- tex.wd, tex.ht, tex.dp = wd, ht, dp end diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua index 6622c64cd..c4f0aba02 100644 --- a/tex/context/base/luat-cbk.lua +++ b/tex/context/base/luat-cbk.lua @@ -34,10 +34,13 @@ functions.</p> local trace_callbacks = false trackers.register("system.callbacks", function(v) trace_callbacks = v end) local trace_calls = false -- only used when analyzing performance and initializations -local register_callback, find_callback, list_callbacks = callback.register, callback.find, callback.list +local register_callback = callback.register +local find_callback = callback.find +local list_callbacks = callback.list + local frozen, stack, list = { }, { }, callbacks.list -if not callbacks.list then -- otherwise counters get reset +if not list then -- otherwise counters get reset list = utilities.storage.allocate(list_callbacks()) @@ -113,15 +116,6 @@ function callbacks.report() end end -function callbacks.table() - local NC, NR, verbatim = context.NC, context.NR, context.type - context.starttabulate { "|l|l|p|" } - for name, _ in sortedhash(list) do - NC() verbatim(name) NC() verbatim(state(name)) NC() context(frozen[name] or "") NC() NR() - end - context.stoptabulate() -end - function callbacks.freeze(name,freeze) freeze = type(freeze) == "string" and freeze if find(name,"%*") then @@ -311,3 +305,16 @@ function garbagecollector.check(size,criterium) end end end + +-- this will move + +commands = commands or { } + +function commands.showcallbacks() + local NC, NR, verbatim = context.NC, context.NR, context.type + context.starttabulate { "|l|l|p|" } + for name, _ in sortedhash(list) do + NC() verbatim(name) NC() verbatim(state(name)) NC() context(frozen[name] or "") NC() NR() + end + context.stoptabulate() +end diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua index 815d7f92c..87b2c0059 100644 --- a/tex/context/base/luat-cod.lua +++ b/tex/context/base/luat-cod.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['luat-cod'] = { license = "see context related readme files" } +local type, loadfile = type, loadfile local match, gsub, find, format = string.match, string.gsub, string.find, string.format local texconfig, lua = texconfig, lua @@ -19,11 +20,13 @@ texconfig.max_in_open = 127 -- registering bytecode chunks -lua.bytecode = lua.bytecode or { } -- built in anyway -lua.bytedata = lua.bytedata or { } -lua.bytedone = lua.bytedone or { } +local bytecode = lua.bytecode or { } +local bytedata = lua.bytedata or { } +local bytedone = lua.bytedone or { } -local bytecode, bytedata, bytedone = lua.bytecode, lua.bytedata, lua.bytedone +lua.bytecode = bytecode -- built in anyway +lua.bytedata = bytedata +lua.bytedone = bytedone lua.firstbytecode = 501 lua.lastbytecode = lua.lastbytecode or (lua.firstbytecode - 1) -- as we load ourselves again ... maybe return earlier @@ -32,14 +35,16 @@ function lua.registeredcodes() return lua.lastbytecode - lua.firstbytecode + 1 end +-- no file.* functions yet + function lua.registercode(filename,version) local barename = gsub(filename,"%.[%a%d]+$","") if barename == filename then filename = filename .. ".lua" end local basename = match(barename,"^.+[/\\](.-)$") or barename - if not bytedone[barename] then + if not bytedone[basename] then local code = environment.luafilechunk(filename) if code then - bytedone[barename] = true + bytedone[basename] = true if environment.initex then local n = lua.lastbytecode + 1 bytedata[n] = { barename, version or "0.000" } @@ -53,10 +58,11 @@ end local finalizers = { } function lua.registerfinalizer(f,comment) + comment = comment or "unknown" if type(f) == "function" then finalizers[#finalizers+1] = { action = f, comment = comment } else - print(format("fatal error: invalid finalizer, action: %s",finalizer.comment or "unknown")) + texio.write_nl(format("fatal error: invalid finalizer, action: %s",comment)) os.exit() end end diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua index 6e31b5a98..4d9a44d42 100644 --- a/tex/context/base/luat-env.lua +++ b/tex/context/base/luat-env.lua @@ -275,9 +275,6 @@ end local function checkstrip(filename) local modu = modules[file.nameonly(filename)] --- if not modu then --- print(">>>>>>>>>>>>>>>>>>>>>>>>",filename) --- end return modu and modu.dataonly end diff --git a/tex/context/base/luat-fmt.lua b/tex/context/base/luat-fmt.lua index cfb9a0bb7..37b0f5166 100644 --- a/tex/context/base/luat-fmt.lua +++ b/tex/context/base/luat-fmt.lua @@ -110,7 +110,6 @@ function environment.make_format(name) end function environment.run_format(name,data,more) - -- hm, rather old code here; we can now use the file.whatever functions if name and name ~= "" then local barename = file.removesuffix(name) local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats") diff --git a/tex/context/base/luat-ini.lua b/tex/context/base/luat-ini.lua index 1f7cca4af..94c878eb1 100644 --- a/tex/context/base/luat-ini.lua +++ b/tex/context/base/luat-ini.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['luat-ini'] = { -- rather experimental down here ... will change with lua 5.2 -- -local debug = require "debug" +local debug = require("debug") + local string, table, lpeg, math, io, system = string, table, lpeg, math, io, system local next, setfenv = next, setfenv or debug.setfenv diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua index ce25d1f55..bcd9e2bdc 100644 --- a/tex/context/base/luat-run.lua +++ b/tex/context/base/luat-run.lua @@ -67,11 +67,11 @@ end local function report_output_log() end ---~ local function show_open() ---~ end +-- local function show_open() +-- end ---~ local function show_close() ---~ end +-- local function show_close() +-- end local function pre_dump_actions() lua.finalize(trace_lua_dump and report_lua or nil) @@ -84,8 +84,8 @@ end callbacks.register('start_run', start_run, "actions performed at the beginning of a run") callbacks.register('stop_run', stop_run, "actions performed at the end of a run") ---~ callbacks.register('show_open', show_open, "actions performed when opening a file") ---~ callbacks.register('show_close', show_close, "actions performed when closing a file") +---------.register('show_open', show_open, "actions performed when opening a file") +---------.register('show_close', show_close, "actions performed when closing a file") callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages") callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file") diff --git a/tex/context/base/luat-soc.lua b/tex/context/base/luat-soc.lua index 1095ed087..9342a4b33 100644 --- a/tex/context/base/luat-soc.lua +++ b/tex/context/base/luat-soc.lua @@ -1,11 +1,11 @@ -- This is just a loader. The package handler knows about the TEX tree. ---~ require "luatex/lua/socket.lua" ---~ require "luatex/lua/ltn12.lua" ---~ require "luatex/lua/mime.lua" ---~ require "luatex/lua/socket/http.lua" ---~ require "luatex/lua/socket/url.lua" ---~ require "luatex/lua/socket/tp.lua" ---~ require "luatex/lua/socket/ftp.lua" +-- require "luatex/lua/socket.lua" +-- require "luatex/lua/ltn12.lua" +-- require "luatex/lua/mime.lua" +-- require "luatex/lua/socket/http.lua" +-- require "luatex/lua/socket/url.lua" +-- require "luatex/lua/socket/tp.lua" +-- require "luatex/lua/socket/ftp.lua" --- "luatex/lua/socket/smtp.lua" +-- "luatex/lua/socket/smtp.lua" diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua index 97ae924a1..fecf42634 100644 --- a/tex/context/base/lxml-tab.lua +++ b/tex/context/base/lxml-tab.lua @@ -43,7 +43,7 @@ local utf = unicode.utf8 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, match, gsub = string.format, string.lower, string.find, string.match, string.gsub -local utfchar, utffind, utfgsub = utf.char, utf.find, utf.gsub +local utfchar, utfgsub = utf.char, utf.gsub local lpegmatch = lpeg.match local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs @@ -368,10 +368,8 @@ local privates_n = { local function escaped(s) if s == "" then return "" - else -- if utffind(s,privates_u) then + else return (utfgsub(s,".",privates_u)) - -- else - -- return s end end diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index b1b8998a5..cd4e03bd6 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -184,22 +184,43 @@ {\global\t_meta_instance\emptytoks \endgroup} +\def\meta_process_graphic_start + {\setbox\b_meta_graphic\hbox\bgroup} + +\def\meta_process_graphic_stop + {\egroup + \meta_place_graphic} + \unexpanded\def\meta_process_graphic#1% todo: extensions and inclusions outside beginfig {\meta_start_current_graphic \forgetall - \setbox\b_meta_graphic\hbox\bgroup % ; added 20100901 (as in mkii) + \meta_process_graphic_start \normalexpanded{\noexpand\ctxlua{metapost.graphic( "\currentMPinstance", "\currentMPformat", \!!bs#1;\!!es, \!!bs\meta_flush_current_initializations;\!!es, \!!bs\meta_flush_current_preamble;\!!es, - \MPaskedfigure + "\MPaskedfigure" )}}% - \egroup - \placeMPgraphic + \meta_process_graphic_stop \meta_stop_current_graphic} +\let\meta_process_graphic_figure_start\relax +\let\meta_process_graphic_figure_stop \relax + +\unexpanded\def\processMPfigurefile#1% special case: obeys beginfig .. endfig and makes pages + {\begingroup + \let\normal_meta_process_graphic_start\meta_process_graphic_start + \let\normal_meta_process_graphic_stop \meta_process_graphic_stop + \let\meta_process_graphic_start\relax + \let\meta_process_graphic_stop \relax + \def\meta_process_graphic_figure_start{\startTEXpage\normal_meta_process_graphic_start}% + \def\meta_process_graphic_figure_stop {\normal_meta_process_graphic_stop\stopTEXpage} + \def\MPaskedfigure{all}% + \meta_process_graphic{input "#1" ;}% + \endgroup} + \newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default \def\setMPrandomseed @@ -500,7 +521,7 @@ \let\meta_relocate_box\relax -\unexpanded\def\placeMPgraphic % the converter also displaces so in fact we revert +\unexpanded\def\meta_place_graphic % the converter also displaces so in fact we revert {\meta_relocate_box \box\b_meta_graphic} diff --git a/tex/context/base/mlib-pdf.mkiv b/tex/context/base/mlib-pdf.mkiv index b9871eead..68b4b922a 100644 --- a/tex/context/base/mlib-pdf.mkiv +++ b/tex/context/base/mlib-pdf.mkiv @@ -91,7 +91,8 @@ \def\MPLIBtoPDF#1{\ctxlua{metapost.flushliteral(#1)}} \def\startMPLIBtoPDF#1#2#3#4% - {\dostarttagged\t!mpgraphic\empty + {\meta_process_graphic_figure_start + \dostarttagged\t!mpgraphic\empty \naturalhbox attr \imageattribute 1 \bgroup \dousecolorparameter\s!black\forcecolorhack \setMPboundingbox{#1}{#2}{#3}{#4}% @@ -104,7 +105,8 @@ \finalizeMPbox \box\MPbox \egroup - \dostoptagged} + \dostoptagged + \meta_process_graphic_figure_stop} \def\MPLIBflushreset % This can (will) move to the Lua end. {\ctxlua{metapost.flushreset()}} diff --git a/tex/context/base/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv index cb6120066..704c9e635 100644 --- a/tex/context/base/mlib-pps.mkiv +++ b/tex/context/base/mlib-pps.mkiv @@ -64,13 +64,15 @@ \vbox to \zeropoint\bgroup \vss \hbox to \zeropoint \bgroup - \scale[\c!sx=#8,\c!sy=#9]{\raise\dp\MPtextbox\box\MPtextbox}% - \forcecolorhack % needed ? already in the scale macro - % % This gives: LuaTeX warning: Misplaced \pdfrestore .. don't ask me why. - % - % \dostartscaling{#8}{#9}% - % \raise\dp\MPtextbox\box\MPtextbox - % \dostopscaling +% \scale[\c!sx=#8,\c!sy=#9]{\raise\dp\MPtextbox\box\MPtextbox}% +% \scale[\c!sx=#8,\c!sy=#9,\c!depth=\v!no]{\box\MPtextbox}% + \fastsxsy{#8}{#9}{\raise\dp\MPtextbox\box\MPtextbox}% + % This gives: LuaTeX warning: Misplaced \pdfrestore .. don't ask me why. + % but I'll retry it some day soon. + % \dostartscaling{#8}{#9}% + % \raise\dp\MPtextbox\box\MPtextbox + % \dostopscaling + \forcecolorhack % needed ? already in the scale macro \hss \egroup \egroup diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv index eade6496c..34ccdbd3f 100644 --- a/tex/context/base/mult-def.mkiv +++ b/tex/context/base/mult-def.mkiv @@ -61,6 +61,7 @@ \def\v!shiftup {shiftup} \def\v!shiftdown {shiftdown} \def\v!construction {construction} +\def\v!unframed {unframed} \def\s!lcgreek {lcgreek} \def\s!ucgreek {ucgreek} diff --git a/tex/context/base/mult-ini.mkiv b/tex/context/base/mult-ini.mkiv index d01000f2a..eb5517277 100644 --- a/tex/context/base/mult-ini.mkiv +++ b/tex/context/base/mult-ini.mkiv @@ -829,7 +829,8 @@ \def\contextversion {unknown} \def\contextversionnumber{0} \else - \def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi#2\ifnum#3<10 0\fi#3 #4:#5} + %\def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi#2\ifnum#3<10 0\fi#3 #4:#5} + \def\contextversionnumber#1.#2.#3 #4:#5\relax{#1\ifnum#2<10 0\fi\purenumber{#2}\ifnum#3<10 0\fi\purenumber{#3} #4:#5} \edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark} \fi diff --git a/tex/context/base/mult-low.lua b/tex/context/base/mult-low.lua index 047b4bdbd..7d5078b60 100644 --- a/tex/context/base/mult-low.lua +++ b/tex/context/base/mult-low.lua @@ -223,7 +223,7 @@ return { -- "wait", "writestatus", "define", "redefine", -- - "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "measure", + "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", -- "getvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", diff --git a/tex/context/base/pack-mrl.mkiv b/tex/context/base/pack-mrl.mkiv index 2ba6434fa..1fc774ade 100644 --- a/tex/context/base/pack-mrl.mkiv +++ b/tex/context/base/pack-mrl.mkiv @@ -523,21 +523,43 @@ \def\pack_textrule_nop_indeed_nop {\csname\??textrulealternatives\v!bottom\endcsname\empty} +%D\startbuffer +%D\showstruts +%D +%D\setupwhitespace[none] +%D +%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test} +%D\textrule[top]{test} xxxxx\strut \textrule[bottom]{test} +%D +%D\setupwhitespace[big] +%D +%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test} +%D\textrule[top]{test} xxxxx\strut \textrule[bottom]{test} +%D\stoptyping +%D +%D \typebuffer \start \getbuffer \stop + \setvalue{\??textrulealternatives\v!top}#1% {\page[\v!preference] % interferes \directtextrulesparameter\c!before\relax + \blank[\v!samepage,\v!nowhite]% \pack_textrule_with_text{#1}% - \nowhitespace + \blank[\v!samepage,\v!nowhite]% \directtextrulesparameter\c!inbetween\relax \endgraf} \setvalue{\??textrulealternatives\v!bottom}#1% - {\pack_textrule_following{#1}% + {\blank[\v!samepage,\v!nowhite]% + \pack_textrule_following{#1}% + \blank[\v!samepage,\v!nowhite]% \directtextrulesparameter\c!after\relax \page[\v!preference]} \setvalue{\??textrulealternatives\v!middle}#1% - {\pack_textrule_following{#1}% + {\blank[\v!samepage,\v!nowhite]% + \directtextrulesparameter\c!inbetween\relax + \pack_textrule_following{#1}% + \blank[\v!samepage,\v!nowhite]% \directtextrulesparameter\c!inbetween\relax \page[\v!preference]} @@ -567,19 +589,20 @@ \noindent\box\scratchbox \egroup} +% \def\pack_textrule_correct_depth +% {\ifhmode +% \endgraf +% \fi +% \vskip\dimexpr \strutdp +.5\exheight +% \ifdim\prevdepth>\strutdp\else % was <\strutdp +% \ifdim\prevdepth>\zeropoint +% -\prevdepth +% \fi +% \fi +% \relax} + \def\pack_textrule_following#1% - {\ifhmode - \endgraf - \fi - \vskip\dimexpr \strutdp +.5\exheight - \ifdim\prevdepth>\strutdp\else % was <\strutdp - \ifdim\prevdepth>\zeropoint - -\prevdepth - \fi - \fi - \relax - \directtextrulesparameter\c!inbetween\relax - \doifelsenothing{#1} + {\doifelsenothing{#1} {\nointerlineskip \dontleavehmode\vbox {\color[\directtextrulesparameter\c!rulecolor] diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv index 13fc2486e..9eb44b747 100644 --- a/tex/context/base/pack-rul.mkiv +++ b/tex/context/base/pack-rul.mkiv @@ -2750,4 +2750,15 @@ \setuplinewidth [\v!medium] +%D A Goodie: + +\def\v!unframed{unframed} + +\defineframed + [\v!unframed] + [\c!frame=\v!off, + \c!rulethickness=\zeropoint, + \c!foregroundstyle=\framedparameter\c!style, + \c!foregroundcolor=\framedparameter\c!color] + \protect \endinput diff --git a/tex/context/base/page-app.mkiv b/tex/context/base/page-app.mkiv index abd3d0ae5..0cf83592d 100644 --- a/tex/context/base/page-app.mkiv +++ b/tex/context/base/page-app.mkiv @@ -34,6 +34,7 @@ [fittingpage] [\c!textstate=\v!empty, \c!doublesided=\v!no, + \c!location=\v!top, % no topskip \c!pagestate=\fittingpageparameter\c!pagestate]% \definelayout diff --git a/tex/context/base/page-mak.mkvi b/tex/context/base/page-mak.mkvi index 33039b83c..6120f56bb 100644 --- a/tex/context/base/page-mak.mkvi +++ b/tex/context/base/page-mak.mkvi @@ -117,17 +117,18 @@ \makeupparameter\c!bottom \egroup \strc_pagenumbers_page_state_push % new - \makeupparameter\c!before - \relax % to be sure we don't enter the \if - \ifdim\ht\b_page_makeup>\vsize - \ht\b_page_makeup\vsize % is already set to \textheight (maybe set dp to 0) - \fi - \setuppagenumber[\c!state=\makeupparameter\c!pagestate]% - \box\b_page_makeup - \the\t_page_makeup_every_setup - \page - \makeupparameter\c!after - \relax % to be sure we don't enter the \if + \makeupparameter\c!before\relax + \begingroup + \ifdim\ht\b_page_makeup>\vsize + \ht\b_page_makeup\vsize % is already set to \textheight (maybe set dp to 0) + \fi + \setuppagenumber[\c!state=\makeupparameter\c!pagestate]% + \doif{\makeupparameter\c!location}\v!top{\topskip\zeropoint}% + \box\b_page_makeup + \the\t_page_makeup_every_setup + \page + \endgroup + \makeupparameter\c!after\relax \ifdoublesided \ifodd\realpageno \else \getvalue{\??makeupdoublesided\makeupparameter\c!doublesided}% \fi \fi @@ -169,6 +170,7 @@ %\c!align=, %\c!before=, %\c!after=, + %\c!location=, \c!page=\v!right, \c!doublesided=\v!empty, \c!top=\vss, diff --git a/tex/context/base/page-sel.mkvi b/tex/context/base/page-sel.mkvi index da96bbb0f..1fe3f2f38 100644 --- a/tex/context/base/page-sel.mkvi +++ b/tex/context/base/page-sel.mkvi @@ -138,7 +138,7 @@ \advance\hsize -2\scratchoffset \externalfigure[#filename][\c!page=\recurselevel,#figuresettings,\c!scale=,\c!factor=\v!max,\c!offset=\v!overlay]% \else - \externalfigurefilename][\c!page=\recurselevel,#figuresettings,\c!offset=\v!overlay]% + \externalfigure[#filename][\c!page=\recurselevel,#figuresettings,\c!offset=\v!overlay]% \fi}}} \page} \egroup} diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index 8640ba825..a6181f5e4 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -527,7 +527,7 @@ local function numify(s) return utfchar(s) end -function sorters.strip(str) -- todo: only letters and such utf.gsub("([^%w%d])","") +function sorters.strip(str) -- todo: only letters and such if str then str = gsub(str,"\\[\"\'~^`]*","") -- \"e str = gsub(str,"\\%S*","") -- the rest diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua index be3a669b6..84cd7aa49 100644 --- a/tex/context/base/sort-lan.lua +++ b/tex/context/base/sort-lan.lua @@ -87,8 +87,20 @@ definitions['Duden'] = { replacements = { { "ß", 's' } }, } -definitions['de'] = { parent = 'default' } -- new german +-- definitions['de'] = { parent = 'default' } -- new german + +definitions['de'] = { + parent = 'default', + replacements = { + { "ä", 'ae' }, { "Ä", 'Ae' }, + { "ö", 'oe' }, { "Ö", 'Oe' }, + { "ü", 'ue' }, { "Ü", 'Ue' }, + { "ß", 's' }, + }, +} + definitions['deo'] = { parent = 'de' } -- old german + definitions['de-DE'] = { parent = 'de' } -- german - Germany definitions['de-CH'] = { parent = 'de' } -- german - Swiss diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 3bf7b15d5..524302525 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex 307ed299a..a30438a00 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/status-mkiv.lua b/tex/context/base/status-mkiv.lua index 75bc521f9..6690e7be6 100644 --- a/tex/context/base/status-mkiv.lua +++ b/tex/context/base/status-mkiv.lua @@ -1,4 +1,9 @@ return { + todo = { + category = "lua", + filename = "core-run", + status = "idea", + }, main = { { category = "mkiv", @@ -604,6 +609,18 @@ return { }, { category = "mkiv", + filename = "lang-frq", + loading = "on demand", + status = "okay", + }, + { + category = "mkiv", + filename = "lang-frd", + loading = "on demand", + status = "okay", + }, + { + category = "mkiv", filename = "lang-wrd", loading = "always", status = "okay", @@ -1191,7 +1208,7 @@ return { }, { category = "mkvi", - comment = "maybe some extensions and maybe delayed loading, needs checking", + comment = "maybe some extensions and delayed loading, needs checking", filename = "page-sel", loading = "always", status = "okay", @@ -1936,7 +1953,7 @@ return { }, { category = "mkiv", - comment = "more or less obsolete", + comment = "more or less obsolete", filename = "lang-spa", loading = "always", status = "okay", @@ -3202,37 +3219,45 @@ return { { category = "lua", filename = "grph-epd", - status = "todo", + loading = "grph-epd", + status = "okay", }, { category = "lua", filename = "grph-fil", - status = "todo", + loading = "grph-inc", + status = "okay", }, { category = "lua", filename = "grph-inc", + loading = "grph-inc", status = "todo", }, { category = "lua", filename = "grph-raw", - status = "todo", + loading = "grph-raw", + status = "okay", }, { category = "lua", filename = "grph-swf", - status = "todo", + loading = "grph-swf", + status = "okay", }, { category = "lua", filename = "grph-u3d", - status = "todo", + loading = "grph-u3d", + status = "okay", }, { category = "lua", + comment = "experiment with graphic magick library", filename = "grph-wnd", - status = "todo", + loading = "on demand", + status = "okay", }, { category = "lua", @@ -3456,100 +3481,104 @@ return { }, { category = "lua", + comment = "replacement code for wd/ht/dp", filename = "luat-bwc", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-cbk", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-cnf", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", comment = "maybe some code should move", filename = "luat-cod", loading = "luat-cod", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-env", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-exe", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-fio", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-fmt", loading = "on demand", - status = "todo", + status = "okay", }, { category = "lua", + comment = "will be upgraded when we have Lua 5.2", filename = "luat-ini", loading = "luat-lib", - status = "todo", + status = "pending", }, { category = "lua", filename = "luat-iop", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", + comment = "this is likely to change some day", filename = "luat-lua", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-mac", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-run", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", + comment = "related to the socket code", filename = "luat-soc", loading = "on demand", - status = "todo", + status = "pending", }, { category = "lua", filename = "luat-sta", loading = "on demand", - status = "todo", + status = "okay", }, { category = "lua", filename = "luat-sto", loading = "luat-lib", - status = "todo", + status = "okay", }, { category = "lua", diff --git a/tex/context/base/status-mkiv.tex b/tex/context/base/status-mkiv.tex index 48c36acfb..2fe00a8b9 100644 --- a/tex/context/base/status-mkiv.tex +++ b/tex/context/base/status-mkiv.tex @@ -267,37 +267,52 @@ context.stoptitle() - context.starttitle { title = "messy namespaces" } + if io.exists("status-namespaces.lua") then - local namespaces = dofile("status-namespaces.lua") + context.starttitle { title = "messy namespaces" } - for namespace, data in table.sortedhash(namespaces) do - if valid[namespace] then - else - context(namespace) + local namespaces = dofile("status-namespaces.lua") + + for namespace, data in table.sortedhash(namespaces) do + if valid[namespace] then + else + context(namespace) + end + context.par() end - context.par() + + context.stoptitle() + end - context.stoptitle() + if io.exists("status-registers.lua") then - context.starttitle { title = "messy registers" } + context.starttitle { title = "messy registers" } - local registers = dofile("status-registers.lua") + local registers = dofile("status-registers.lua") - for register, data in table.sortedhash(registers) do - context(register) - context.par() - for name in table.sortedhash(data) do - context.quad() - context.type(name) + for register, data in table.sortedhash(registers) do + context(register) + context.par() + for name in table.sortedhash(data) do + context.quad() + context.type(name) + context.par() + end context.par() end - context.par() + + context.stoptitle() + end + context.starttitle { title = "callbacks" } + + commands.showcallbacks() + context.stoptitle() \stopluacode + \stoptext diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index 734a17733..fce085916 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -328,7 +328,8 @@ \placecurrentformulanumber} \def\strc_formulas_handle_sub_numbering - {\doiftextelse\currentsubformulasuffix + {\let\strc_formulas_handle_sub_numbering\relax % else error: see math/numbering-001.tex + \doiftextelse\currentsubformulasuffix {\strc_counters_setown_sub\v!formula\plustwo\currentsubformulasuffix} {\strc_counters_increment_sub\v!formula\plustwo}% \placecurrentformulanumber} diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 626328b6d..ab2d366cc 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -29,6 +29,12 @@ local trace_analyzing = false trackers.register("structures.referencing.anal local trace_identifying = false trackers.register("structures.referencing.identifying", function(v) trace_identifying = v end) local trace_importing = false trackers.register("structures.referencing.importing", function(v) trace_importing = v end) +local check_duplicates = true + +directives.register("structures.referencing.checkduplicates", function(v) + check_duplicates = v +end) + local report_references = logs.reporter("references") local report_unknown = logs.reporter("unknown") local report_identifying = logs.reporter("references","identifying") @@ -283,7 +289,7 @@ function references.set(kind,prefix,tag,data) local n = 0 for ref in gmatch(tag,"[^,]+") do if ref ~= "" then - if pd[ref] then + if check_duplicates and pd[ref] then if prefix and prefix ~= "" then report_references("redundant reference: %q in namespace %q",ref,prefix) else diff --git a/tex/context/base/syst-aux.lua b/tex/context/base/syst-aux.lua index b04d11d89..cda340cb6 100644 --- a/tex/context/base/syst-aux.lua +++ b/tex/context/base/syst-aux.lua @@ -16,6 +16,7 @@ local commands, context = commands, context local settings_to_array = utilities.parsers.settings_to_array local concat = table.concat local format = string.format +local utfsub = utf.sub local P, C, Carg, lpegmatch, utf8char = lpeg.P, lpeg.C, lpeg.Carg, lpeg.match, lpeg.patterns.utf8char local setvalue = context.setvalue @@ -34,6 +35,10 @@ function commands.doiffirstcharelse(chr,str) commands.doifelse(lpegmatch(pattern,str) == chr) end +function commands.getsubstring(str,first,last) + context(utfsub(str,tonumber(first),tonumber(last))) +end + -- function commands.addtocommalist(list,item) -- if list == "" then -- context(item) diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index 8dd99fe83..815a26b33 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -6243,10 +6243,16 @@ \def\syst_helpers_define_measure[#1][#2]% {\expandafter\def\csname\??measure#1\endcsname{#2}} -\unexpanded\def\setmeasure #1#2{\expandafter\def \csname\??measure#1\endcsname{#2}} % quick way -\unexpanded\def\setemeasure#1#2{\expandafter\edef\csname\??measure#1\endcsname{#2}} % quick way -\unexpanded\def\setgmeasure#1#2{\expandafter\gdef\csname\??measure#1\endcsname{#2}} % quick way -\unexpanded\def\setxmeasure#1#2{\expandafter\xdef\csname\??measure#1\endcsname{#2}} % quick way +\unexpanded\def\freezemeasure + {\dodoubleargument\syst_helpers_freeze_measure} + +\def\syst_helpers_freede_measure[#1][#2]% + {\expandafter\edef\csname\??measure#1\endcsname{\the\dimexpr#2}} + +\unexpanded\def\setmeasure #1#2{\expandafter\def \csname\??measure#1\endcsname{#2}} % quick way +\unexpanded\def\setgmeasure#1#2{\expandafter\gdef\csname\??measure#1\endcsname{#2}} % quick way +\unexpanded\def\setemeasure#1#2{\expandafter\edef\csname\??measure#1\endcsname{\the\dimexpr#2}} % quick way +\unexpanded\def\setxmeasure#1#2{\expandafter\xdef\csname\??measure#1\endcsname{\the\dimexpr#2}} % quick way \def\measure#1% maybe \dimexpr ... \relax {\ifcsname\??measure#1\endcsname\csname\??measure#1\endcsname\else\zeropoint\fi} @@ -6789,6 +6795,27 @@ % \def\dimchoice#1#2{\syst_helpers_choice_dim{#1}#2{=#1}{#1}\empty} % \def\numchoice#1#2{\syst_helpers_choice_num{#1}#2{=#1}{#1}\empty} +%D \macros +%D {getsubstring} +%D \startbuffer +%D +%D \getsubstring{4}{}{Who Wants This} +%D \getsubstring{4}{9}{Who Wants This} +%D \getsubstring{9}{-2}{Who Wants This} +%D \getsubstring{1}{5}{Who Wants This} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlines +%D \getbuffer +%D \stoplines + +% expandable: + +%def\getsubstring#1#2#3{\cldcontext{utf.sub([[#3]],tonumber("#1"),tonumber("#2"))}} +\def\getsubstring#1#2#3{\ctxcommand{getsubstring(\!!bs#3\!!es,"#1","#2")}} + \protect \endinput % \edef\choicetokenyes{+} diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua index 4f5f6ed98..6ba3d348e 100644 --- a/tex/context/base/trac-inf.lua +++ b/tex/context/base/trac-inf.lua @@ -13,7 +13,7 @@ if not modules then modules = { } end modules ['trac-inf'] = { local format, lower = string.format, string.lower local clock = os.gettimeofday or os.clock -- should go in environment -local write_nl = texio.write_nl +local write_nl = texio and texio.write_nl or print statistics = statistics or { } local statistics = statistics diff --git a/tex/context/base/trac-lmx.lua b/tex/context/base/trac-lmx.lua index 4db9fde42..82b241688 100644 --- a/tex/context/base/trac-lmx.lua +++ b/tex/context/base/trac-lmx.lua @@ -114,6 +114,10 @@ function html.th(str) end end +function html.a(text,url) + result[#result+1] = format("<a href=%q>%s</a>",url,text) +end + setmetatableindex(html,function(t,k) local f = format("<%s>%%s</%s>",k,k) local v = function(str) result[#result+1] = format(f,str or "") end @@ -171,9 +175,9 @@ local function do_type(str) end end -local function do_fprint(...) +local function do_fprint(str,...) if str and str ~= "" then - result[#result+1] = format(...) + result[#result+1] = format(str,...) end end @@ -227,7 +231,9 @@ function lmx.initialize(d,v) setmetatableindex(d,lmxvariables) if variables ~= d then setmetatableindex(variables,d) - report_lmx("variables => given defaults => lmx variables") + if trace_variables then + report_lmx("variables => given defaults => lmx variables") + end elseif trace_variables then report_lmx("variables == given defaults => lmx variables") end @@ -257,7 +263,9 @@ function lmx.initialize(d,v) setmetatableindex(v,lmxvariables) if variables ~= v then setmetatableindex(variables,v) - report_lmx("variables => given variables => lmx variables") + if trace_variables then + report_lmx("variables => given variables => lmx variables") + end elseif trace_variables then report_lmx("variables == given variables => lmx variables") end @@ -279,7 +287,7 @@ function lmx.reset() -- obsolete end --- Creation: +-- Creation: (todo: strip <!-- -->) local template = [[ return function(defaults,variables) @@ -328,58 +336,63 @@ local function getdefinition(definitions,tag) return definitions[tag] or "" end -local whitespace = lpeg.patterns.whitespace^0 +local whitespace = lpeg.patterns.whitespace^0 + +local begincomment = P("<!--") +local endcomment = P("-->") -local beginembedxml = P("<?") -local endembedxml = P("?>") +local beginembedxml = P("<?") +local endembedxml = P("?>") -local beginembedcss = P("/*") -local endembedcss = P("*/") +local beginembedcss = P("/*") +local endembedcss = P("*/") -local gobbledend = (whitespace * endembedxml) / "" -local argument = (1-gobbledend)^0 +local gobbledend = (whitespace * endembedxml) / "" +local argument = (1-gobbledend)^0 -local beginluaxml = (beginembedxml * P("lua")) / "" -local endluaxml = endembedxml / "" +local comment = (begincomment * (1-endcomment)^0 * endcomment) / "" -local luacodexml = beginluaxml - * (1-endluaxml)^1 - * endluaxml +local beginluaxml = (beginembedxml * P("lua")) / "" +local endluaxml = endembedxml / "" -local beginluacss = (beginembedcss * P("lua")) / "" -local endluacss = endembedcss / "" +local luacodexml = beginluaxml + * (1-endluaxml)^1 + * endluaxml -local luacodecss = beginluacss - * (1-endluacss)^1 - * endluacss +local beginluacss = (beginembedcss * P("lua")) / "" +local endluacss = endembedcss / "" -local othercode = Cc(" p[==[") - * (1-beginluaxml-beginluacss)^1 - * Cc("]==] ") +local luacodecss = beginluacss + * (1-endluacss)^1 + * endluacss -local include = ((beginembedxml * P("lmx-include") * whitespace) / "") - * (argument / lmx.include) - * gobbledend +local othercode = Cc(" p[==[") + * (1-beginluaxml-beginluacss)^1 + * Cc("]==] ") -local define_b = ((beginembedxml * P("lmx-define-begin") * whitespace) / "") - * argument - * gobbledend +local include = ((beginembedxml * P("lmx-include") * whitespace) / "") + * (argument / lmx.include) + * gobbledend -local define_e = ((beginembedxml * P("lmx-define-end") * whitespace) / "") - * argument - * gobbledend +local define_b = ((beginembedxml * P("lmx-define-begin") * whitespace) / "") + * argument + * gobbledend -local define_c = C((1-define_e)^0) +local define_e = ((beginembedxml * P("lmx-define-end") * whitespace) / "") + * argument + * gobbledend -local define = (Carg(1) * C(define_b) * define_c * define_e) / savedefinition +local define_c = C((1-define_e)^0) -local resolve = ((beginembedxml * P("lmx-resolve") * whitespace) / "") - * ((Carg(1) * C(argument)) / getdefinition) - * gobbledend +local define = (Carg(1) * C(define_b) * define_c * define_e) / savedefinition -local pattern_1 = Cs((include + P(1))^0) -local pattern_2 = Cs((define + resolve + P(1))^0) -local pattern_3 = Cs((luacodexml + luacodecss + othercode)^0) +local resolve = ((beginembedxml * P("lmx-resolve") * whitespace) / "") + * ((Carg(1) * C(argument)) / getdefinition) + * gobbledend + +local pattern_1 = Cs((comment + include + P(1))^0) -- get rid of comments asap +local pattern_2 = Cs((define + resolve + P(1))^0) +local pattern_3 = Cs((luacodexml + luacodecss + othercode)^0) local cache = { } @@ -483,6 +496,31 @@ end lmx.convert = lmxconvert +-- helpers + +function lmx.color(r,g,b,a) + if r > 1 then + r = 1 + end + if g > 1 then + g = 1 + end + if b > 1 then + b = 1 + end + if not a then + a= 0 + elseif a > 1 then + a = 1 + end + if a > 0 then + return string.format("rgba(%s%%,%s%%,%s%%,%s)",r*100,g*100,b*100,a) + else + return string.format("rgb(%s%%,%s%%,%s%%)",r*100,g*100,b*100) + end +end + + -- these can be overloaded lmx.lmxfile = string.itself diff --git a/tex/context/base/typo-scr.mkiv b/tex/context/base/typo-scr.mkiv index c5e1ec5fb..6249c390a 100644 --- a/tex/context/base/typo-scr.mkiv +++ b/tex/context/base/typo-scr.mkiv @@ -233,9 +233,9 @@ \dostarttagged\t!subsup\currentlowmidhigh \uselowmidhighstyleandcolor\c!style\c!color \setstrut - \setbox\plustwo \hbox{\strut\dostarttagged\t!sub\empty#4\dostoptagged}% - \setbox\plusfour\hbox{\strut\dostarttagged\t!mid\empty#2\dostoptagged}% inefficient - \setbox\plussix \hbox{\strut\dostarttagged\t!sup\empty#3\dostoptagged}% + \setbox\plustwo \hbox{\strut\dostarttagged\t!sub\empty#2\dostoptagged}% + \setbox\plusfour\hbox{\strut\dostarttagged\t!mid\empty#3\dostoptagged}% inefficient + \setbox\plussix \hbox{\strut\dostarttagged\t!sup\empty#4\dostoptagged}% \scratchdimen \wd \ifdim\wd\plustwo>\wd\plusfour \ifdim\wd\plustwo>\wd\plussix @@ -251,9 +251,9 @@ \fi \fi \relax - \setbox\plustwo \hbox to \scratchdimen{\hss \box\plustwo \hss}% - \setbox\plusfour\hbox to \scratchdimen{\hss\raise\lowmidhighparameter\c!up \box\plusfour\hss}% - \setbox\plussix \hbox to \scratchdimen{\hss\lower\lowmidhighparameter\c!down\box\plussix \hss}% + \setbox\plustwo \hbox to \scratchdimen{\hss\lower\lowmidhighparameter\c!down\box\plustwo \hss}% + \setbox\plusfour\hbox to \scratchdimen{\hss \box\plusfour\hss}% + \setbox\plussix \hbox to \scratchdimen{\hss\raise\lowmidhighparameter\c!up \box\plussix \hss}% \wd\plustwo \zeropoint \wd\plusfour\zeropoint \box\plusfour diff --git a/tex/context/base/util-jsn.lua b/tex/context/base/util-jsn.lua index 6ca956c02..101a75d6b 100644 --- a/tex/context/base/util-jsn.lua +++ b/tex/context/base/util-jsn.lua @@ -107,7 +107,9 @@ local function tojson(value,t) -- we could optimize #t end t[#t+1] = "]" end - elseif kind == "string" or kind == "number" then + elseif kind == "string" then + t[#t+1] = format("%q",value) + elseif kind == "number" then t[#t+1] = value else t[#t+1] = tostring(value) diff --git a/tex/context/base/util-sql.lua b/tex/context/base/util-sql.lua index 1eabe3c31..9c1feba7f 100644 --- a/tex/context/base/util-sql.lua +++ b/tex/context/base/util-sql.lua @@ -13,10 +13,13 @@ if not modules then modules = { } end modules ['util-sql'] = { -- buffer template local format = string.format -local rawset, setmetatable = rawset, setmetatable -local P, V, C, Ct, Cc, Cg, Cf, patterns, lpegmatch = lpeg.P, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.patterns, lpeg.match +local rawset, setmetatable, loadstring = rawset, setmetatable, loadstring +local P, S, V, C, Cs, Ct, Cc, Cg, Cf, patterns, lpegmatch = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.patterns, lpeg.match +local concat = table.concat -local osclock = os.clock or os.time +local osclock = os.clock or os.time +local fastserialize = table.fastserialize +local lpegmatch = lpeg.match local trace_sql = false trackers.register("sql.trace",function(v) trace_sql = v end) local report_state = logs.reporter("sql") @@ -24,13 +27,8 @@ local report_state = logs.reporter("sql") utilities.sql = utilities.sql or { } local sql = utilities.sql -local separator = P("\t") -local newline = patterns.newline -local entry = C((1-separator-newline)^1) -- C 10% faster than C -local empty = Cc("") - -local getfirst = Ct( entry * (separator * (entry+empty))^0) + newline -local skipfirst = (1-newline)^1 * newline +local replacetemplate = utilities.templates.replace +local loadtemplate = utilities.templates.load local defaults = { __index = { @@ -49,59 +47,89 @@ local defaults = { __index = local engine = "mysql" local runners = { -- --defaults-extra-file="%inifile" - mysql = [[mysql --user="%username%" --password="%password%" --host="%host%" --port=%port% --database="%database%" < "%queryfile%" > "%resultfile%"]] + mysql = [[mysql --user="%username%" --password="%password%" --host="%host%" --port=%port% --database="%database%" < "%queryfile%" > "%resultfile%"]], +-- mysql = [[mysql --user="%username%" --password="%password%" --host="%host%" --port=%port% --database="%database%" < "%queryfile%"]], } +sql.runners = runners + -- Experiments with an p/action demonstrated that there is not much gain. We could do a runtime -- capture but creating all the small tables is not faster and it doesn't work well anyway. -local function splitdata(data) +local separator = P("\t") +local newline = patterns.newline +local entry = C((1-separator-newline)^0) -- C 10% faster than Cs +local empty = Cc("") + +local getfirst = Ct( entry * (separator * (entry+empty))^0) + newline +local skipfirst = (1-newline)^1 * newline +local getfirstline = C((1-newline)^0) + +local cache = { } + +local function splitdata(data) -- todo: hash on first line if data == "" then if trace_sql then report_state("no data") end return { }, { } end - local keys = lpegmatch(getfirst,data) or { } - if #keys == 0 then + local first = lpegmatch(getfirstline,data) + if not first then if trace_sql then - report_state("no banner") + report_state("no data") end return { }, { } end - -- quite generic, could be a helper - local p = nil - local n = #keys --- for i=1,n do --- local key = keys[i] --- if trace_sql then --- report_state("field %s has name %q",i,key) --- end --- local s = Cg(Cc(key) * entry) --- if p then --- p = p * s --- else --- p = s --- end --- if i < n then --- p = p * separator --- end --- end - for i=1,n do - local key = keys[i] - if trace_sql then - report_state("field %s has name %q",i,key) + local p = cache[first] + if p then + -- report_state("reusing: %s",first) + local entries = lpegmatch(p.parser,data) + return entries or { }, p.keys + elseif p == false then + return { }, { } + elseif p == nil then + local keys = lpegmatch(getfirst,first) or { } + if #keys == 0 then + if trace_sql then + report_state("no banner") + end + cache[first] = false + return { }, { } + end + -- quite generic, could be a helper + local n = #keys + if n == 0 then + report_state("no fields") + cache[first] = false + return { }, { } end - local s = Cg(Cc(key) * entry) - if p then - p = p * separator * s + if n == 1 then + local key = keys[1] + if trace_sql then + report_state("one field with name",key) + end + p = Cg(Cc(key) * entry) else - p = s + for i=1,n do + local key = keys[i] + if trace_sql then + report_state("field %s has name %q",i,key) + end + local s = Cg(Cc(key) * entry) + if p then + p = p * separator * s + else + p = s + end + end end + p = Cf(Ct("") * p,rawset) * newline^1 + p = skipfirst * Ct(p^0) + cache[first] = { parser = p, keys = keys } + local entries = lpegmatch(p,data) + return entries or { }, keys end - p = Cf(Ct("") * p,rawset) * newline^0 - local entries = lpegmatch(skipfirst * Ct(p^0),data) - return entries or { }, keys end -- I will add a bit more checking. @@ -133,9 +161,9 @@ end local function dataprepared(specification) local query = false if specification.template then - query = utilities.templates.replace(specification.template,specification.variables) + query = replacetemplate(specification.template,specification.variables) elseif specification.templatefile then - query = utilities.templates.load(specification.templatefile,specification.variables) + query = loadtemplate(specification.templatefile,specification.variables) end if query then io.savedata(specification.queryfile,query) @@ -147,7 +175,7 @@ local function dataprepared(specification) end local function datafetched(specification) - local command = utilities.templates.replace(runners[engine],specification) + local command = replacetemplate(runners[engine],specification) if trace_sql then local t = osclock() report_state("command: %s",command) @@ -155,6 +183,7 @@ local function datafetched(specification) report_state("fetchtime: %.3f sec",osclock()-t) -- not okay under linux else os.execute(command) +-- return os.resultof(command) end return true end @@ -203,6 +232,7 @@ function sql.fetch(specification) return end local data = dataloaded(specification) +-- local data = datafetched(specification) if not data then report("error in loading") return @@ -241,7 +271,7 @@ sql.splitdata = splitdata -- -- -- -- local data = utilities.sql.prepare { --- templatefile = "ld-003.sql", +-- templatefile = "test.sql", -- variables = { }, -- host = "...", -- username = "...", @@ -257,25 +287,49 @@ sql.splitdata = splitdata -- } -- -- local data = utilities.sql.prepare { --- templatefile = "ld-003.sql", +-- templatefile = "test.sql", -- variables = { }, -- presets = presets, -- } -- local data = utilities.sql.prepare { --- templatefile = "ld-003.sql", +-- templatefile = "test.sql", -- variables = { }, -- presets = dofile(...), -- } -- local data = utilities.sql.prepare { --- templatefile = "ld-003.sql", +-- templatefile = "test.sql", -- variables = { }, -- presets = "...", -- } -- -- -- +local e_pattern = lpeg.replacer { { '\\"','\\\\""' }, {'"','""'} } +local u_pattern = lpeg.replacer { { '\\\\','\\' } } + +function sql.escape(str) + return lpegmatch(e_replace,str) +end + +function sql.unescape(str) + return lpegmatch(u_replace,str) +end + +function sql.serialize(t) + return lpegmatch(e_pattern,fastserialize(t,"return")) +end + +function sql.deserialize(data) + data = lpegmatch(u_pattern,data) + data = data and loadstring(data) + data = data and data() + return data +end + +-- -- -- + if tex and tex.systemmodes then function sql.prepare(specification) diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index 28a6b8cc5..7dc9e09f8 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -10,10 +10,11 @@ utilities = utilities or {} utilities.tables = utilities.tables or { } local tables = utilities.tables -local format, gmatch, rep = string.format, string.gmatch, string.rep +local format, gmatch, rep, gsub = string.format, string.gmatch, string.rep, string.gsub local concat, insert, remove = table.concat, table.insert, table.remove local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring local type, next, rawset, tonumber = type, next, rawset, tonumber +local lpegmatch = lpeg.match function tables.definetable(target) -- defines undefined tables local composed, t, n = nil, { }, 0 @@ -166,3 +167,45 @@ function tables.encapsulate(core,capsule,protect) } ) end end + +local function serialize(t,r) -- no mixes + r[#r+1] = "{" + local n = #t + if n > 0 then + for i=1,n do + local v = t[i] + local tv = type(v) + if tv == "table" then + serialize(v,r) + elseif tv == "string" then + r[#r+1] = format("%q,",v) + elseif tv == "number" then + r[#r+1] = format("%s,",v) + elseif tv == "boolean" then + r[#r+1] = format("%s,",tostring(v)) + end + end + else + for k, v in next, t do + local tv = type(v) + if tv == "table" then + r[#r+1] = format("[%q]=",k) + serialize(v,r) + elseif tv == "string" then + r[#r+1] = format("[%q]=%q,",k,v) + elseif tv == "number" then + r[#r+1] = format("[%q]=%s,",k,v) + elseif tv == "boolean" then + r[#r+1] = format("[%q]=%s,",k,tostring(v)) + end + end + end + r[#r+1] = "}" + return r +end + +function table.fastserialize(t,prefix) + return concat(serialize(t,{ prefix })) +end + +-- inspect(table.fastserialize { a = 1, b = { 4, { 5, 6 } }, c = { d = 7 } }) diff --git a/tex/context/base/util-tpl.lua b/tex/context/base/util-tpl.lua index 09aed8a2c..61fbbd48e 100644 --- a/tex/context/base/util-tpl.lua +++ b/tex/context/base/util-tpl.lua @@ -19,6 +19,8 @@ local report_template = logs.reporter("template") local P, C, Cs, Carg, lpegmatch = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match +local replacer + local function replacekey(k,t) local v = t[k] if not v then @@ -30,7 +32,8 @@ local function replacekey(k,t) if trace_template then report_template("setting key %q to value %q",k,v) end - return v + -- return v + return lpegmatch(replacer,v,1,t) -- recursive end end @@ -43,17 +46,37 @@ local rightmarker = P("%") / "" local key = leftmarker * (C((1-rightmarker)^1 * Carg(1))/replacekey) * rightmarker local any = P(1) -local replacer = Cs((escape + key + any)^0) + replacer = Cs((escape + key + any)^0) -function templates.replace(str,mapping) - return mapping and lpegmatch(replacer,str,1,mapping) or str +local function replace(str,mapping) + if mapping then + return lpegmatch(replacer,str,1,mapping) or str + else + return str + end end +templates.replace = replace + function templates.load(filename,mapping) local data = io.loaddata(filename) or "" if mapping and next(mapping) then - return templates.replace(data,mapping) + return replace(data,mapping) else return data end end + +function templates.resolve(t,mapping) + if not mapping then + mapping = t + end + for k, v in next, t do + t[k] = replace(v,mapping) + end + return t +end + +-- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" })) +-- inspect(utilities.templates.resolve({ one = "%two%", two = "two" })) + diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua index 30e770190..bf4cae43f 100644 --- a/tex/context/base/x-mathml.lua +++ b/tex/context/base/x-mathml.lua @@ -12,7 +12,7 @@ local type, next = type, next local utf = unicode.utf8 local format, lower, find, gsub = string.format, string.lower, string.find, string.gsub local strip = string.strip -local utfchar, utffind, utfgmatch, utfgsub = utf.char, utf.find, utf.gmatch, utf.gsub +local utfchar, utfgsub = utf.char, utf.gsub local xmlsprint, xmlcprint, xmltext, xmlcontent = xml.sprint, xml.cprint, xml.text, xml.content local getid = lxml.getid local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues @@ -524,10 +524,7 @@ function mathml.mfenced(id) -- multiple separators elseif n == 1 then xmlsprint(collected[1]) -- to be checked else - local t = { } - for s in utfgmatch(separators,"[^%s]") do - t[#t+1] = s - end + local t = utf.split(separators,true) for i=1,n do xmlsprint(collected[i]) -- to be checked if i < n then @@ -646,8 +643,8 @@ function mathml.mcolumn(root) local tag = e.tg if tag == "mi" or tag == "mn" or tag == "mo" or tag == "mtext" then local str = xmltext(e) -str = gsub(str,"&.-;","") - for s in utfcharacters(str) do -- utf.gmatch(str,".") btw, the gmatch was bugged + str = gsub(str,"&.-;","") + for s in utfcharacters(str) do m[#m+1] = { tag, s } end if tag == "mn" then @@ -658,7 +655,7 @@ str = gsub(str,"&.-;","") end elseif tag == "mspace" or tag == "mline" then local str = e.at.spacing or "" - for s in utfcharacters(str) do -- utf.gmatch(str,".") btw, the gmatch was bugged + for s in utfcharacters(str) do m[#m+1] = { tag, s } end -- elseif tag == "mline" then diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 78606488a..f17a3e045 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 08/16/12 22:20:23 +-- merge date : 08/25/12 12:53:08 do -- begin closure to overcome local limits and interference @@ -1131,6 +1131,8 @@ local lpeg = require("lpeg") -- tracing (only used when we encounter a problem in integration of lpeg in luatex) +-- some code will move to unicode and string + local report = texio and texio.write_nl or print -- Watch this: Lua does some juggling with replacement values and although lpeg itself is agnostic of @@ -1193,7 +1195,7 @@ local byte, char, gmatch, format = string.byte, string.char, string.gmatch, stri lpeg.patterns = lpeg.patterns or { } -- so that we can share local patterns = lpeg.patterns -local P, R, S, V, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local P, R, S, V, Ct, C, Cs, Cc, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp local lpegtype, lpegmatch = lpeg.type, lpeg.match local utfcharacters = string.utfcharacters @@ -1422,6 +1424,57 @@ function string.utfsplitlines(str) return lpegmatch(utflinesplitter,str or "") end +local utfcharsplitter_ows = utfbom^-1 * Ct(C(utf8char)^0) +local utfcharsplitter_iws = utfbom^-1 * Ct((whitespace^1 + C(utf8char))^0) + +function string.utfsplit(str,ignorewhitespace) -- new + if ignorewhitespace then + return lpegmatch(utfcharsplitter_iws,str or "") + else + return lpegmatch(utfcharsplitter_ows,str or "") + end +end + +-- inspect(string.utfsplit("a b c d")) +-- inspect(string.utfsplit("a b c d",true)) + +-- -- alternative 1: 0.77 +-- +-- local utfcharcounter = utfbom^-1 * Cs((utf8char/'!')^0) +-- +-- function string.utflength(str) +-- return #lpegmatch(utfcharcounter,str or "") +-- end +-- +-- -- alternative 2: 1.70 +-- +-- local n = 0 +-- +-- local utfcharcounter = utfbom^-1 * (utf8char/function() n = n + 1 end)^0 -- slow +-- +-- function string.utflength(str) +-- n = 0 +-- lpegmatch(utfcharcounter,str or "") +-- return n +-- end +-- +-- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047) + +local n = 0 + +local utfcharcounter = utfbom^-1 * Cs ( ( + Cp() * (lpeg.patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end + + Cp() * (lpeg.patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end + + Cp() * (lpeg.patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end + + Cp() * (lpeg.patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end +)^0 ) + +function string.utflength(str) + n = 0 + lpegmatch(utfcharcounter,str or "") + return n +end + --~ lpeg.splitters = cache -- no longer public local cache = { } @@ -1510,33 +1563,43 @@ function lpeg.replacer(one,two) if type(one) == "table" then local no = #one local p - if no > 0 then - for i=1,no do - local o = one[i] - local pp = P(o[1]) / o[2] + if no == 0 then + for k, v in next, one do + local pp = P(k) / v if p then p = p + pp else p = pp end end + return Cs((p + 1)^0) + elseif no == 1 then + local o = one[1] + one, two = P(o[1]), o[2] + return Cs(((1-one)^1 + one/two)^0) else - for k, v in next, one do - local pp = P(k) / v + for i=1,no do + local o = one[i] + local pp = P(o[1]) / o[2] if p then p = p + pp else p = pp end end + return Cs((p + 1)^0) end - return Cs((p + 1)^0) else + one = P(one) two = two or "" - return Cs((P(one)/two + 1)^0) + return Cs(((1-one)^1 + one/two)^0) end end +-- print(lpeg.match(lpeg.replacer("e","a"),"test test")) +-- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test")) +-- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test")) + local splitters_f, splitters_s = { }, { } function lpeg.firstofsplit(separator) -- always return value |