From 68fde114493544244df1fddf2d72499cf67a764b Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Thu, 26 Mar 2015 20:15:06 +0100 Subject: 2015-03-26 19:21:00 --- tex/context/base/anch-bck.mkvi | 6 +- tex/context/base/anch-pgr.lua | 62 ++- tex/context/base/anch-pgr.mkiv | 10 +- tex/context/base/anch-pos.lua | 307 ++++++++----- tex/context/base/anch-pos.mkiv | 115 ++--- tex/context/base/anch-tab.mkiv | 8 +- tex/context/base/back-pdf.lua | 54 ++- tex/context/base/back-pdf.mkiv | 112 ++--- tex/context/base/buff-ini.lua | 278 ++++++++---- tex/context/base/buff-ini.mkiv | 69 ++- tex/context/base/buff-ver.lua | 91 +++- tex/context/base/buff-ver.mkiv | 101 ++--- tex/context/base/colo-ini.lua | 158 ++++++- tex/context/base/colo-ini.mkiv | 80 ++-- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4343 -> 4343 bytes tex/context/base/context.mkiv | 2 +- tex/context/base/file-ini.lua | 47 +- tex/context/base/file-ini.mkvi | 20 +- tex/context/base/font-ctx.lua | 497 ++++++++++++--------- tex/context/base/font-fea.mkvi | 24 +- tex/context/base/font-ini.mkvi | 117 ++--- tex/context/base/font-lib.mkvi | 2 +- tex/context/base/grph-inc.lua | 84 +++- tex/context/base/grph-inc.mkiv | 148 +++--- tex/context/base/l-lpeg.lua | 270 +++-------- tex/context/base/lang-hyp.lua | 1 + tex/context/base/lang-hyp.mkiv | 3 + tex/context/base/lxml-ini.mkiv | 224 +++++----- tex/context/base/math-ini.mkiv | 16 +- tex/context/base/math-map.lua | 33 +- tex/context/base/meta-ini.lua | 28 -- tex/context/base/meta-ini.mkiv | 106 +++-- tex/context/base/mlib-ctx.lua | 220 ++++++++- tex/context/base/mlib-pdf.lua | 51 +-- tex/context/base/mlib-pdf.mkiv | 59 ++- tex/context/base/mlib-pps.lua | 62 ++- tex/context/base/mlib-pps.mkiv | 12 +- tex/context/base/mult-ini.lua | 52 ++- tex/context/base/mult-ini.mkiv | 20 +- tex/context/base/node-fin.lua | 12 +- tex/context/base/node-fin.mkiv | 6 +- tex/context/base/node-shp.lua | 11 +- tex/context/base/pack-obj.lua | 67 ++- tex/context/base/pack-obj.mkiv | 8 +- tex/context/base/publ-aut.lua | 48 +- tex/context/base/publ-dat.lua | 14 +- tex/context/base/publ-imp-apa.mkvi | 2 +- tex/context/base/publ-imp-default.mkvi | 6 +- tex/context/base/publ-ini.lua | 405 +++++++++-------- tex/context/base/publ-ini.mkiv | 280 ++++++------ tex/context/base/publ-reg.lua | 29 +- tex/context/base/regi-ini.lua | 32 +- tex/context/base/regi-ini.mkiv | 32 +- tex/context/base/s-fonts-ligatures.mkiv | 2 +- tex/context/base/s-languages-hyphenation.lua | 16 +- tex/context/base/s-languages-hyphenation.mkiv | 6 +- tex/context/base/spac-ver.lua | 63 ++- tex/context/base/spac-ver.mkiv | 22 +- tex/context/base/status-files.pdf | Bin 24641 -> 24664 bytes tex/context/base/status-lua.pdf | Bin 398039 -> 399807 bytes tex/context/base/strc-con.mkvi | 98 ++-- tex/context/base/strc-doc.lua | 173 +++++-- tex/context/base/strc-doc.mkiv | 7 +- tex/context/base/strc-lst.lua | 263 +++++++++-- tex/context/base/strc-lst.mkvi | 157 +++---- tex/context/base/strc-mar.lua | 39 +- tex/context/base/strc-mar.mkiv | 36 +- tex/context/base/strc-num.lua | 120 +++-- tex/context/base/strc-num.mkiv | 403 ++++++++--------- tex/context/base/strc-pag.lua | 58 ++- tex/context/base/strc-pag.mkiv | 37 +- tex/context/base/strc-ref.lua | 35 +- tex/context/base/strc-ref.mkvi | 2 +- tex/context/base/strc-reg.lua | 2 +- tex/context/base/strc-reg.mkiv | 2 +- tex/context/base/strc-sbe.mkiv | 6 +- tex/context/base/strc-sec.mkiv | 253 +++++++---- tex/context/base/strc-syn.lua | 50 ++- tex/context/base/strc-syn.mkiv | 98 ++-- tex/context/base/strc-tag.lua | 83 +++- tex/context/base/strc-tag.mkiv | 28 +- tex/context/base/supp-ran.lua | 42 +- tex/context/base/supp-ran.mkiv | 20 +- tex/context/base/x-asciimath.lua | 10 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 88 ++-- 86 files changed, 4127 insertions(+), 2595 deletions(-) (limited to 'tex') diff --git a/tex/context/base/anch-bck.mkvi b/tex/context/base/anch-bck.mkvi index cccf14ee4..273cf0159 100644 --- a/tex/context/base/anch-bck.mkvi +++ b/tex/context/base/anch-bck.mkvi @@ -20,10 +20,6 @@ \unprotect -% we can flush 5 in one call (saved 4 lua calls) .. brrr wself .. will change - -\def\MPposset#1{\ctxcommand{MPposset("#1")}} % will go - % This might be overloaded later on: % \defineoverlay[\v!text-2][\positionoverlay{\v!text-2}] @@ -50,7 +46,7 @@ % tricky: we need to catch newly set! otherwise an old run can have positions \unexpanded\def\anch_backgrounds_text_initialize - {\ctxcommand{doifelsepositionsused()}\enableparpositions\donothing + {\doifelsepositionsused\enableparpositions\donothing \global\let\anch_backgrounds_text_initialize\relax} \appendtoks diff --git a/tex/context/base/anch-pgr.lua b/tex/context/base/anch-pgr.lua index 84d0f6939..dc1597665 100644 --- a/tex/context/base/anch-pgr.lua +++ b/tex/context/base/anch-pgr.lua @@ -8,8 +8,6 @@ if not modules then modules = { } end modules ['anch-pgr'] = { -- todo: we need to clean up lists (of previous pages) -local commands, context = commands, context - local format = string.format local abs = math.abs local concat, sort = table.concat, table.sort @@ -19,6 +17,15 @@ local lpegmatch = lpeg.match local jobpositions = job.positions local formatters = string.formatters +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer +local scandimen = scanners.dimen + +local scanners = interfaces.scanners + +local commands = commands +local context = context local report_graphics = logs.reporter("graphics") @@ -603,13 +610,18 @@ backgrounds.point = f_point backgrounds.pair = f_pair backgrounds.path = f_path -function commands.fetchmultipar(n,anchor,page) - context(fetchmultipar(n,anchor,page)) -end +-- scanners.fetchmultipar = function() -- n anchor page +-- context(fetchmultipar(scanstring(),scanstring(),scaninteger())) +-- end +-- +-- scanners.fetchmultishape = function() -- n anchor page +-- context(fetchmultipar(scanstring(),scanstring(),scaninteger(),true)) +-- end -function commands.fetchmultishape(n,anchor,page) - context(fetchmultipar(n,anchor,page,true)) -end +-- n anchor page + +scanners.fetchmultipar = tokens.compile { actions = { fetchmultipar, context }, arguments = { "string", "string", "integer" } } +scanners.fetchmultishape = tokens.compile { actions = { fetchmultipar, context }, arguments = { "string", "string", "integer", true } } local f_template_a = [[ path posboxes[], posregions[] ; @@ -628,7 +640,10 @@ posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; f_template_a = formatters[f_template_a] f_template_b = formatters[f_template_b] -function commands.fetchposboxes(tags,anchor,page) -- no caching (yet) / todo: anchor, page +scanners.fetchposboxes = function() -- tags anchor page -- no caching (yet) / todo: anchor, page + local tags = scanstring() + local anchor = scanstring() + local page = scaninteger() local collected = jobpositions.collected if type(tags) == "string" then tags = utilities.parsers.settings_to_array(tags) @@ -665,20 +680,23 @@ end local doifelse = commands.doifelse -function commands.doifelsemultipar(n,page,obeyhang) - local data = pbg[n] - if not data then - data = calculatemultipar(n,obeyhang) - pbg[n] = data - end - if page then - doifelse(data and data[page] and true) - else - doifelse(data and next(data) and true) - end -end +-- function commands.doifelsemultipar(n,page,obeyhang) +-- local data = pbg[n] +-- if not data then +-- data = calculatemultipar(n,obeyhang) +-- pbg[n] = data +-- end +-- if page then +-- doifelse(data and data[page] and true) +-- else +-- doifelse(data and next(data) and true) +-- end +-- end -function commands.doifelserangeonpage(first,last,page) +scanners.doifelserangeonpage = function() -- first last page + local first = scanstring() + local last = scanstring() + local page = scaninteger() local collected = jobpositions.collected local f = collected[first] if not f or f.p == true then diff --git a/tex/context/base/anch-pgr.mkiv b/tex/context/base/anch-pgr.mkiv index c18a1b669..9b0151a81 100644 --- a/tex/context/base/anch-pgr.mkiv +++ b/tex/context/base/anch-pgr.mkiv @@ -261,7 +261,7 @@ \setbox\scratchbox\hbox to \overlaywidth{\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}% \ht\scratchbox\overlayheight \dp\scratchbox\zeropoint - \ctxcommand{markregionbox(\number\scratchbox,"\MPanchorid")}% needs an hbox + \anch_mark_tagged_box\scratchbox\MPanchorid % needs an hbox \box\scratchbox \vfill}} @@ -475,7 +475,7 @@ {\handlepositionaction\anch_positions_meta_graphic_handle_range_indeed\with{#1}{#2}{#3}{#4}\on{#2}} \def\anch_positions_meta_graphic_insert_range#1#2#3#4% pos pos tag setups - {\ctxcommand{doifelserangeonpage("#1","#2",\number\realpageno)}% + {\clf_doifelserangeonpage{#1}{#2}\realpageno {\def\currentposition{#1}% \MPpositiongraphic{#3}{#4}}% {}} @@ -497,8 +497,8 @@ % Helpers: -\def\MPgetposboxes #1#2{\ctxcommand{fetchposboxes("#1","#2",\the\realpageno)}} -\def\MPgetmultipars #1#2{\ctxcommand{fetchmultipar("#1","#2",\the\realpageno)}} -\def\MPgetmultishapes#1#2{\ctxcommand{fetchmultishape("#1","#2",\the\realpageno)}} +\def\MPgetposboxes #1#2{\clf_fetchposboxes {#1}{#2}\realpageno} +\def\MPgetmultipars #1#2{\clf_fetchmultipar {#1}{#2}\realpageno} +\def\MPgetmultishapes#1#2{\clf_fetchmultishape{#1}{#2}\realpageno} \protect \endinput diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua index 1f366121d..f9c061e92 100644 --- a/tex/context/base/anch-pos.lua +++ b/tex/context/base/anch-pos.lua @@ -29,6 +29,14 @@ local lpegmatch = lpeg.match local insert, remove = table.insert, table.remove local allocate, mark = utilities.storage.allocate, utilities.storage.mark +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer +local scandimen = scanners.dimen + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + local commands = commands local context = context @@ -295,31 +303,31 @@ local function get(id,index) end end --- local function get(id,index) -- ,key --- local data --- if index then --- local container = collected[id] --- if container then --- data = container[index] --- if not data then --- -- nothing --- elseif type(data) == "table" then --- return data --- else --- return { [key] = data } --- end --- end --- else --- return collected[id] --- end --- end - jobpositions.setdim = setdim jobpositions.setall = setall jobpositions.set = set jobpositions.get = get -commands.setpos = setall +-- scanners.setpos = setall + +-- trackers.enable("tokens.compi*") + +-- something weird: the compiler fails us here + +scanners.dosaveposition = compilescanner { + actions = setall, -- name p x y + arguments = { "string", "integer", "dimen", "dimen" } +} + +scanners.dosavepositionwhd = compilescanner { -- somehow fails + actions = setall, -- name p x y w h d + arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen" } +} + +scanners.dosavepositionplus = compilescanner { + actions = setall, -- name p x y w h d extra + arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen", "string" } +} -- will become private table (could also become attribute driven but too nasty -- as attributes can bleed e.g. in margin stuff) @@ -348,18 +356,26 @@ function jobpositions.e_col(tag) column = columns[#columns] end -function commands.bcolumn(tag,register) -- name will change +scanners.bposcolumn = function() -- tag + local tag = scanstring() insert(columns,tag) column = tag - if register then - context(new_latelua_node(f_b_column(tag))) - end end -function commands.ecolumn(register) -- name will change - if register then - context(new_latelua_node(f_e_column())) - end +scanners.bposcolumnregistered = function() -- tag + local tag = scanstring() + insert(columns,tag) + column = tag + context(new_latelua_node(f_b_column(tag))) +end + +scanners.eposcolumn = function() + remove(columns) + column = columns[#columns] +end + +scanners.eposcolumnregistered = function() + context(new_latelua_node(f_e_column())) remove(columns) column = columns[#columns] end @@ -385,7 +401,7 @@ function jobpositions.e_region(correct) region = regions[#regions] end -function jobpositions.markregionbox(n,tag,correct) +local function markregionbox(n,tag,correct) if not tag or tag == "" then nofregions = nofregions + 1 tag = f_region(nofregions) @@ -419,18 +435,21 @@ function jobpositions.markregionbox(n,tag,correct) setfield(box,"list",push) end +jobpositions.markregionbox = markregionbox + function jobpositions.enhance(name) enhance(tobesaved[name]) end -function commands.pos(name,t) - tobesaved[name] = t - context(new_latelua_node(f_enhance(name))) -end +-- scanners.pos = function(name,t) -- name t +-- local name = scanstring() +-- tobesaved[name] = scanstring() +-- context(new_latelua_node(f_enhance(name))) +-- end local nofparagraphs = 0 -function commands.parpos() -- todo: relate to localpar (so this is an intermediate variant) +scanners.parpos = function() -- todo: relate to localpar (so this is an intermediate variant) nofparagraphs = nofparagraphs + 1 texsetcount("global","c_anch_positions_paragraph",nofparagraphs) local strutbox = getbox("strutbox") @@ -473,7 +492,8 @@ function commands.parpos() -- todo: relate to localpar (so this is an intermedia context(new_latelua_node(f_enhance(tag))) end -function commands.posxy(name) -- can node.write be used here? +scanners.dosetposition = function() -- name + local name = scanstring() tobesaved[name] = { p = true, c = column, @@ -485,38 +505,58 @@ function commands.posxy(name) -- can node.write be used here? context(new_latelua_node(f_enhance(name))) end -function commands.poswhd(name,w,h,d) +scanners.dosetpositionwhd = function() -- name w h d extra + local name = scanstring() tobesaved[name] = { p = true, c = column, r = true, x = true, y = true, - w = w, - h = h, - d = d, + w = scandimen(), + h = scandimen(), + d = scandimen(), n = nofparagraphs > 0 and nofparagraphs or nil, } context(new_latelua_node(f_enhance(name))) end -function commands.posplus(name,w,h,d,extra) +scanners.dosetpositionbox = function() -- name box + local name = scanstring() + local box = getbox(scaninteger()) tobesaved[name] = { p = true, c = column, r = true, x = true, y = true, - w = w, - h = h, - d = d, + w = getfield(box,"width"), + h = getfield(box,"height"), + d = getfield(box,"depth"), n = nofparagraphs > 0 and nofparagraphs or nil, - e = extra, } context(new_latelua_node(f_enhance(name))) end -function commands.posstrut(name,w,h,d) +scanners.dosetpositionplus = function() -- name w h d extra + local name = scanstring() + tobesaved[name] = { + p = true, + c = column, + r = true, + x = true, + y = true, + w = scandimen(), + h = scandimen(), + d = scandimen(), + n = nofparagraphs > 0 and nofparagraphs or nil, + e = scanstring(), + } + context(new_latelua_node(f_enhance(name))) +end + +scanners.dosetpositionstrut = function() -- name + local name = scanstring() local strutbox = getbox("strutbox") tobesaved[name] = { p = true, @@ -768,11 +808,23 @@ jobpositions.onsamepage = onsamepage -- interface -commands.replacepospxywhd = jobpositions.replace -commands.copyposition = jobpositions.copy +scanners.replacepospxywhd = function() -- name page x y w h d + collected[scanstring()] = { + p = scaninteger(), + x = scandimen(), + y = scandimen(), + w = scandimen(), + h = scandimen(), + d = scandimen(), + } +end -function commands.MPp(id) - local jpi = collected[id] +scanners.copyposition = function() -- target source + collected[scanstring()] = collected[scanstring()] +end + +scanners.MPp = function() -- name + local jpi = collected[scanstring()] if jpi then local p = jpi.p if p and p ~= true then @@ -783,8 +835,8 @@ function commands.MPp(id) context('0') end -function commands.MPx(id) - local jpi = collected[id] +scanners.MPx = function() -- name + local jpi = collected[scanstring()] if jpi then local x = jpi.x if x and x ~= true and x ~= 0 then @@ -795,8 +847,8 @@ function commands.MPx(id) context('0pt') end -function commands.MPy(id) - local jpi = collected[id] +scanners.MPy = function() -- name + local jpi = collected[scanstring()] if jpi then local y = jpi.y if y and y ~= true and y ~= 0 then @@ -807,8 +859,8 @@ function commands.MPy(id) context('0pt') end -function commands.MPw(id) - local jpi = collected[id] +scanners.MPw = function() -- name + local jpi = collected[scanstring()] if jpi then local w = jpi.w if w and w ~= 0 then @@ -819,8 +871,8 @@ function commands.MPw(id) context('0pt') end -function commands.MPh(id) - local jpi = collected[id] +scanners.MPh = function() -- name + local jpi = collected[scanstring()] if jpi then local h = jpi.h if h and h ~= 0 then @@ -831,8 +883,8 @@ function commands.MPh(id) context('0pt') end -function commands.MPd(id) - local jpi = collected[id] +scanners.MPd = function() -- name + local jpi = collected[scanstring()] if jpi then local d = jpi.d if d and d ~= 0 then @@ -843,8 +895,8 @@ function commands.MPd(id) context('0pt') end -function commands.MPxy(id) - local jpi = collected[id] +scanners.MPxy = function() -- name + local jpi = collected[scanstring()] if jpi then context('(%.5Fpt,%.5Fpt)', jpi.x*pt, @@ -855,8 +907,8 @@ function commands.MPxy(id) end end -function commands.MPll(id) - local jpi = collected[id] +scanners.MPll = function() -- name + local jpi = collected[scanstring()] if jpi then context('(%.5Fpt,%.5Fpt)', jpi.x *pt, @@ -867,8 +919,8 @@ function commands.MPll(id) end end -function commands.MPlr(id) - local jpi = collected[id] +scanners.MPlr = function() -- name + local jpi = collected[scanstring()] if jpi then context('(%.5Fpt,%.5Fpt)', (jpi.x + jpi.w)*pt, @@ -879,8 +931,8 @@ function commands.MPlr(id) end end -function commands.MPur(id) - local jpi = collected[id] +scanners.MPur = function() -- name + local jpi = collected[scanstring()] if jpi then context('(%.5Fpt,%.5Fpt)', (jpi.x + jpi.w)*pt, @@ -891,8 +943,8 @@ function commands.MPur(id) end end -function commands.MPul(id) - local jpi = collected[id] +scanners.MPul = function() -- name + local jpi = collected[scanstring()] if jpi then context('(%.5Fpt,%.5Fpt)', jpi.x *pt, @@ -922,10 +974,12 @@ local function MPpos(id) context('0,0,0,0,0,0') -- for mp only end -commands.MPpos = MPpos +scanners.MPpos = function() -- name + MPpos(scanstring()) +end -function commands.MPn(id) - local jpi = collected[id] +scanners.MPn = function() -- name + local jpi = collected[scanstring()] if jpi then local n = jpi.n if n then @@ -936,8 +990,8 @@ function commands.MPn(id) context(0) end -function commands.MPc(id) - local jpi = collected[id] +scanners.MPc = function() -- name + local jpi = collected[scanstring()] if jpi then local c = jpi.c if c and p ~= true then @@ -948,8 +1002,8 @@ function commands.MPc(id) context(c) -- number end -function commands.MPr(id) - local jpi = collected[id] +scanners.MPr = function() -- name + local jpi = collected[scanstring()] if jpi then local r = jpi.r if r and p ~= true then @@ -979,29 +1033,32 @@ local function MPpardata(n) end end -commands.MPpardata = MPpardata +scanners.MPpardata = function() -- name + MPpardata(scanstring()) +end -function commands.MPposset(id) -- special helper, used in backgrounds - local b = f_b_tag(id) - local e = f_e_tag(id) - local w = f_w_tag(id) +scanners.MPposset = function() -- name (special helper, used in backgrounds) + local name = scanstring() + local b = f_b_tag(name) + local e = f_e_tag(name) + local w = f_w_tag(name) local p = f_p_tag(jobpositions.n(b)) MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p) end -function commands.MPls(id) - local t = collected[id] - if t then - context("%.5Fpt",t.ls*pt) +scanners.MPls = function() -- name + local jpi = collected[scanstring()] + if jpi then + context("%.5Fpt",jpi.ls*pt) else context("0pt") end end -function commands.MPrs(id) - local t = collected[id] - if t then - context("%.5Fpt",t.rs*pt) +scanners.MPrs = function() -- name + local jpi = collected[scanstring()] + if jpi then + context("%.5Fpt",jpi.rs*pt) else context("0pt") end @@ -1009,8 +1066,10 @@ end local splitter = lpeg.tsplitat(",") -function commands.MPplus(id,n,default) - local jpi = collected[id] +scanners.MPplus = function() -- name n default + local jpi = collected[scanstring()] + local n = scaninteger() + local default = scanstring() if jpi then local e = jpi.e if e then @@ -1026,59 +1085,71 @@ function commands.MPplus(id,n,default) context(default) end -function commands.MPrest(id,default) - local jpi = collected[id] +scanners.MPrest = function() -- name default + local jpi = collected[scanstring()] + local default = scanstring() context(jpi and jpi.e or default) end -function commands.MPxywhd(id) - local t = collected[id] - if t then +scanners.MPxywhd = function() -- name + local jpi = collected[scanstring()] + if jpi then context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt", - t.x*pt, - t.y*pt, - t.w*pt, - t.h*pt, - t.d*pt + jpi.x*pt, + jpi.y*pt, + jpi.w*pt, + jpi.h*pt, + jpi.d*pt ) else context("0,0,0,0,0") -- for mp only end end -local doif, doifelse = commands.doif, commands.doifelse +local doif = commands.doif +local doifelse = commands.doifelse -function commands.doifpositionelse(name) - doifelse(collected[name]) +scanners.doifpositionelse = function() -- name + doifelse(collected[scanstring()]) end -function commands.doifposition(name) - doif(collected[name]) +scanners.doifposition = function() -- name + doif(collected[scanstring()]) end -function commands.doifpositiononpage(name,page) -- probably always realpageno - local c = collected[name] - doifelse(c and c.p == page) +scanners.doifpositiononpageelse = function() -- name page -- probably always realpageno + local c = collected[scanstring()] + local p = scaninteger() + doifelse(c and c.p == p) end -function commands.doifoverlappingelse(one,two,overlappingmargin) - doifelse(overlapping(one,two,overlappingmargin)) +scanners.doifoverlappingelse = function() -- one two + doifelse(overlapping(scanstring(),scanstring())) end -function commands.doifpositionsonsamepageelse(list,page) - doifelse(onsamepage(list)) +scanners.doifpositionsonsamepageelse = function() -- list + doifelse(onsamepage(scanstring())) end -function commands.doifpositionsonthispageelse(list) - doifelse(onsamepage(list,tostring(texgetcount("realpageno")))) +scanners.doifpositionsonthispageelse = function() -- list + doifelse(onsamepage(scanstring(),tostring(texgetcount("realpageno")))) end -function commands.doifelsepositionsused() +scanners.doifelsepositionsused = function() doifelse(next(collected)) end -commands.markcolumnbox = jobpositions.markcolumnbox -commands.markregionbox = jobpositions.markregionbox +scanners.markregionbox = function() -- box + markregionbox(scaninteger()) +end + +scanners.markregionboxtagged = function() -- box tag + markregionbox(scaninteger(),scanstring()) +end + +scanners.markregionboxcorrected = function() -- box tag + markregionbox(scaninteger(),scanstring(),true) +end -- statistics (at least for the moment, when testing) diff --git a/tex/context/base/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv index 516f695f8..ef47da594 100644 --- a/tex/context/base/anch-pos.mkiv +++ b/tex/context/base/anch-pos.mkiv @@ -32,17 +32,15 @@ %D \dosetpositionplus {identifier} {width} {height} {depth} {list} %D \stoptyping -\def\dosaveposition #1#2#3#4{\ctxcommand{setpos("#1",\number#2,\number\dimexpr#3,\number\dimexpr#4)}} -\def\dosavepositionwhd #1#2#3#4#5#6#7{\ctxcommand{setpos("#1",\number#2,\number\dimexpr#3,\number\dimexpr#4,\number\dimexpr#5,\number\dimexpr#6,\number\dimexpr#7)}} -\def\dosavepositionplus#1#2#3#4#5#6#7#8{\ctxcommand{setpos("#1",\number#2,\number\dimexpr#3,\number\dimexpr#4,\number\dimexpr#5,\number\dimexpr#6,\number\dimexpr#7,"#8")}} +\def\dosaveposition #1#2#3#4{\clf_dosaveposition {#1}#2 #3 #4\relax} +\def\dosavepositionwhd #1#2#3#4#5#6#7{\clf_dosavepositionwhd {#1}#2 #3 #4 #5 #6 #7\relax} +\def\dosavepositionplus#1#2#3#4#5#6#7#8{\clf_dosavepositionplus{#1}#2 #3 #4 #5 #6 #7{#8}} -\def\dosetposition #1{\ctxcommand{posxy("#1")}} -\def\dosetpositionwhd #1#2#3#4{\ctxcommand{poswhd("#1",\number\dimexpr#2,\number\dimexpr#3,\number\dimexpr#4)}} -\def\dosetpositionplus#1#2#3#4#5{\ctxcommand{posplus("#1",\number\dimexpr#2,\number\dimexpr#3,\number\dimexpr#4,"#5")}} -\def\dosetpositionbox #1#2{\ctxcommand{poswhd("#1",\number\wd#2,\number\ht#2,\number\dp#2)}} -\def\dosetpositionstrut #1{\ctxcommand{posstrut("#1")}} - -\unexpanded\def\doifelsepositionsused{\ctxcommand{doifelsepositionsused()}} +\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands +\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax} +\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}} +\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax} +\def\dosetpositionstrut #1{\clf_dosetpositionstrut{#1}} \newbox\b_anch_position \newif \ifpositioning % sort of public @@ -50,7 +48,7 @@ %D Sometimes we want to trick the position handler a bit: \def\replacepospxywhd#1#2#3#4#5#6#7% when used we can better make a helper - {\ctxcommand{replacepospxywhd('#1',\number#2,\number\dimexpr#3,\number\dimexpr#4,\number\dimexpr#5,\number\dimexpr#6,\number\dimexpr#7)}} + {\clf_replacepospxywhd{#1}#2 #3 #4 #5 #6 #7\relax} %D \macros %D {MPp, MPx, MPy, MPw, MPh, MPd, MPxy, MPll, MPlr, MPur, MPul, MPpos, MPanchor} @@ -58,28 +56,35 @@ %D Access to the positional information is provided by macros with short names %S that are clearly meant for \METAPOST\ but nowadays also used for other purposes. -\def\MPp #1{\ctxcommand{MPp("#1")}} \let\MPpage \MPp -\def\MPr #1{\ctxcommand{MPr("#1")}} \let\MPregion \MPr -\def\MPc #1{\ctxcommand{MPc("#1")}} \let\MPcolumn \MPc -\def\MPn #1{\ctxcommand{MPn("#1")}} \let\MPparagraph\MPn -\def\MPx #1{\ctxcommand{MPx("#1")}} -\def\MPy #1{\ctxcommand{MPy("#1")}} -\def\MPw #1{\ctxcommand{MPw("#1")}} % first we need to replace \MPwidth etc -\def\MPh #1{\ctxcommand{MPh("#1")}} -\def\MPd #1{\ctxcommand{MPd("#1")}} -\def\MPxy #1{\ctxcommand{MPxy("#1")}} -\def\MPll #1{\ctxcommand{MPll("#1")}} -\def\MPlr #1{\ctxcommand{MPlr("#1")}} -\def\MPur #1{\ctxcommand{MPur("#1")}} -\def\MPul #1{\ctxcommand{MPul("#1")}} -\def\MPpos #1{\ctxcommand{MPpos("#1")}} \let\MPanchor\MPpos % overloaded locally when needed -\def\MPe #1{\ctxcommand{MPe("#1")}} - -\def\MPls #1{\ctxcommand{MPls("#1")}} \let\MPleftskip\MPls % compatible feature -\def\MPrs #1{\ctxcommand{MPrs("#1")}} \let\MPrightkip\MPrs % compatible feature - -\def\MPpardata#1{\ctxcommand{MPpardata("#1")}} -\def\MPxywhd #1{\ctxcommand{MPxywhd("#1")}} +\def\MPp #1{\clf_MPp {#1}} +\def\MPr #1{\clf_MPr {#1}} +\def\MPc #1{\clf_MPc {#1}} +\def\MPn #1{\clf_MPn {#1}} +\def\MPx #1{\clf_MPx {#1}} +\def\MPy #1{\clf_MPy {#1}} +\def\MPw #1{\clf_MPw {#1}} +\def\MPh #1{\clf_MPh {#1}} +\def\MPd #1{\clf_MPd {#1}} +\def\MPxy #1{\clf_MPxy {#1}} +\def\MPll #1{\clf_MPll {#1}} +\def\MPlr #1{\clf_MPlr {#1}} +\def\MPur #1{\clf_MPur {#1}} +\def\MPul #1{\clf_MPul {#1}} +\def\MPpos #1{\clf_MPpos {#1}} +\def\MPls #1{\clf_MPls {#1}} +\def\MPrs #1{\clf_MPrs {#1}} +\def\MPpardata#1{\clf_MPpardata{#1}} +\def\MPxywhd #1{\clf_MPxywhd {#1}} +\def\MPposset #1{\clf_MPposset {#1}} + +\let\MPpage \MPp +\let\MPregion \MPr +\let\MPcolumn \MPc +\let\MPparagraph\MPn + +\let\MPanchor \MPpos % overloaded locally when needed +\let\MPleftskip \MPls % compatible feature +\let\MPrightkip \MPrs % compatible feature %D \macros %D {MPplus, MPrest, MPv, MPvv} @@ -100,8 +105,8 @@ %D %D The extra parameters are not treated. -\def\MPplus#1#2#3{\ctxcommand{MPplus("#1",#2,"#3")}} \let\MPv \MPplus -\def\MPrest #1#2{\ctxcommand{MPrest("#1","#2")}} \let\MPvv\MPrest +\def\MPplus#1#2#3{\clf_MPplus{#1}#2{#3}} \let\MPv \MPplus +\def\MPrest #1#2{\clf_MPrest{#1}{#2}} \let\MPvv\MPrest %D There are two low level positioning macros. Both store the position as well %D as execute an action associated with that position. @@ -250,9 +255,11 @@ \newcount\c_anch_column % will be delegated to lua \newcount\c_anch_text % will be delegated to lua +% beware we need to pass \somethingexpanded or { } + \unexpanded\def\anch_mark_column_box#1% {\global\advance\c_anch_column\plusone - \ctxcommand{markregionbox(\number#1,"columnarea:\the\c_anch_column")}} % extra height + \clf_markregionboxtagged#1{columnarea:\the\c_anch_column}} % extra height \unexpanded\def\anch_mark_region_box {\iftrialtypesetting @@ -264,27 +271,27 @@ \fi\fi} \unexpanded\def\anch_mark_region_box_indeed#1% - {\ctxcommand{markregionbox(\number#1)}} + {\clf_markregionbox#1\relax} \unexpanded\def\anch_mark_flow_box#1% will be extended / renamed {\hbox\bgroup \global\advance\c_anch_text\plusone - \ctxcommand{markregionbox(\number#1,"textarea:\the\c_anch_text")}% + \clf_markregionboxtagged#1{textarea:\the\c_anch_text}% \box#1% \egroup} +\unexpanded\def\anch_mark_tagged_box#1#2% + {\clf_markregionboxtagged#1{#2}} + \unexpanded\def\anch_mark_flow_only#1% will be extended / renamed {\global\advance\c_anch_text\plusone - \ctxcommand{markregionbox(\number#1,"textarea:\the\c_anch_text",true)}} + \clf_markregionboxcorrected#1{textarea:\the\c_anch_text}} \unexpanded\def\anch_make_page_box#1% maybe like text - {\ctxcommand{markregionbox(\number#1,"\pageanchor")}} % needs an hbox + {\clf_markregionboxtagged#1{page:\the\realpageno}} % needs an hbox \unexpanded\def\anch_mark_text_box#1% - {\ctxcommand{markregionbox(\number#1,"\textanchor")}} % needs an hbox - -\unexpanded\def\anch_mark_tagged_box#1#2% - {\ctxcommand{markregionbox(\number#1,"#2")}} % needs an hbox + {\clf_markregionboxtagged#1{text:\the\realpageno}} % needs an hbox %D We can copy a position with: %D @@ -294,7 +301,8 @@ %D %D Again, this is a global operation. -\def\copyposition#1#2{\ctxcommand{copyposition('#1','#2')}} +\unexpanded\def\copyposition#1#2% + {\clf_copyposition{#1}{#2}} %D The fact that handling positions is a two pass operation, is one of the %D reasons why we need to be able to test for existence, using: @@ -303,8 +311,9 @@ %D \doifpositionelse {identifier} {found action} {not found action} %D \stoptyping -\def\doifpositionelse#1{\ctxcommand{doifpositionelse('#1')}} -\def\doifposition #1{\ctxcommand{doifposition('#1')}} +\unexpanded\def\doifpositionelse #1{\clf_doifpositionelse {#1}} +\unexpanded\def\doifposition #1{\clf_doifposition {#1}} +\unexpanded\def\doifpositiononpageelse#1#2{\clf_doifpositiononpageelse{#1}#2\relax} %D \macros %D {xypos} @@ -357,7 +366,7 @@ \fi} \def\anch_positions_register_par_options_normal - {\dontleavehmode\ctxcommand{parpos()}} + {\dontleavehmode\clf_parpos} \def\anch_positions_register_par_options_traced {\anch_positions_register_par_options_normal @@ -412,7 +421,7 @@ %D {action when not overlapping} %D \stoptyping -\def\doifoverlappingelse#1#2{\ctxcommand{doifoverlappingelse("#1","#2")}} +\unexpanded\def\doifoverlappingelse#1#2{\clf_doifoverlappingelse{#1}{#2}} %D \macros %D {doifpositionsonsamepageelse, @@ -430,7 +439,11 @@ %D {action when not on this page} %D \stoptyping -\def\doifpositionsonsamepageelse#1{\ctxcommand{doifpositionsonsamepageelse("#1")}} -\def\doifpositionsonthispageelse#1{\ctxcommand{doifpositionsonthispageelse("#1")}} +\unexpanded\def\doifpositionsonsamepageelse#1{\clf_doifpositionsonsamepageelse{#1}} +\unexpanded\def\doifpositionsonthispageelse#1{\clf_doifpositionsonthispageelse{#1}} + +%D Moved here: + +\unexpanded\def\doifelsepositionsused{\clf_doifelsepositionsused} \protect \endinput diff --git a/tex/context/base/anch-tab.mkiv b/tex/context/base/anch-tab.mkiv index a70f63e24..da735b49d 100644 --- a/tex/context/base/anch-tab.mkiv +++ b/tex/context/base/anch-tab.mkiv @@ -43,16 +43,16 @@ \fi} \unexpanded\def\tabl_tabulate_hook_b_first - {\ctxcommand{bcolumn("tabulate:\the\c_anch_tabs:\the\c_tabl_tabulate_column",true)}} + {\clf_bposcolumnregistered{tabulate:\the\c_anch_tabs:\the\c_tabl_tabulate_column}} \unexpanded\def\tabl_tabulate_hook_b_next - {\ctxcommand{bcolumn("tabulate:\the\c_anch_tabs:\the\c_tabl_tabulate_column")}} + {\clf_bposcolumn{tabulate:\the\c_anch_tabs:\the\c_tabl_tabulate_column}} \unexpanded\def\tabl_tabulate_hook_e_first - {\ctxcommand{ecolumn(true)}} + {\clf_eposcolumnregistered} \unexpanded\def\tabl_tabulate_hook_e_next - {\ctxcommand{ecolumn()}} + {\clf_eposcolumn} % \appendtoks \registerparoptions \to \everypar diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua index 2d6370811..8a41d9960 100644 --- a/tex/context/base/back-pdf.lua +++ b/tex/context/base/back-pdf.lua @@ -6,13 +6,23 @@ if not modules then modules = { } end modules ['back-pdf'] = { license = "see context related readme files" } +-- we could do \pdfmatrix sx <> sy <> etc local tonumber = tonumber local sind, cosd = math.sind, math.cosd local insert, remove = table.insert, table.remove + local codeinjections = backends.pdf.codeinjections local context = context + +local scanners = tokens.scanners +local scanstring = scanners.string +local scannumber = scanners.number +local scankeyword = scanners.keyword + +local scanners = interfaces.scanners + local outputfilename function codeinjections.getoutputfilename() @@ -26,8 +36,9 @@ backends.install("pdf") local f_matrix = string.formatters["%F %F %F %F"] -- 0.8 is default -function commands.pdfrotation(a) +scanners.pdfrotation = function() -- a -- todo: check for 1 and 0 and flush sparse + local a = scannumber() local s, c = sind(a), cosd(a) context(f_matrix(c,s,-s,c)) end @@ -45,7 +56,8 @@ local pdfsetmatrix = nodes.pool.pdfsetmatrix local stack = { } local restore = true -- false -function commands.pdfstartrotation(a) +scanners.pdfstartrotation = function() -- a + local a = scannumber() if a == 0 then insert(stack,false) else @@ -56,7 +68,17 @@ function commands.pdfstartrotation(a) end end -function commands.pdfstartscaling(sx,sy) +scanners.pdfstartscaling = function() -- sx sy + local sx, sy = 0, 0 + while true do + if scankeyword("sx") then + sx = scannumber() + elseif scankeyword("sy") then + sy = scannumber() + else + break + end + end if sx == 1 and sy == 1 then insert(stack,false) else @@ -72,7 +94,21 @@ function commands.pdfstartscaling(sx,sy) end end -function commands.pdfstartmatrix(sx,rx,ry,sy) -- tx, ty +scanners.pdfstartmatrix = function() -- sx rx ry sy -- tx, ty + local sx, rx, ry, sy = 0, 0, 0, 0 + while true do + if scankeyword("sx") then + sx = scannumber() + elseif scankeyword("sy") then + sy = scannumber() + elseif scankeyword("rx") then + rx = scannumber() + elseif scankeyword("ry") then + ry = scannumber() + else + break + end + end if sx == 1 and rx == 0 and ry == 0 and sy == 1 then insert(stack,false) else @@ -96,14 +132,14 @@ local function pdfstopsomething() end end -commands.pdfstoprotation = pdfstopsomething -commands.pdfstopscaling = pdfstopsomething -commands.pdfstopmatrix = pdfstopsomething +scanners.pdfstoprotation = pdfstopsomething +scanners.pdfstopscaling = pdfstopsomething +scanners.pdfstopmatrix = pdfstopsomething -function commands.pdfstartmirroring() +scanners.pdfstartmirroring = function() context(pdfsetmatrix(-1,0,0,1)) end -commands.pdfstopmirroring = commands.pdfstartmirroring +scanners.pdfstopmirroring = scanners.pdfstartmirroring -- todo : clipping diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv index 413365539..2f8215d16 100644 --- a/tex/context/base/back-pdf.mkiv +++ b/tex/context/base/back-pdf.mkiv @@ -135,73 +135,73 @@ % % % rotation % % % -\unexpanded\def\dostartrotation#1% grouped - {\forcecolorhack - \pdfsave - \pdfsetmatrix{\ctxcommand{pdfrotation(#1)}}} - -\unexpanded\def\dostoprotation - {\pdfrestore - \forcecolorhack} - % \unexpanded\def\dostartrotation#1% grouped % {\forcecolorhack -% \ctxcommand{pdfstartrotation(#1)}} +% \pdfsave +% \pdfsetmatrix{\clf_pdfrotation#1}} % \unexpanded\def\dostoprotation -% {\ctxcommand{pdfstoprotation()}} +% {\pdfrestore +% \forcecolorhack} -% % % scaling % % % +\unexpanded\def\dostartrotation#1% + {\forcecolorhack + \clf_pdfstartrotation#1\relax} -\unexpanded\def\dostartscaling#1#2% the test is needed because acrobat is bugged! - {\forcecolorhack % maybe use signal instead - \pdfsave - \pdfsetmatrix - {\ifdim#1\points=\zeropoint.0001\else#1\fi\space 0 0 - \ifdim#2\points=\zeropoint.0001\else#2\fi\space}}% 0 0 +\unexpanded\def\dostoprotation + {\clf_pdfstoprotation} -\unexpanded\def\dostopscaling - {\pdfrestore - \forcecolorhack} +% % % scaling % % % % \unexpanded\def\dostartscaling#1#2% the test is needed because acrobat is bugged! -% {\forcecolorhack -% \ctxcommand{pdfstartscaling(#1,#2)}} +% {\forcecolorhack % maybe use signal instead +% \pdfsave +% \pdfsetmatrix +% {\ifdim#1\points=\zeropoint.0001\else#1\fi\space 0 0 +% \ifdim#2\points=\zeropoint.0001\else#2\fi\space}}% 0 0 % \unexpanded\def\dostopscaling -% {\ctxcommand{pdfstopscaling()}} - -% % % mirroring % % % +% {\pdfrestore +% \forcecolorhack} -\unexpanded\def\dostartmirroring +\unexpanded\def\dostartscaling#1#2% {\forcecolorhack - \pdfsave - \pdfsetmatrix{-1 0 0 1}} % 0 0 + \clf_pdfstartscaling sx #1 sy #2\relax} -\unexpanded\def\dostopmirroring - {\pdfrestore - \forcecolorhack} +\unexpanded\def\dostopscaling + {\clf_pdfstopscaling} + +% % % mirroring % % % % \unexpanded\def\dostartmirroring -% {\ctxcommand{pdfstartmirroring()}} +% {\forcecolorhack +% \pdfsave +% \pdfsetmatrix{-1 0 0 1}} % 0 0 % \unexpanded\def\dostopmirroring -% {\ctxcommand{pdfstopmirroring()}} +% {\pdfrestore +% \forcecolorhack} + +\unexpanded\def\dostartmirroring + {\clf_pdfstartmirroring} + +\unexpanded\def\dostopmirroring + {\clf_pdfstopmirroring} % % % transform % % % -\unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints ! - {\dowithnextbox{\dodotransformnextbox{#5}{#6}{#1 #2 #3 #4}}} +% \unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints ! +% {\dowithnextbox{\dodotransformnextbox{#5}{#6}{#1 #2 #3 #4}}} -\unexpanded\def\dodotransformnextbox#1#2#3% - {\hbox - {\kern#1\onebasepoint - \raise#2\onebasepoint\hbox - {\pdfsave - \pdfsetmatrix{#3}% 0 0 (no #5 #6 yet) - \box\nextbox - \pdfrestore - }}} +% \unexpanded\def\dodotransformnextbox#1#2#3% +% {\hbox +% {\kern#1\onebasepoint +% \raise#2\onebasepoint\hbox +% {\pdfsave +% \pdfsetmatrix{#3}% 0 0 (no #5 #6 yet) +% \box\nextbox +% \pdfrestore +% }}} % \unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints ! % {% fixing ht/dp/wd should happen elsewhere @@ -212,9 +212,21 @@ % {\kern #5\onebasepoint % \raise#6\onebasepoint % \hbox -% {\ctxcommand{pdfstartmatrix(#1,#2,#3,#4)}% +% {\clf_pdfstartmatrix sx #1 rx #2 ry #3 sy #4\relax % \box\nextbox -% \ctxcommand{pdfstopmatrix()}}}} +% \clf_pdfstopmatrix}}} + +\unexpanded\def\dotransformnextbox#1#2#3#4#5#6% sx rx ry sy tx ty (will change) / basepoints ! + {\dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}} + +\unexpanded\def\dodotransformnextbox#1#2#3#4#5#6% + {\hbox + {\kern #5\onebasepoint + \raise#6\onebasepoint + \hbox + {\clf_pdfstartmatrix sx #1 rx #2 ry #3 sy #4\relax + \box\nextbox + \clf_pdfstopmatrix}}} % somehow the shift is not happening .. bug in luatex? % @@ -295,11 +307,11 @@ {\the\pdfbackendeveryxform \finalizeobjectbox\objectbox \immediate\pdfxform resources {\pdfbackendcurrentresources}\objectbox - \dosetobjectreference{#1}{#2}{\the\pdflastxform}} + \dosetobjectreference{#1}{#2}\pdflastxform} \let\m_back_object_reference\empty -\def\doinsertobject#1#2% +\unexpanded\def\doinsertobject#1#2% {\begingroup \doifobjectreferencefoundelse{#1}{#2} {\dogetobjectreference{#1}{#2}\m_back_object_reference @@ -309,7 +321,7 @@ \let\lastpredefinedsymbol\empty % some day we can do more at the lua end -\def\predefinesymbol[#1]% +\unexpanded\def\predefinesymbol[#1]% {\begingroup \xdef\lastpredefinedsymbol{#1}% \settightobject{SYM}{#1}\hbox{\symbol[#1]}% to be checked ... maybe only fitting diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index 9954ad39f..a825ad719 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -11,6 +11,8 @@ local type, next, load = type, next, load local sub, format = string.sub, string.format local splitlines, validstring = string.splitlines, string.valid local P, Cs, patterns, lpegmatch = lpeg.P, lpeg.Cs, lpeg.patterns, lpeg.match +local utfchar = utf.char +local totable = string.totable local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) local trace_grab = false trackers.register("buffers.grab", function(v) trace_grab = v end) @@ -23,6 +25,21 @@ local report_grabbing = logs.reporter("buffers","grabbing") local context = context local commands = commands +local implement = interfaces.implement + +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer +local scanboolean = scanners.boolean +local scancode = scanners.code +local scantoken = scanners.token + +local getters = tokens.getters +local gettoken = getters.token + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + local variables = interfaces.variables local settings_to_array = utilities.parsers.settings_to_array local formatters = string.formatters @@ -165,8 +182,17 @@ buffers.loadcontent = loadcontent -- the context interface -commands.erasebuffer = erase -commands.assignbuffer = assign +implement { + name = "assignbuffer", + actions = assign, + arguments = { "string", "string", "integer" } +} + +implement { + name = "erasebuffer", + actions = erase, + arguments = "string" +} local anything = patterns.anything local alwaysmatched = patterns.alwaysmatched @@ -259,51 +285,141 @@ end buffers.undent = undent -function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes,doundent) -- maybe move \\ to call - local dn = getcontent(name) - if dn == "" then - nesting = 0 - continue = false - end - if trace_grab then - if #bufferdata > 30 then - report_grabbing("%s => |%s..%s|",name,sub(bufferdata,1,10),sub(bufferdata,-10,#bufferdata)) +-- function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes,doundent) -- maybe move \\ to call +-- local dn = getcontent(name) +-- if dn == "" then +-- nesting = 0 +-- continue = false +-- end +-- if trace_grab then +-- if #bufferdata > 30 then +-- report_grabbing("%s => |%s..%s|",name,sub(bufferdata,1,10),sub(bufferdata,-10,#bufferdata)) +-- else +-- report_grabbing("%s => |%s|",name,bufferdata) +-- end +-- end +-- local counter = counters[begintag] +-- if not counter then +-- counter = countnesting(begintag,endtag) +-- counters[begintag] = counter +-- end +-- nesting = nesting + lpegmatch(counter,bufferdata) +-- local more = nesting > 0 +-- if more then +-- dn = dn .. sub(bufferdata,2,-1) .. endtag +-- nesting = nesting - 1 +-- continue = true +-- else +-- if continue then +-- dn = dn .. sub(bufferdata,2,-2) -- no \r, \n is more generic +-- elseif dn == "" then +-- dn = sub(bufferdata,2,-2) +-- else +-- dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic +-- end +-- local last = sub(dn,-1) +-- if last == "\n" or last == "\r" then -- \n is unlikely as \r is the endlinechar +-- dn = sub(dn,1,-2) +-- end +-- if doundent or (autoundent and doundent == nil) then +-- dn = undent(dn) +-- end +-- end +-- assign(name,dn,catcodes) +-- commands.doifelse(more) +-- end + +function tokens.pickup(start,stop) + local stoplist = totable(stop) + local stoplength = #stoplist + local stoplast = stoplist[stoplength] + local startlist = totable(start) + local startlength = #startlist + local startlast = startlist[startlength] + local list = { } + local size = 0 + local depth = 0 + while true do -- or use depth + local char = scancode() + if char then + char = utfchar(char) + size = size + 1 + list[size] = char + if char == stoplast and size >= stoplength then + local done = true + local last = size + for i=stoplength,1,-1 do + if stoplist[i] ~= list[last] then + done = false + break + end + last = last - 1 + end + if done then + if depth > 0 then + depth = depth - 1 + else + break + end + char = false -- trick: let's skip the next (start) test + end + end + if char == startlast and size >= startlength then + local done = true + local last = size + for i=startlength,1,-1 do + if startlist[i] ~= list[last] then + done = false + break + end + last = last - 1 + end + if done then + depth = depth + 1 + end + end else - report_grabbing("%s => |%s|",name,bufferdata) + -- local t = scantoken() + local t = gettoken() + if t then + -- we're skipping leading stuff, like obeyedlines and relaxes + else + break + end end end - local counter = counters[begintag] - if not counter then - counter = countnesting(begintag,endtag) - counters[begintag] = counter - end - nesting = nesting + lpegmatch(counter,bufferdata) - local more = nesting > 0 - if more then - dn = dn .. sub(bufferdata,2,-1) .. endtag - nesting = nesting - 1 - continue = true - else - if continue then - dn = dn .. sub(bufferdata,2,-2) -- no \r, \n is more generic - elseif dn == "" then - dn = sub(bufferdata,2,-2) - else - dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic - end - local last = sub(dn,-1) - if last == "\n" or last == "\r" then -- \n is unlikely as \r is the endlinechar - dn = sub(dn,1,-2) - end - if doundent or (autoundent and doundent == nil) then - dn = undent(dn) - end + list = concat(list,"",1,size-stoplength-1) + return list +end + +-- function buffers.pickup(name,start,stop,finish,catcodes,doundent) +-- local data = tokens.pickup(start,stop) +-- if doundent or (autoundent and doundent == nil) then +-- data = buffers.undent(data) +-- end +-- buffers.assign(name,data,catcodes) +-- context(finish) +-- end + +-- commands.pickupbuffer = buffers.pickup + +scanners.pickupbuffer = function() + local name = scanstring() + local start = scanstring() + local stop = scanstring() + local finish = scanstring() + local catcodes = scaninteger() + local doundent = scanboolean() + local data = tokens.pickup(start,stop) + if doundent or (autoundent and doundent == nil) then + data = buffers.undent(data) end - assign(name,dn,catcodes) - commands.doifelse(more) + buffers.assign(name,data,catcodes) + -- context[finish]() + context(finish) end -function commands.savebuffer(list,name,prefix) -- name is optional +local function savebuffer(list,name,prefix) -- name is optional if not list or list == "" then list = name end @@ -320,47 +436,18 @@ function commands.savebuffer(list,name,prefix) -- name is optional io.savedata(name,content) end --- local files = { } --- local last = 0 --- --- function commands.runbuffer(name,encapsulate) -- we used to compare the saved file with content --- local names = getnames(name) --- local filename = files[name] --- local tobedone = not istypeset(names) --- if tobedone or not filename then --- last = last + 1 --- filename = formatters["%s-typeset-buffer-%03i"](tex.jobname,last) --- files[name] = filename --- end --- if tobedone then --- if trace_run then --- report_typeset("changes in %a, processing forced",name) --- end --- local filename = addsuffix(filename,"tmp") --- local content = collectcontent(names,nil) or "" --- if content == "" then --- content = "empty buffer" --- end --- if encapsulate then --- content = formatters["\\starttext\n%s\n\\stoptext\n"](content) --- end --- io.savedata(filename,content) --- local command = formatters["context %s %s"](jit and "--jit" or "",filename) --- report_typeset("running: %s\n",command) --- os.execute(command) --- markastypeset(names) --- elseif trace_run then --- report_typeset("no changes in %a, not processed",name) --- end --- context(replacesuffix(filename,"pdf")) --- end +implement { + name = "savebuffer", + actions = savebuffer, + arguments = { "string", "string", "string" } +} -- we can consider adding a size to avoid unlikely clashes local oldhashes = nil local newhashes = nil -function commands.runbuffer(name,encapsulate) +local function runbuffer(name,encapsulate) if not oldhashes then oldhashes = job.datasets.getdata("typeset buffers","hashes") or { } for hash, n in next, oldhashes do @@ -406,10 +493,10 @@ function commands.runbuffer(name,encapsulate) registertempfile(filename) registertempfile(resultname,nil,true) -- - context(resultname) + return resultname end -function commands.getbuffer(name) +local function getbuffer(name) local str = getcontent(name) if str ~= "" then -- characters.showstring(str) @@ -417,11 +504,11 @@ function commands.getbuffer(name) end end -function commands.getbuffermkvi(name) -- rather direct ! +local function getbuffermkvi(name) -- rather direct ! context.viafile(resolvers.macros.preprocessed(getcontent(name)),formatters["buffer.%s.mkiv"](validstring(name,"noname"))) end -function commands.gettexbuffer(name) +local function gettexbuffer(name) local buffer = name and cache[name] if buffer and buffer.data ~= "" then context.pushcatcodetable() @@ -436,20 +523,29 @@ function commands.gettexbuffer(name) end end -commands.getbufferctxlua = loadcontent +implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" } +implement { name = "getbuffer", actions = getbuffer, arguments = "string" } +implement { name = "getbuffermkvi", actions = getbuffermkvi, arguments = "string" } +implement { name = "gettexbuffer", actions = gettexbuffer, arguments = "string" } -function commands.doifelsebuffer(name) - commands.doifelse(exists(name)) -end +implement { + name = "runbuffer", + actions = { runbuffer, context }, + arguments = { "string", "boolean" } +} + +implement { + name = "doifelsebuffer", + actions = { exists, commands.doifelse }, + arguments = "string" +} -- This only used for mp buffers and is a kludge. Don't change the -- texprint into texsprint as it fails because "penddef" becomes -- "penddef" then. --- function commands.feedback(names) --- texprint(ctxcatcodes,splitlines(collectcontent(names))) --- end - -function commands.feedback(names) -- bad name, maybe rename to injectbuffercontent - context.printlines(collectcontent(names)) -end +implement { + name = "feedback", -- bad name, maybe rename to injectbuffercontent + actions = { collectcontent, context.printlines }, + arguments = "string" +} diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv index abee6c7c6..d11a6db97 100644 --- a/tex/context/base/buff-ini.mkiv +++ b/tex/context/base/buff-ini.mkiv @@ -23,13 +23,13 @@ \let\currentbuffer\empty \def\doifelsebuffer#1% - {\ctxcommand{doifelsebuffer("#1")}} + {\clf_doifelsebuffer{#1}} \unexpanded\def\resetbuffer {\dosingleempty\buff_reset} \def\buff_reset[#1]% - {\ctxcommand{erasebuffer("#1")}} + {\clf_erasebuffer{#1}} \setuvalue{\e!start\v!buffer}% {\begingroup % (3) @@ -67,35 +67,70 @@ \let\buff_finish\relax \let\buff_gobble\relax +% \unexpanded\def\buff_pickup#1#2#3#4#5#6% name, startsequence, stopsequence, before, after, undent +% {\begingroup % (1) +% #4% +% \begingroup % (2) +% \edef\catcodetableofbuffer{\number\catcodetable}% +% \clf_erasebuffer{#1}% +% \setcatcodetable\vrbcatcodes +% \def\buff_finish +% {\endgroup % (1) +% \endgroup % (2) +% #5}% +% \def\buff_gobble##1#3% is detokenize needed? TEST +% %{\ctxcommand{grabbuffer("#1","#2","#3",\!!bs\detokenize{##1}\!!es)} % space ? +% {\ctxcommand{grabbuffer("#1","#2","#3",\!!bs>##1\!!es,\catcodetableofbuffer,\ifnum#6=\plusone true\else false\fi)}% space ? +% \buff_gobble +% \buff_finish}% +% \buff_gobble} + +% % \def\startgrab +% % {\begingroup +% % \setcatcodetable\vrbcatcodes +% % \ctxlua{tokens.pickup("\\startgrab","\\stopgrab") context("\\endgroup")}} +% % +% % \def\stopgrab +% % {} + \unexpanded\def\buff_pickup#1#2#3#4#5#6% name, startsequence, stopsequence, before, after, undent {\begingroup % (1) #4% \begingroup % (2) - \edef\catcodetableofbuffer{\number\catcodetable}% - \ctxcommand{erasebuffer("#1")}% + \scratchcounter\catcodetable + \clf_erasebuffer{#1}% \setcatcodetable\vrbcatcodes - \def\buff_finish + \unexpanded\def\dofinishpickupbuffer {\endgroup % (1) \endgroup % (2) #5}% - \def\buff_gobble##1#3% is detokenize needed? TEST - %{\ctxcommand{grabbuffer("#1","#2","#3",\!!bs\detokenize{##1}\!!es)} % space ? - {\ctxcommand{grabbuffer("#1","#2","#3",\!!bs>##1\!!es,\catcodetableofbuffer,\ifnum#6=\plusone true\else false\fi)}% space ? - \buff_gobble - \buff_finish}% - \buff_gobble} + % todo: we need to skip the first lineending which is na active character + % but sometimes we have something different ... this is a side effect of + % checking for optional arguments i.e. the next token is already tokenized + % and for that reason we have the \relax as well as the \string + \clf_pickupbuffer + {#1}% + {#2}% + {#3}% + {\string\dofinishpickupbuffer}% + \scratchcounter + \ifnum#6=\plusone\s!true\else\s!false\fi + % \relax} + \expandafter\relax\string} \unexpanded\def\buff_stop#1% {\endgroup % (3 & 4 & 5 & 6) \getvalue{#1}} +% \installctxfunction\dopickupbuffer{commands.dopickupbuffer} + \unexpanded\def\setbuffer {\dosingleempty\buff_set} \let\endbuffer\relax \def\buff_set[#1]#2\endbuffer % seldom used so we just pass #2 - {\ctxcommand{assignbuffer("#1",\!!bs\detokenize{#2}\!!es,\number\catcodetable)}} + {\clf_assignbuffer{#1}{\detokenize{#2}}\catcodetable\relax} % beware, never adapt the global buffer settings, actually we might introduce % a broken parent chain for this purpose but on the other hand it's not that @@ -144,7 +179,7 @@ \namedbufferparameter{#1}\c!after} \unexpanded\def\buff_get_stored_indeed#1% - {\ctxcommand{getbuffer("#1")}} + {\clf_getbuffer{#1}} \unexpanded\def\getdefinedbuffer[#1]% {\buff_get_stored{#1}{\thedefinedbuffer{#1}}}% @@ -158,7 +193,7 @@ {\processcommalist[#1]\buff_get_stored_inline_indeed}} \unexpanded\def\buff_get_stored_inline_indeed#1% - {\ignorespaces\ctxcommand{getbuffer("#1")}\removeunwantedspaces} + {\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces} \definebuffer [\v!hiding] @@ -203,7 +238,7 @@ \doifassignmentelse{#1} {\setupcurrentsavebuffer[#1]}% {\setupcurrentsavebuffer[\c!list={#1},\c!file=#2]}% - \ctxcommand{savebuffer("\directsavebufferparameter\c!list","\directsavebufferparameter\c!file","\directsavebufferparameter\c!prefix")}% + \clf_savebuffer{\directsavebufferparameter\c!list}{\directsavebufferparameter\c!file}{\directsavebufferparameter\c!prefix}% \endgroup} %D Experimental: no expansion of commands in buffer! @@ -221,8 +256,8 @@ \unexpanded\def\mkvibuffer {\dosingleempty\buff_mkvi} % what was: \mkvibufferraw -\def\buff_ctxlua[#1]{\ctxcommand{getbufferctxlua("#1")}} -\def\buff_mkvi [#1]{\ctxcommand{getbuffermkvi("#1")}} +\def\buff_ctxlua[#1]{\clf_getbufferctxlua{#1}} +\def\buff_mkvi [#1]{\clf_getbuffermkvi {#1}} % used elsewhere diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua index 7e7120eae..0dc079b31 100644 --- a/tex/context/base/buff-ver.lua +++ b/tex/context/base/buff-ver.lua @@ -29,6 +29,12 @@ visualizers = visualizers or { } local specifications = allocate() visualizers.specifications = specifications +local scanners = tokens.scanners +local scanstring = scanners.string + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + local context = context local commands = commands @@ -712,7 +718,7 @@ commands.loadvisualizer = visualizers.load -- local decodecomment = resolvers.macros.decodecomment -- experiment -function commands.typebuffer(settings) +local function typebuffer(settings) local lines = getlines(settings.name) if lines then ctx_displayverbatiminitialize(#lines) @@ -725,7 +731,7 @@ function commands.typebuffer(settings) end end -function commands.processbuffer(settings) +local function processbuffer(settings) local lines = getlines(settings.name) if lines then local content, m = filter(lines,settings) @@ -736,6 +742,9 @@ function commands.processbuffer(settings) end end +commands.typebuffer = typebuffer +commands.processbuffer = processbuffer + -- not really buffers but it's closely related -- A string.gsub(str,"(\\.-) +$","%1") is faster than an lpeg when there is a @@ -759,7 +768,7 @@ local compactors = { [v_last] = Cs((space^1 * endstring/"" + 1)^0), } -function commands.typestring(settings) +local function typestring(settings) local content = settings.data if content and content ~= "" then local compact = settings.compact @@ -773,7 +782,7 @@ function commands.typestring(settings) end end -function commands.typefile(settings) +local function typefile(settings) local filename = settings.name local foundname = resolvers.findtexfile(filename) if foundname and foundname ~= "" then @@ -795,3 +804,77 @@ function commands.typefile(settings) end end end + +commands.typestring = typestring +commands.typefile = typefile + +-- scanners.typenormal = function() +-- typestring { +-- nature = "inline", +-- data = scanstring(), +-- tab = scanstring(), +-- method = scanstring(), +-- compact = scanstring(), +-- escape = scanstring(), +-- } +-- end + +-- scanners.typenested = function() +-- typestring { +-- nature = "inline", +-- method = "nested", +-- data = scanstring(), +-- tab = scanstring(), +-- option = scanstring(), +-- escape = scanstring(), +-- } +-- end + +scanners.type = compilescanner { + actions = typestring, + arguments = { + { + { "data" }, + { "tab" }, + { "option" }, + { "method" }, + { "compact" }, + { "nature" }, + { "escape" }, + } + } +} + +scanners.processbuffer = compilescanner { + actions = processbuffer, + arguments = { + { + { "name" }, + { "strip" }, + { "tab" }, + { "method" }, + { "nature" }, + } + } +} + +local get_typing = compilescanner { + { + { "name" }, + { "strip" }, + { "range" }, + { "regime" }, + { "tab" }, + { "method" }, + { "escape" }, + { "nature" }, + } +} + +scanners.typebuffer = function() + typebuffer(get_typing()) +end + +scanners.typefile = function() + typefile(get_typing()) +end diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index 9e0244eca..c756c57c4 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -337,14 +337,14 @@ \def\buff_verbatim_type_normal#1% {\buff_verbatim_initialize_type_two \dostarttaggedchained\t!verbatim\currenttype\??type - \ctxcommand{typestring{ - data = \!!bs\detokenize{#1}\!!es, - tab = "\typeparameter\c!tab", - method = "\p_buff_option", - nature = "inline", - compact = "\typeparameter\c!compact", % none | all | last (all needed in tabulate etc for manuals) - escape = \!!bs\typeparameter\c!escape\!!es, % new but rather useless imo (escaping in general is not used much) - }}% + \clf_type + data {\detokenize{#1}}% + tab {\typeparameter\c!tab}% + option {\p_buff_option}% + compact {\typeparameter\c!compact}% % none | all | last (all needed in tabulate etc for manuals) + escape {\typeparameter\c!escape}% % new but rather useless imo (escaping in general is not used much) + % nature {inline}% is default + \relax \dostoptagged \buff_verbatim_right_of_type \egroup} @@ -352,13 +352,14 @@ \def\buff_verbatim_type_nested#1% {\buff_verbatim_initialize_type_two \dostarttaggedchained\t!verbatim\currenttype\??type - \ctxcommand{typestring{ - data = \!!bs\detokenize{#1}\!!es, - tab = "\typeparameter\c!tab", - method = "nested", % we force a special visualizer - option = "\p_buff_option", % extra visualizer (maybe: nested,\typeparameter\c!option) - nature = "inline", - }}% + \clf_type + data {\detokenize{#1}}% + tab {\typeparameter\c!tab}% + option {\p_buff_option}% % extra visualizer (maybe: nested,\typeparameter\c!option) + escape {\typeparameter\c!escape}% % new but rather useless imo (escaping in general is not used much) + % nature {inline}% is default + method {nested}% + \relax \dostoptagged \buff_verbatim_right_of_type \egroup @@ -520,15 +521,15 @@ \dostarttaggedchained\t!verbatimblock\currenttyping\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty - \ctxcommand{typebuffer { - name = "_typing_", - strip = "\typingparameter\c!strip", - range = "\typingparameter\c!range", - tab = "\typingparameter\c!tab", - method = "\p_buff_option", - escape = \!!bs\typingparameter\c!escape\!!es, - nature = "display", - }}% + \clf_typebuffer + name {_typing_}% + strip {\typingparameter\c!strip}% + range {\typingparameter\c!range}% + tab {\typingparameter\c!tab}% + method {\p_buff_option}% + escape {\typingparameter\c!escape}% + nature {display}% + \relax \dostoptagged \endofverbatimlines \dostoptagged @@ -639,15 +640,15 @@ \dostarttaggedchained\t!verbatimblock\currenttyping\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty - \ctxcommand{typefile { - name = "#2", - strip = "\typingparameter\c!strip", - range = "\typingparameter\c!range", - regime = "\currentregime", - tab = "\typingparameter\c!tab", - method = "\p_buff_option", - nature = "display", - }}% + \clf_typefile + name {#2}% + strip {\typingparameter\c!strip}% + range {\typingparameter\c!range}% + regime {\currentregime}% + tab {\typingparameter\c!tab}% + method {\p_buff_option}% + nature {display}% + \relax \dostoptagged \endofverbatimlines \dostoptagged @@ -812,16 +813,16 @@ \dostarttaggedchained\t!verbatimblock{#1}\??typing \beginofverbatimlines \dostarttagged\t!verbatimlines\empty - \ctxcommand{typebuffer { - name = "#2", - strip = "\typingparameter\c!strip", - range = "\typingparameter\c!range", - regime = "\currentregime", - tab = "\typingparameter\c!tab", - method = "\p_buff_option", - escape = \!!bs\typingparameter\c!escape\!!es, - nature = "display", - }}% + \clf_typebuffer + name {#2}% + strip {\typingparameter\c!strip}% + range {\typingparameter\c!range}% + regime {\currentregime}% + tab {\typingparameter\c!tab}% + method {\p_buff_option}% + escape {\typingparameter\c!escape}% + % nature {display}% + \relax \dostoptagged \endofverbatimlines \dostoptagged @@ -856,13 +857,13 @@ \def\buff_verbatim_process_indeed#1#2% {\edef\currenttyping{#1}% - \ctxcommand{processbuffer { - name = "#2", - strip = "\typingparameter\c!strip", - tab = "\typingparameter\c!tab", - method = "\p_buff_option", - nature = "direct", - }}} + \clf_processbuffer + name {#2}% + strip {\typingparameter\c!strip}% + tab {\typingparameter\c!tab}% + method {\p_buff_option}% + nature {direct}% + \relax} % so far for obsolete diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index 9ccbc6cb3..19d0703cf 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -20,6 +20,14 @@ local report_colors = logs.reporter("colors","defining") local attributes, backends, storage = attributes, backends, storage local context, commands = context, commands +local scanners = tokens.scanners +local scanstring = scanners.string +local scanboolean = scanners.boolean +local scaninteger = scanners.integer + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + local settings_to_hash_strict = utilities.parsers.settings_to_hash_strict local colors = attributes.colors @@ -48,7 +56,7 @@ storage.register("attributes/colors/sets",colorsets,"attributes.colors.sets") local stack = { } -function colors.pushset(name) +local function pushset(name) insert(stack,colorset) colorset = colorsets[name] if not colorset then @@ -57,14 +65,18 @@ function colors.pushset(name) end end -function colors.popset(name) +local function popset(name) colorset = remove(stack) end -function colors.setlist(name) +local function setlist(name) return table.sortedkeys(name and name ~= "" and colorsets[name] or colorsets.default or {}) end +colors.pushset = pushset +colors.popset = popset +colors.setlist = setlist + local context_colordefagc = context.colordefagc local context_colordefagt = context.colordefagt local context_colordefalc = context.colordefalc @@ -242,10 +254,12 @@ colors.forcedmodel = forcedmodel colors.couple = true -function colors.definetransparency(name,n) +local function definetransparency(name,n) transparent[name] = n end +colors.definetransparency = definetransparency + local registered = { } local function do_registerspotcolor(parent,parentnumber,e,f,d,p) @@ -327,17 +341,19 @@ directives.register("colors.pgf",function(v) end end) -function colors.defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent +local defineintermediatecolor + +local function defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent local what, one, two, three = lpegmatch(specialcolor,str) if what == "H" then -- for old times sake (if we need to feed from xml or so) definecolor(name, register_color(name,'rgb',one,two,three),global) elseif what == "M" then -- intermediate - return colors.defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) + return defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) elseif what == "P" then -- pgf for tikz - return colors.defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) + return defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) else local settings = settings_to_hash_strict(str) if settings then @@ -393,12 +409,14 @@ function colors.defineprocesscolor(name,str,global,freeze) -- still inconsistent colorset[name] = true-- maybe we can store more end -function colors.isblack(ca) -- maybe commands +local function isblack(ca) -- maybe commands local cv = ca > 0 and colorvalues[ca] return (cv and cv[2] == 0) or false end -function colors.definespotcolor(name,parent,str,global) +colors.isblack = isblack + +local function definespotcolor(name,parent,str,global) if parent == "" or find(parent,"=",1,true) then colors.registerspotcolor(name, parent) -- does that work? no attr elseif name ~= parent then @@ -479,7 +497,7 @@ local function definemixcolor(makename,name,fractions,cs,global,freeze) end end -function colors.definemultitonecolor(name,multispec,colorspec,selfspec) +local function definemultitonecolor(name,multispec,colorspec,selfspec) local dd, pp, nn, max = { }, { }, { }, 0 for k,v in gmatch(multispec,"([^=,]+)=([^%,]*)") do -- use settings_to_array max = max + 1 @@ -497,7 +515,7 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec) if selfspec ~= "" then colorspec = colorspec .. "," .. selfspec end - colors.defineprocesscolor(parent,colorspec,true,true) + defineprocesscolor(parent,colorspec,true,true) end local cp = attributes_list[a_color][parent] dd, pp = concat(dd,','), concat(pp,',') @@ -516,6 +534,10 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec) colorset[name] = true-- maybe we can store more end +colors.defineprocesscolor = defineprocesscolor +colors.definespotcolor = definespotcolor +colors.definemultitonecolor = definemultitonecolor + -- will move to mlib-col as colors in mp are somewhat messy due to the fact -- that we cannot cast .. so we really need to use (s,s,s) for gray in order -- to be able to map onto 'color' @@ -732,7 +754,7 @@ local function complement(one,fraction,i) return otf end -function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) +defineintermediatecolor = function(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) fraction = tonumber(fraction) or 1 local one, two = colorvalues[c_one], colorvalues[c_two] if one then @@ -788,6 +810,8 @@ function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,sp end end +colors.defineintermediatecolor = defineintermediatecolor + -- for the moment downward compatible local patterns = { "colo-imp-%s.mkiv", "colo-imp-%s.tex", "colo-%s.mkiv", "colo-%s.tex" } @@ -807,7 +831,7 @@ local function failure(name) report_colors("unknown library %a",name) end -function colors.usecolors(name) +local function usecolors(name) commands.uselibrary { category = "color definition", name = name, @@ -818,6 +842,8 @@ function colors.usecolors(name) } end +colors.usecolors = usecolors + -- interface (todo: use locals) local setcolormodel = colors.setmodel @@ -826,6 +852,10 @@ function commands.setcolormodel(model,weight) texsetattribute(a_colorspace,setcolormodel(model,weight)) end +scanners.setcolormodel = function() + texsetattribute(a_colorspace,setcolormodel(scanstring(),scanboolean())) +end + -- function commands.setrastercolor(name,s) -- texsetattribute(a_color,colors.definesimplegray(name,s)) -- end @@ -834,11 +864,50 @@ function commands.registermaintextcolor(a) colors.main = a end -commands.defineprocesscolor = colors.defineprocesscolor -commands.definespotcolor = colors.definespotcolor -commands.definemultitonecolor = colors.definemultitonecolor -commands.definetransparency = colors.definetransparency -commands.defineintermediatecolor = colors.defineintermediatecolor +commands.defineprocesscolor = defineprocesscolor +commands.definespotcolor = definespotcolor +commands.definemultitonecolor = definemultitonecolor +commands.definetransparency = definetransparency +commands.defineintermediatecolor = defineintermediatecolor + +scanners.defineprocesscolorlocal = compilescanner { + actions = defineprocesscolor, + arguments = { "string", "string", false, "boolean" } +} + +scanners.defineprocesscolorglobal = compilescanner { + actions = defineprocesscolor, + arguments = { "string", "string", true, "boolean" } +} + +scanners.defineprocesscolordummy = compilescanner { + actions = defineprocesscolor, + arguments = { "'d_u_m_m_y'", "string", false, false } +} + +scanners.definespotcolorglobal = compilescanner { + actions = definespotcolor, + arguments = { "string", "string", "string", true } +} + +scanners.definemultitonecolorglobal = compilescanner { + actions = definespotcolor, + arguments = { "string", "string", "string", "string", true } +} + +scanners.registermaintextcolor = function() + colors.main = scaninteger() +end + +scanners.definetransparency = compilescanner { + actions = definetransparency, + arguments = { "string", "integer" }, +} + +scanners.defineintermediatecolor = compilescanner { + actions = defineintermediatecolor, + arguments = { "string", "string", "integer", "integer", "integer", "integer", "string", false, "boolean" } +} function commands.spotcolorname (a) context(spotcolorname (a)) end function commands.spotcolorparent (a) context(spotcolorparent (a)) end @@ -849,22 +918,56 @@ function commands.processcolorcomponents(a,s) context(processcolorcomponents(a,s function commands.formatcolor (...) context(formatcolor (...)) end function commands.formatgray (...) context(formatgray (...)) end +scanners.spotcolorname = compilescanner { actions = spotcolorname, arguments = "integer" } +scanners.spotcolorparent = compilescanner { actions = spotcolorparent, arguments = "integer" } +scanners.spotcolorvalue = compilescanner { actions = spotcolorvalue, arguments = "integer" } + +scanners.colorcomponents = compilescanner { actions = colorcomponents, arguments = "integer" } +scanners.transparencycomponents = compilescanner { actions = transparencycomponents, arguments = "integer" } +scanners.processcolorcomponents = compilescanner { actions = processcolorcomponents, arguments = { "integer", "','" } } + +scanners.formatcolor = compilescanner { actions = formatcolor, arguments = { "integer", "string" } } +scanners.formatgray = compilescanner { actions = formatgray, arguments = { "integer", "string" } } + function commands.mpcolor(model,ca,ta,default) context(mpcolor(model,ca,ta,default)) end +-- scanners.mpcolor = function() +-- context(mpcolor(scaninteger(),scaninteger(),scaninteger())) +-- end + +scanners.mpcolor = compilescanner { + actions = { mpcolor, context }, + arguments = { "integer", "integer", "integer" } +} + function commands.mpoptions(model,ca,ta,default) context(mpoptions(model,ca,ta,default)) end +scanners.mpoptions = compilescanner { + actions = { mpoptions, context }, + arguments = { "integer", "integer", "integer" } +} + +local ctx_doifelse = commands.doifelse + function commands.doifblackelse(a) - commands.doifelse(colors.isblack(a)) + ctx_doifelse(isblack(a)) end function commands.doifdrawingblackelse() - commands.doifelse(colors.isblack(texgetattribute(a_color))) + ctx_doifelse(isblack(texgetattribute(a_color))) end +scanners.doifblackelse = compilescanner { + actions = { isblack, ctx_doifelse }, + arguments = "integer" +} + +scanners.doifdrawingblackelse = commands.doifdrawingblackelse + -- function commands.withcolorsinset(name,command) -- local set -- if name and name ~= "" then @@ -883,14 +986,17 @@ end -- end -- end -commands.startcolorset = colors.pushset -commands.stopcolorset = colors.popset +commands.startcolorset = pushset +commands.stopcolorset = popset +commands.usecolors = usecolors -commands.usecolors = colors.usecolors +scanners.startcolorset = compilescanner { actions = pushset, arguments = "string" } +scanners.stopcolorset = popset +scanners.usecolors = compilescanner { actions = usecolors, arguments = "string" } -- bonus -function commands.pgfxcolorspec(ca) -- {}{}{colorspace}{list} +local function pgfxcolorspec(ca) -- {}{}{colorspace}{list} -- local cv = attributes.colors.values[ca] local cv = colorvalues[ca] if cv then @@ -909,6 +1015,10 @@ function commands.pgfxcolorspec(ca) -- {}{}{colorspace}{list} end end +commands.pgfxcolorspec = pgfxcolorspec + +scanners.pgfxcolorspec = compilescanner { actions = pgfxcolorspec, arguments = "integer" } + -- function commands.pgfregistercolor(name,attribute) -- local cv = colorvalues[ca] -- context.pushcatcodes('prt') diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv index c713d8803..217330afc 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -203,9 +203,9 @@ %D \usecolors[dem] %D \stoptyping -\unexpanded\def\startcolorset[#1]{\ctxcommand{startcolorset("#1")}} -\unexpanded\def\stopcolorset {\ctxcommand{stopcolorset()}} -\unexpanded\def\usecolors [#1]{\ctxcommand{usecolors("#1")}} +\unexpanded\def\startcolorset[#1]{\clf_startcolorset{#1}} +\unexpanded\def\stopcolorset {\clf_stopcolorset} +\unexpanded\def\usecolors [#1]{\clf_usecolors{#1}} \let\setupcolor\usecolors @@ -563,7 +563,7 @@ \def\colo_helpers_set_model#1% direct {\edef\currentcolormodel{#1}% - \ctxcommand{setcolormodel('\currentcolormodel',\v_colo_weight_state)}} % sets attribute at lua end + \clf_setcolormodel{\currentcolormodel}\v_colo_weight_state\relax} % sets attribute at lua end \colo_helpers_set_model\s!all @@ -699,31 +699,31 @@ {\advance\c_colo_protection\minusone} \def\colo_basics_define[#1][#2]% - {\ctxcommand{defineprocesscolor("#1","#2",false,\v_colo_freeze_state)}% + {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_global[#1][#2]% - {\ctxcommand{defineprocesscolor("#1","#2",true,\v_colo_freeze_state)}% + {\clf_defineprocesscolorglobal{#1}{#2}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_named[#1][#2]% currently same as define - {\ctxcommand{defineprocesscolor("#1","#2",false,\v_colo_freeze_state)}% + {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\dodefinefastcolor[#1][#2]% still not fast but ok (might change) - {\ctxcommand{defineprocesscolor("#1","#2",false,\v_colo_freeze_state)}% + {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_defined_and_activated#1% - {\ctxcommand{defineprocesscolor("\v_colo_dummy_name","#1",false,false)}% + {\clf_defineprocesscolordummy{#1}% \colo_helpers_activate_dummy} \def\colo_basics_define_process @@ -734,13 +734,13 @@ \fi} \def\colo_basics_define_process_yes[#1][#2][#3]% - {\ctxcommand{defineprocesscolor("#1","\processcolorcomponents{#2},#3",false,\v_colo_freeze_state)}% + {\clf_defineprocesscolorlocal{#1}{\processcolorcomponents{#2},#3}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_process_nop[#1][#2][#3]% - {\ctxcommand{defineprocesscolor("#1","#2",false,\v_colo_freeze_state)}% + {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} @@ -751,13 +751,13 @@ % spot colors often are a document wide property \def\colo_basics_define_spot[#1][#2][#3]% - {\ctxcommand{definespotcolor("#1","#2","#3",true)}% + {\clf_definespotcolorglobal{#1}{#2}{#3}% \ifcase\c_colo_protection \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_multitone[#1][#2][#3][#4]% - {\ctxcommand{definemultitonecolor("#1","#2","#3","#4",true)}% + {\clf_definemultitonecolorglobal{#1}{#2}{#3}{#4}% \ifcase\c_colo_protection \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% \fi} @@ -765,7 +765,7 @@ %D Transparencies (only): \def\colo_basics_define_transpancy[#1][#2]% - {\ctxcommand{definetransparency("#1",#2)}} + {\clf_definetransparency{#1}#2\relax} % A goodie that replaces the startMPcolor hackery @@ -817,10 +817,15 @@ {\colo_basics_define_intermediate_indeed[#1][#2][#3]} \def\colo_basics_define_intermediate_indeed[#1][#2,#3,#4][#5]% - {\ctxcommand{defineintermediatecolor("#1","#2", - \thecolorattribute{#3},\thecolorattribute{#4}, - \thetransparencyattribute{#3},\thetransparencyattribute{#4}, - "#5",false,\v_colo_freeze_state)}% not global + {\clf_defineintermediatecolor % not global + {#1}{#2}% + \thecolorattribute{#3} % + \thecolorattribute{#4} % + \thetransparencyattribute{#3} % + \thetransparencyattribute{#4} % + {#5}% + \v_colo_freeze_state + \relax \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}} %D Here is a more efficient helper for pgf: @@ -860,7 +865,7 @@ %D \stopmode \def\pgf@context@registercolor#1% bonus macro - {\setevalue{\string\color@#1}{\noexpand\xcolor@{}{}\ctxcommand{pgfxcolorspec(\thecolorattribute{#1})}}} + {\setevalue{\string\color@#1}{\noexpand\xcolor@{}{}\clf_pgfxcolorspec\thecolorattribute{#1}}} %D \starttyping %D \ifdefined\pgf@context@registercolor @@ -942,7 +947,7 @@ {\let\maintextcolor\s!themaintextcolor \definecolor[\maintextcolor][#1]% can be fast one \colo_helpers_activate\maintextcolor - \ctxcommand{registermaintextcolor(\thecolorattribute\maintextcolor)}} + \clf_registermaintextcolor\thecolorattribute\maintextcolor\relax} \unexpanded\def\starttextcolor[#1]% {\doifsomething{#1} @@ -1055,27 +1060,38 @@ \let\colorformatseparator\space -\def\MPcolor #1{\ctxcommand {mpcolor(\number\attribute\colormodelattribute,\number\colo_helpers_inherited_current_ca{#1},\number\colo_helpers_inherited_current_ta{#1})}} -\def\MPoptions #1{\ctxcommand{mpoptions(\number\attribute\colormodelattribute,\number\colo_helpers_inherited_current_ca{#1},\number\colo_helpers_inherited_current_ta{#1})}} +\def\MPcolor#1% + {\clf_mpcolor + \attribute\colormodelattribute + \colo_helpers_inherited_current_ca{#1} % + \colo_helpers_inherited_current_ta{#1} } + + +\def\MPoptions#1% + {\clfmpoptions + \attribute\colormodelattribute + \colo_helpers_inherited_current_ca{#1} % + \colo_helpers_inherited_current_ta{#1} } + \def\thecolorattribute #1{\number\csname\??colorattribute \ifcsname\??colorattribute \currentcolorprefix#1\endcsname\currentcolorprefix#1\else\ifcsname\??colorattribute #1\endcsname#1\fi\fi\endcsname} \def\thetransparencyattribute#1{\number\csname\??transparencyattribute\ifcsname\??transparencyattribute\currentcolorprefix#1\endcsname\currentcolorprefix#1\else\ifcsname\??transparencyattribute#1\endcsname#1\fi\fi\endcsname} \def\thecolormodelattribute {\the\attribute\colormodelattribute} -\def\internalspotcolorname #1{\ctxcommand{spotcolorname(\thecolorattribute{#1})}} -\def\internalspotcolorparent #1{\ctxcommand{spotcolorparent(\thecolorattribute{#1})}} -\def\internalspotcolorsize #1{\ctxcommand{spotcolorvalue(\thecolorattribute{#1})}} +\def\internalspotcolorname #1{\clf_spotcolorname \thecolorattribute{#1} } +\def\internalspotcolorparent #1{\clf_spotcolorparent\thecolorattribute{#1} } +\def\internalspotcolorsize #1{\clf_spotcolorvalue \thecolorattribute{#1} } -\def\colorcomponents #1{\ctxcommand{colorcomponents(\thecolorattribute{#1})}} -\def\transparencycomponents #1{\ctxcommand{transparencycomponents(\thetransparencyattribute{#1})}} -\def\processcolorcomponents #1{\ctxcommand{processcolorcomponents(\thecolorattribute{#1},",")}} +\def\colorcomponents #1{\clf_colorcomponents \thecolorattribute{#1} } +\def\transparencycomponents #1{\clf_transparencycomponents\thetransparencyattribute{#1} } +\def\processcolorcomponents #1{\clf_processcolorcomponents\thecolorattribute{#1} } -\def\colorvalue #1{\ctxcommand{formatcolor(\thecolorattribute{#1},"\colorformatseparator")}} -\def\grayvalue #1{\ctxcommand{formatgray (\thecolorattribute{#1},"\colorformatseparator")}} +\def\colorvalue #1{\clf_formatcolor\thecolorattribute{#1}{\colorformatseparator}} +\def\grayvalue #1{\clf_formatgray \thecolorattribute{#1}{\colorformatseparator}} -\def\doifblackelse #1{\ctxcommand{doifblackelse(\thecolorattribute{#1})}} -\def\doifdrawingblackelse {\ctxcommand{doifdrawingblackelse()}} +\def\doifblackelse #1{\clf_doifblackelse\thecolorattribute{#1} } +\def\doifdrawingblackelse {\clf_doifdrawingblackelse} %D \macros %D {forcecolorhack} diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 61bfc0ca9..5835599a0 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{2015.03.25 22:13} +\newcontextversion{2015.03.26 19:19} %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/context-version.pdf b/tex/context/base/context-version.pdf index 4ffe51b69..57b949d98 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 8252c7b8c..c80621cda 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -28,7 +28,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2015.03.25 22:13} +\edef\contextversion{2015.03.26 19:19} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/file-ini.lua b/tex/context/base/file-ini.lua index e6acc9e5d..f47feca55 100644 --- a/tex/context/base/file-ini.lua +++ b/tex/context/base/file-ini.lua @@ -11,33 +11,42 @@ if not modules then modules = { } end modules ['file-ini'] = { . These methods have counterparts at the end.

--ldx]]-- + +local implement = interfaces.implement +local setmacro = interfaces.setmacro +local setcount = interfaces.setcount + resolvers.jobs = resolvers.jobs or { } -local texsetcount = tex.setcount +local filenametotable = file.nametotable +local findtexfile = resolvers.findtexfile -local context_setvalue = context.setvalue local commands_doifelse = commands.doifelse -function commands.splitfilename(fullname) - local t = file.nametotable(fullname) - local path = t.path - texsetcount("splitoffkind",(path == "" and 0) or (path == '.' and 1) or 2) - context_setvalue("splitofffull",fullname) - context_setvalue("splitoffpath",path) - context_setvalue("splitoffname",t.name) - context_setvalue("splitoffbase",t.base) - context_setvalue("splitofftype",t.suffix) +local function splitfilename(full) + local split = filenametotable(full) + local path = split.path + setcount("splitoffkind",(path == "" and 0) or (path == '.' and 1) or 2) + setmacro("splitofffull",full or "") + setmacro("splitoffpath",path or "") + setmacro("splitoffname",split.name or "") + setmacro("splitoffbase",split.base or "") + setmacro("splitofftype",split.suffix or "") end -function commands.doifparentfileelse(n) - commands_doifelse(n == environment.jobname or n == environment.jobname .. '.tex' or n == environment.outputfilename) +local function isparentfile(name) + return + name == environment.jobname + or name == environment.jobname .. '.tex' + or name == environment.outputfilename end -function commands.doiffileexistelse(name) - name = resolvers.findtexfile(name) - commands_doifelse(name and name ~= "") +local function istexfile(name) + local name = name and findtexfile(name) + return name ~= "" and name end -function commands.doifpathexistelse(name) - commands_doifelse(lfs.isdir(name)) -end +implement { name = "splitfilename", actions = splitfilename, arguments = "string" } +implement { name = "doifparentfileelse", actions = { isparentfile, commands_doifelse }, arguments = "string" } +implement { name = "doifpathexistelse", actions = { lfs.isdir, commands_doifelse }, arguments = "string" } +implement { name = "doiffileexistelse", actions = { istexfile, commands_doifelse }, arguments = "string" } diff --git a/tex/context/base/file-ini.mkvi b/tex/context/base/file-ini.mkvi index 633407fe2..4cc6ef62a 100644 --- a/tex/context/base/file-ini.mkvi +++ b/tex/context/base/file-ini.mkvi @@ -103,11 +103,11 @@ \the\everystartreadingfile \pushcatcodetable % saveguard \setcatcodetable\ctxcatcodes - \ctxcommand{pushregime()}}% temporarily this way + \clf_pushregime}% temporarily this way \unexpanded\def\stopreadingfile {\popcatcodetable % saveguard - \ctxcommand{popregime()}% temporarily this way + \clf_popregime % temporarily this way \the\everystopreadingfile \global\advance\readingfilelevel\minusone} @@ -134,13 +134,13 @@ %D \doiffileelse {filename} {found} {not found} %D \stoptyping -\def\doiffileexistselse#name{\ctxcommand{doiffileexistelse([[#name]])}} -\def\doifpathexistselse#name{\ctxcommand{doifpathexistelse([[#name]])}} +\unexpanded\def\doiffileelse {\clf_doiffileexistelse} +\unexpanded\def\doifpathelse {\clf_doifpathexistelse} +\unexpanded\def\doiffile #name{\clf_doiffileexistelse{#name}\firstofoneargument\gobbleoneargument} +\unexpanded\def\doifnotfile #name{\clf_doiffileexistelse{#name}\gobbleoneargument\firstofoneargument} -\def\doiffileelse {\doiffileexistselse} -\def\doifpathelse {\doifpathexistselse} -\def\doiffile #name{\doiffileexistselse{#name}\firstofoneargument\gobbleoneargument} -\def\doifnotfile #name{\doiffileexistselse{#name}\gobbleoneargument\firstofoneargument} +\let\doiffileexistselse\doiffileelse +\let\doifpathexistselse\doifpathelse %D \macros %D {doifparentfileelse} @@ -151,7 +151,7 @@ \ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi -\def\doifparentfileelse#name{\ctxcommand{doifparentfileelse([[#name]])}} +\unexpanded\def\doifparentfileelse{\clf_doifparentfileelse} %D \macros %D {splitfilename} @@ -187,7 +187,7 @@ \let\splitoffname\empty \let\splitofftype\empty -\def\splitfilename#name{\ctxcommand{splitfilename([[#name]])}} +\unexpanded\def\splitfilename{\clf_splitfilename} %D \macros %D {doonlyonce, doinputonce, doendinputonce} diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 9f5559290..a00cc228e 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -21,6 +21,7 @@ local settings_to_hash, hash_to_string = utilities.parsers.settings_to_hash, uti local formatcolumns = utilities.formatters.formatcolumns local mergehashes = utilities.parsers.mergehashes local formatters = string.formatters +local basename = file.basename local tostring, next, type, rawget, tonumber = tostring, next, type, rawget, tonumber local utfchar, utfbyte = utf.char, utf.byte @@ -44,6 +45,8 @@ local report_mapfiles = logs.reporter("fonts","mapfiles") local setmetatableindex = table.setmetatableindex +local implement = interfaces.implement + local fonts = fonts local handlers = fonts.handlers local otf = handlers.otf -- brrr @@ -141,10 +144,12 @@ end -- this will move elsewhere ... -function fonts.helpers.name(tfmdata) - return file.basename(type(tfmdata) == "number" and properties[tfmdata].name or tfmdata.properties.name) +local function getfontname(tfmdata) + return basename(type(tfmdata) == "number" and properties[tfmdata].name or tfmdata.properties.name) end +fonts.helpers.name = getfontname + if _LUAVERSION < 5.2 then utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name") @@ -871,7 +876,10 @@ end specifiers.splitcontext = splitcontext function specifiers.contexttostring(name,kind,separator,yes,no,strict,omit) -- not used - return hash_to_string(mergedtable(handlers[kind].features.defaults or {},setups[name] or {}),separator,yes,no,strict,omit) + return hash_to_string( + mergedtable(handlers[kind].features.defaults or {},setups[name] or {}), + separator, yes, no, strict, omit or { "number" } + ) end local function starred(features) -- no longer fallbacks here @@ -949,16 +957,29 @@ local getspecification = definers.getspecification do -- else too many locals - local ctx_setdefaultfontname = context.fntsetdefname - local ctx_setsomefontname = context.fntsetsomename - local ctx_setemptyfontsize = context.fntsetnopsize - local ctx_setsomefontsize = context.fntsetsomesize - local ctx_letvaluerelax = context.letvaluerelax + ----- ctx_setdefaultfontname = context.fntsetdefname + ----- ctx_setsomefontname = context.fntsetsomename + ----- ctx_setemptyfontsize = context.fntsetnopsize + ----- ctx_setsomefontsize = context.fntsetsomesize + ----- ctx_letvaluerelax = context.letvaluerelax local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming - function commands.definefont_one(str) + local scanners = tokens.scanners + local scanstring = scanners.string + local scaninteger = scanners.integer + local scanboolean = scanners.boolean + + local setmacro = tokens.setters.macro + + local scanners = interfaces.scanners + + -- function commands.definefont_one(str) + + scanners.definefont_one = function() + local str = scanstring() + starttiming(fonts) if trace_defining then report_defining("memory usage before: %s",statistics.memused()) @@ -968,29 +989,31 @@ do -- else too many locals local lookup, name, sub, method, detail = getspecification(fullname) if not name then report_defining("strange definition %a",str) - ctx_setdefaultfontname() + -- ctx_setdefaultfontname() elseif name == "unknown" then - ctx_setdefaultfontname() + -- ctx_setdefaultfontname() else - ctx_setsomefontname(name) + -- ctx_setsomefontname(name) + setmacro("somefontname",name,"global") end -- we can also use a count for the size if size and size ~= "" then local mode, size = lpegmatch(sizepattern,size) if size and mode then texsetcount("scaledfontmode",mode) - ctx_setsomefontsize(size) + -- ctx_setsomefontsize(size) + setmacro("somefontsize",size) else texsetcount("scaledfontmode",0) - ctx_setemptyfontsize() + -- ctx_setemptyfontsize() end elseif true then -- so we don't need to check in tex texsetcount("scaledfontmode",2) - ctx_setemptyfontsize() + -- ctx_setemptyfontsize() else texsetcount("scaledfontmode",0) - ctx_setemptyfontsize() + -- ctx_setemptyfontsize() end specification = definers.makespecification(str,lookup,name,sub,method,detail,size) if trace_defining then @@ -1007,33 +1030,28 @@ do -- else too many locals return (gsub(cs,".->", "")) end --- local scan_string = newtoken.scan_string --- local scan_dimen = newtoken.scan_dimen --- local scan_number = newtoken.scan_number --- local scan_boolean = newtoken.scan_boolean - --- function commands.definefont_two() - --- local global = scan_boolean() --- local cs = scan_string() --- local str = scan_string() --- local size = scan_number() --- local inheritancemode = scan_number() --- local classfeatures = scan_string() --- local fontfeatures = scan_string() --- local classfallbacks = scan_string() --- local fontfallbacks = scan_string() --- local mathsize = scan_number() --- local textsize = scan_number() --- local relativeid = scan_string() --- local classgoodies = scan_string() --- local goodies = scan_string() --- local classdesignsize = scan_string() --- local fontdesignsize = scan_string() --- local scaledfontmode = scan_number() - - function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks, - mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode) + -- function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks, + -- mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode) + + scanners.definefont_two = function() + + local global = scanboolean() -- \ifx\fontclass\empty\s!false\else\s!true\fi + local cs = scanstring () -- {#csname}% + local str = scanstring () -- \somefontfile + local size = scaninteger() -- \d_font_scaled_font_size + local inheritancemode = scaninteger() -- \c_font_feature_inheritance_mode + local classfeatures = scanstring () -- \m_font_class_features + local fontfeatures = scanstring () -- \m_font_features + local classfallbacks = scanstring () -- \m_font_class_fallbacks + local fontfallbacks = scanstring () -- \m_font_fallbacks + local mathsize = scaninteger() -- \fontface + local textsize = scaninteger() -- \d_font_scaled_text_face + local relativeid = scaninteger() -- \relativefontid + local classgoodies = scanstring () -- \m_font_class_goodies + local goodies = scanstring () -- \m_font_goodies + local classdesignsize = scanstring () -- \m_font_class_designsize + local fontdesignsize = scanstring () -- \m_font_designsize + local scaledfontmode = scaninteger() -- \scaledfontmode if trace_defining then report_defining("start stage two: %s (size %s)",str,size) @@ -1134,7 +1152,8 @@ do -- else too many locals if not tfmdata then report_defining("unable to define %a as %a",name,nice_cs(cs)) lastfontid = -1 - ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one + texsetcount("scaledfontsize",0) + -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one elseif type(tfmdata) == "number" then if trace_defining then report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", @@ -1144,7 +1163,8 @@ do -- else too many locals texdefinefont(global,cs,tfmdata) -- resolved (when designsize is used): local size = fontdata[tfmdata].parameters.size or 0 - ctx_setsomefontsize(size .. "sp") + -- ctx_setsomefontsize(size .. "sp") + setmacro("somefontsize",size.."sp") texsetcount("scaledfontsize",size) lastfontid = tfmdata else @@ -1171,7 +1191,8 @@ do -- else too many locals end -- resolved (when designsize is used): local size = tfmdata.parameters.size or 655360 - ctx_setsomefontsize(size .. "sp") + setmacro("somefontsize",size.."sp") + -- ctx_setsomefontsize(size .. "sp") texsetcount("scaledfontsize",size) lastfontid = id end @@ -1192,6 +1213,8 @@ do -- else too many locals stoptiming(fonts) end + -- + function definers.define(specification) -- local name = specification.name @@ -1585,6 +1608,8 @@ do -- else too many locals return utfchar(str) elseif t == "string" then return lpegmatch(splitter,str) or str + else + return str end end @@ -1594,23 +1619,23 @@ do -- else too many locals -- interfaces: - function commands.fontchar(n) - n = nametoslot(n) - if n then - context_char(n) - end - end + implement { + name = "fontchar", + actions = { nametoslot, context_char }, + arguments = "string", + } - function commands.fontcharbyindex(n) - n = indextoslot(n) - if n then - context_char(n) - end - end + implement { + name = "fontcharbyindex", + actions = { indextoslot, context_char }, + arguments = "integer", + } - function commands.tochar(str) - context(tochar(str)) - end + implement { + name = "tochar", + actions = { tochar, context }, + arguments = "string", + } end @@ -1753,91 +1778,6 @@ function fonts.currentid() return currentfont() or 0 end --- interfaces - -local commands_doifelse = commands.doifelse - -function commands.doifelsecurrentfonthasfeature(name) -- can be made faster with a supportedfeatures hash - local f = fontdata[currentfont()] - f = f and f.shared - f = f and f.rawdata - f = f and f.resources - f = f and f.features - commands_doifelse(f and (f.gpos[name] or f.gsub[name])) -end - -local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once - -local stripper = lpeg.patterns.stripzeros - -function commands.nbfs(amount,precision) - if precision ~= p then - p = precision - f = formatters["%0." .. p .. "fpt"] - end - context(lpegmatch(stripper,f(amount/65536))) -end - -function commands.featureattribute(tag) - context(contextnumber(tag)) -end - -function commands.setfontfeature(tag) - texsetattribute(0,contextnumber(tag)) -end - -function commands.resetfontfeature() - texsetattribute(0,0) -end - --- function commands.addfs(tag) withset(tag, 1) end --- function commands.subfs(tag) withset(tag,-1) end --- function commands.addff(tag) withfnt(tag, 2) end -- on top of font features --- function commands.subff(tag) withfnt(tag,-2) end -- on top of font features - -function commands.cleanfontname (name) context(names.cleanname(name)) end - -function commands.fontlookupinitialize (name) names.lookup(name) end -function commands.fontlookupnoffound () context(names.noflookups()) end -function commands.fontlookupgetkeyofindex(key,index) context(names.getlookupkey(key,index)) end -function commands.fontlookupgetkey (key) context(names.getlookupkey(key)) end - --- this might move to a runtime module: - -function commands.showchardata(n) - local tfmdata = fontdata[currentfont()] - if tfmdata then - if type(n) == "string" then - n = utfbyte(n) - end - local chr = tfmdata.characters[n] - if chr then - report_status("%s @ %s => %U => %c => %s",tfmdata.properties.fullname,tfmdata.parameters.size,n,n,serialize(chr,false)) - end - end -end - -function commands.showfontparameters(tfmdata) - -- this will become more clever - local tfmdata = tfmdata or fontdata[currentfont()] - if tfmdata then - local parameters = tfmdata.parameters - local mathparameters = tfmdata.mathparameters - local properties = tfmdata.properties - local hasparameters = parameters and next(parameters) - local hasmathparameters = mathparameters and next(mathparameters) - if hasparameters then - report_status("%s @ %s => text parameters => %s",properties.fullname,parameters.size,serialize(parameters,false)) - end - if hasmathparameters then - report_status("%s @ %s => math parameters => %s",properties.fullname,parameters.size,serialize(mathparameters,false)) - end - if not hasparameters and not hasmathparameters then - report_status("%s @ %s => no text parameters and/or math parameters",properties.fullname,parameters.size) - end - end -end - -- for the moment here, this will become a chain of extras that is -- hooked into the ctx registration (or scaler or ...) @@ -2019,79 +1959,145 @@ end -- end -- end -function commands.setfontofid(id) - context_getvalue(csnames[id]) -end +do --- more interfacing: + local scanners = tokens.scanners + local scanstring = scanners.string + local scaninteger = scanners.integer + local scandimen = scanners.dimen + local scanboolean = scanners.boolean -commands.definefontfeature = presetcontext + local setmacro = tokens.setters.macro -local cache = { } + local scanners = interfaces.scanners -local hows = { - ["+"] = "add", - ["-"] = "subtract", - ["="] = "replace", -} + function constructors.currentfonthasfeature(n) + local f = fontdata[currentfont()] + if not f then return end f = f.shared + if not f then return end f = f.rawdata + if not f then return end f = f.resources + if not f then return end f = f.features + return f and (f.gpos[n] or f.gsub[n]) + end -function commands.feature(how,parent,name,font) -- 0/1 test temporary for testing - if not how or how == 0 then - if trace_features and texgetattribute(0) ~= 0 then - report_cummulative("font %!font:name!, reset",fontdata[font or true]) - end - texsetattribute(0,0) - elseif how == true or how == 1 then - local hash = "feature > " .. parent - local done = cache[hash] - if trace_features and done then - report_cummulative("font %!font:name!, revive %a : %!font:features!",fontdata[font or true],parent,setups[numbers[done]]) - end - texsetattribute(0,done or 0) - else - local full = parent .. how .. name - local hash = "feature > " .. full - local done = cache[hash] - if not done then - local n = setups[full] - if n then - -- already defined - else - n = mergecontextfeatures(parent,name,how,full) - end - done = registercontextfeature(hash,full,how) - cache[hash] = done - if trace_features then - report_cummulative("font %!font:name!, %s %a : %!font:features!",fontdata[font or true],hows[how],full,setups[numbers[done]]) - end - end - texsetattribute(0,done) + implement { + name = "doifelsecurrentfonthasfeature", + actions = { currentfonthasfeature, commands.doifelse }, + arguments = "string" + } + + -- local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once + -- + -- local stripper = lpeg.patterns.stripzeros + -- + -- function commands.nbfs(amount,precision) + -- if precision ~= p then + -- p = precision + -- f = formatters["%0." .. p .. "fpt"] + -- end + -- context(lpegmatch(stripper,f(amount/65536))) + -- end + + local f = formatters["%0.2fpt"] -- normally this value is changed only once + + local stripper = lpeg.patterns.stripzeros + + scanners.nbfs = function() + context(lpegmatch(stripper,f(scandimen()/65536))) end -end -function commands.featurelist(...) - context(fonts.specifiers.contexttostring(...)) -end + commands.featureattribute = function(tag) context(contextnumber(tag)) end + commands.setfontfeature = function(tag) texsetattribute(0,contextnumber(tag)) end + commands.resetfontfeature = function() texsetattribute(0,0) end + commands.setfontofid = function(id) context_getvalue(csnames[id]) end + commands.definefontfeature = presetcontext + + scanners.featureattribute = function() context(contextnumber(scanstring())) end + scanners.setfontfeature = function() texsetattribute(0,contextnumber(scanstring())) end + scanners.resetfontfeature = function() texsetattribute(0,0) end + scanners.setfontofid = function() context_getvalue(csnames[scaninteger()]) end + scanners.definefontfeature = function() presetcontext(scanstring(),scanstring(),scanstring()) end -function commands.registerlanguagefeatures() - local specifications = languages.data.specifications - for i=1,#specifications do - local specification = specifications[i] - local language = specification.opentype - if language then - local script = specification.opentypescript or specification.script - if script then - local context = specification.context - if type(context) == "table" then - for i=1,#context do - definecontext(context[i], { language = language, script = script}) + local cache = { } + + local hows = { + ["+"] = "add", + ["-"] = "subtract", + ["="] = "replace", + } + + local function setfeature(how,parent,name,font) -- 0/1 test temporary for testing + if not how or how == 0 then + if trace_features and texgetattribute(0) ~= 0 then + report_cummulative("font %!font:name!, reset",fontdata[font or true]) + end + texsetattribute(0,0) + elseif how == true or how == 1 then + local hash = "feature > " .. parent + local done = cache[hash] + if trace_features and done then + report_cummulative("font %!font:name!, revive %a : %!font:features!",fontdata[font or true],parent,setups[numbers[done]]) + end + texsetattribute(0,done or 0) + else + local full = parent .. how .. name + local hash = "feature > " .. full + local done = cache[hash] + if not done then + local n = setups[full] + if n then + -- already defined + else + n = mergecontextfeatures(parent,name,how,full) + end + done = registercontextfeature(hash,full,how) + cache[hash] = done + if trace_features then + report_cummulative("font %!font:name!, %s %a : %!font:features!",fontdata[font or true],hows[how],full,setups[numbers[done]]) + end + end + texsetattribute(0,done) + end + end + + local function registerlanguagefeatures() + local specifications = languages.data.specifications + for i=1,#specifications do + local specification = specifications[i] + local language = specification.opentype + if language then + local script = specification.opentypescript or specification.script + if script then + local context = specification.context + if type(context) == "table" then + for i=1,#context do + definecontext(context[i], { language = language, script = script}) + end + elseif type(context) == "string" then + definecontext(context, { language = language, script = script}) end - elseif type(context) == "string" then - definecontext(context, { language = language, script = script}) end end end end + + implement { name = "resetfeature", actions = setfeature, arguments = { false } } + implement { name = "addfeature", actions = setfeature, arguments = { "'+'", "string", "string" } } + implement { name = "subtractfeature", actions = setfeature, arguments = { "'-'", "string", "string" } } + implement { name = "replacefeature", actions = setfeature, arguments = { "'='", "string", "string" } } + implement { name = "revivefeature", actions = setfeature, arguments = { true, "string" } } + + implement { + name = "featurelist", + actions = { fonts.specifiers.contexttostring, context }, + arguments = { "string", "'otf'", "string", "'yes'", "'no'", true } + } + + implement { + name = "registerlanguagefeatures", + actions = registerlanguagefeatures, + } + end -- a fontkern plug: @@ -2208,27 +2214,45 @@ function methods.nocolor(head,font,attr) return head, true end -function commands.purefontname(name) +local function purefontname(name) if type(name) == "number" then - name = fonts.helpers.name(name) + name = getfontname(name) end if type(name) == "string" then - context(file.basename(name)) + return basename(name) end end +implement { + name = "purefontname", + actions = { purefontname, context }, + arguments = "string", +} + local list = storage.shared.bodyfontsizes or { } storage.shared.bodyfontsizes = list -function commands.registerbodyfontsize(size) +local function registerbodyfontsize(size) list[size] = true end -function commands.getbodyfontsizes(separator) +implement { + name = "registerbodyfontsize", + actions = registerbodyfontsize, + arguments = "string" +} + +local function getbodyfontsizes(separator) context(concat(sortedkeys(list),separator)) end -function commands.processbodyfontsizes(command) +implement { + name = "getbodyfontsizes", + actions = getbodyfontsizes, + arguments = "string" +} + +local function processbodyfontsizes(command) local keys = sortedkeys(list) if command then local action = context[command] @@ -2239,3 +2263,52 @@ function commands.processbodyfontsizes(command) context(concat(keys,",")) end end + +implement { + name = "processbodyfontsizes", + actions = processbodyfontsizes, + arguments = "string" +} + +function commands.cleanfontname (name) context(names.cleanname(name)) end + +function commands.fontlookupinitialize (name) names.lookup(name) end +function commands.fontlookupnoffound () context(names.noflookups()) end +function commands.fontlookupgetkeyofindex(key,index) context(names.getlookupkey(key,index)) end +function commands.fontlookupgetkey (key) context(names.getlookupkey(key)) end + +-- this might move to a runtime module: + +function commands.showchardata(n) + local tfmdata = fontdata[currentfont()] + if tfmdata then + if type(n) == "string" then + n = utfbyte(n) + end + local chr = tfmdata.characters[n] + if chr then + report_status("%s @ %s => %U => %c => %s",tfmdata.properties.fullname,tfmdata.parameters.size,n,n,serialize(chr,false)) + end + end +end + +function commands.showfontparameters(tfmdata) + -- this will become more clever + local tfmdata = tfmdata or fontdata[currentfont()] + if tfmdata then + local parameters = tfmdata.parameters + local mathparameters = tfmdata.mathparameters + local properties = tfmdata.properties + local hasparameters = parameters and next(parameters) + local hasmathparameters = mathparameters and next(mathparameters) + if hasparameters then + report_status("%s @ %s => text parameters => %s",properties.fullname,parameters.size,serialize(parameters,false)) + end + if hasmathparameters then + report_status("%s @ %s => math parameters => %s",properties.fullname,parameters.size,serialize(mathparameters,false)) + end + if not hasparameters and not hasmathparameters then + report_status("%s @ %s => no text parameters and/or math parameters",properties.fullname,parameters.size) + end + end +end diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi index 35a9a642a..e1a7651fe 100644 --- a/tex/context/base/font-fea.mkvi +++ b/tex/context/base/font-fea.mkvi @@ -123,13 +123,13 @@ {\dotripleargument\font_basics_define_font_feature} \def\font_basics_define_font_feature[#featureset][#parent][#settings]% - {\ctxcommand{definefontfeature("#featureset","#parent","#settings")}} + {\clf_definefontfeature{#featureset}{#parent}{#settings}} \unexpanded\def\fontfeatureslist {\dodoubleargument\font_basics_features_list} \def\font_basics_features_list[#name][#separator]% todo: arg voor type - {\cldcommand{featurelist("#name","otf","\luaescapestring{#separator}","yes","no",true,{"number"})}} + {\clf_featurelist{#name}{\luaescapestring{#separator}}} \attribute\zerocount\zerocount % first in list, so fast match @@ -176,7 +176,7 @@ \fi} \unexpanded\def\font_feature_add_indeed - {\ctxcommand{feature("+","\m_font_feature_list","\m_font_feature_asked")}% + {\clf_addfeature{\m_font_feature_list}{\m_font_feature_asked}% \edef\m_font_feature_list{\m_font_feature_list+\m_font_feature_asked}% also + at the lua end \c_font_feature_state\plusone \let\currentfeature\m_font_feature_asked} @@ -191,7 +191,7 @@ \fi} \unexpanded\def\font_feature_subtract_indeed - {\ctxcommand{feature("-","\m_font_feature_list","\m_font_feature_asked")}% + {\clf_subtractfeature{\m_font_feature_list}{\m_font_feature_asked}% \edef\m_font_feature_list{\m_font_feature_list-\m_font_feature_asked}% also - at the lua end \c_font_feature_state\minusone \let\currentfeature\m_font_feature_asked} @@ -206,7 +206,7 @@ \fi} \unexpanded\def\font_feature_replace_indeed - {\ctxcommand{feature("=","\m_font_feature_list","\m_font_feature_asked")}% + {\clf_replacefeature{\m_font_feature_list}{\m_font_feature_asked}% \edef\m_font_feature_list{\m_font_feature_list=\m_font_feature_asked}% also = at the lua end \c_font_feature_state\zerocount \let\currentfeature\m_font_feature_asked} @@ -220,7 +220,7 @@ {\let\m_font_feature_asked\empty \let\currentfeature \s!current \let\m_font_feature_list \s!current - \ctxcommand{feature(false)}} + \clf_resetfeature} \unexpanded\def\revivefeature {\ifx\currentfeature\s!current \else @@ -228,7 +228,7 @@ \fi} \unexpanded\def\font_feature_revive_indeed - {\ctxcommand{feature(true,"\m_font_feature_list")}} + {\clf_revivefeature{\m_font_feature_list}} \unexpanded\def\font_feature_reset_add {\ifnum\c_font_feature_state=\plusone @@ -240,7 +240,7 @@ \fi} \unexpanded\def\font_feature_reset_add_indeed - {\ctxcommand{feature("+","\s!current","\m_font_feature_asked")}% + {\clf_addfeature{\s!current}{\m_font_feature_asked}% \edef\m_font_feature_list{\s!current+\m_font_feature_asked}% also + at the lua end \c_font_feature_state\plusone \let\currentfeature\m_font_feature_asked} @@ -284,12 +284,12 @@ % just for old times sake: \unexpanded\def\featureattribute#feature% - {\ctxcommand{featureattribute("#feature")}} + {\clf_featureattribute{#feature}} \unexpanded\def\setfontfeature#feature% {\edef\currentfeature{#feature}% \let\m_font_feature_list\currentfeature - \ctxcommand{setfontfeature("\currentfeature")}} + \clf_setfontfeature{\currentfeature}} \let\resetfontfeature\resetfeature @@ -324,11 +324,11 @@ % \doifelsecurrentfonthasfeature{kern}{YES}{NO} \def\doifelsecurrentfonthasfeature#feature% - {\ctxcommand{doifelsecurrentfonthasfeature("#feature")}} + {\clf_doifelsecurrentfonthasfeature{#feature}} % new: -\ctxcommand{registerlanguagefeatures()} +\clf_registerlanguagefeatures % also new diff --git a/tex/context/base/font-ini.mkvi b/tex/context/base/font-ini.mkvi index 60104f31a..9ab1962f6 100644 --- a/tex/context/base/font-ini.mkvi +++ b/tex/context/base/font-ini.mkvi @@ -419,24 +419,39 @@ %D When we assign for instance 12pt to a \DIMENSION\ register the \type %D {\the}'d value comes out as 12.0pt, which is often not the way users %D specify the bodyfont size. Therefore we use normalized values. They -%D are caches to save overhead in \LUA\ calls. +%D are cached to save overhead in \LUA\ calls. -\setnewconstant\fontdigits\plustwo +% \setnewconstant\fontdigits\plustwo % from now on always 2 \installcorenamespace{fontnormalizedbody} +% \def\normalizebodyfontsize#macro#body% +% {\expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname +% \ifx#macro\relax +% \normalizebodyfontsize_indeed#macro{#body}% +% \fi} +% +% \def\normalizebodyfontsize_indeed#macro#body% +% {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body,\number\fontdigits)}}% +% \global\expandafter\let\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} +% +% \def\thenormalizedbodyfontsize#body% +% {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}} +% +% caching is less relevant now + \def\normalizebodyfontsize#macro#body% - {\expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname + {\expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\dimexpr#body\endcsname \ifx#macro\relax \normalizebodyfontsize_indeed#macro{#body}% \fi} \def\normalizebodyfontsize_indeed#macro#body% - {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body,\number\fontdigits)}}% - \global\expandafter\let\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} + {\edef#macro{\clf_nbfs\dimexpr#body\relax}% + \global\expandafter\let\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} \def\thenormalizedbodyfontsize#body% - {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}} + {\clf_nbfs\dimexpr#body\relax} \edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize} \edef\normalizedlocalbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize} @@ -723,7 +738,9 @@ \unexpanded\def\font_helpers_low_level_define#specification#csname% {% we can now set more at the lua end - \ctxcommand{definefont_one(\!!bs\luaescapestring{#specification}\!!es)}% the escapestring catches at \somedimen + \global\let\somefontname\defaultfontfile + \let\somefontsize\empty + \clf_definefont_one{\luaescapestring{#specification}}% the escapestring catches at \somedimen % sets \scaledfontmode and \somefontname and \somefontsize \ifcase\fontface\relax % \let\v_font_size_absolute\textface % fontbody @@ -774,39 +791,43 @@ \else \d_font_scaled_text_face\textface \fi - \edef\somefontspec{at \number\d_font_scaled_font_size sp}% probably no longer used, needs checking + \edef\somefontspec{at \number\d_font_scaled_font_size sp}% \edef\somefontfile{\truefontname\somefontname}% \ifx\somefontfile\s!unknown \edef\somefontfile{\defaultfontfile}% \fi - \ifx\somefontfile\s!unknown - \edef\somefontfile{\defaultfontfile}% - \fi \font_helpers_update_font_parameters \font_helpers_update_font_class_parameters % \writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}% - \ctxcommand{definefont_two( - \ifx\fontclass\empty false\else true\fi, - "#csname", - \!!bs\somefontfile\!!es, - \number\d_font_scaled_font_size, - \number\c_font_feature_inheritance_mode, - "\m_font_class_features", - "\m_font_features", - "\m_font_class_fallbacks", - "\m_font_fallbacks", - \fontface, % 1/2/3: text script scriptscript 0/4/5: body x xx - \number\d_font_scaled_text_face, - "\number\relativefontid", % experiment - "\m_font_class_goodies", % experiment (not yet used) - "\m_font_goodies", - "\m_font_class_designsize", - "\m_font_designsize", - \number\scaledfontmode - )}% - \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) - \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname - \the\everydefinefont + \clf_definefont_two + \ifx\fontclass\empty\s!false\else\s!true\fi + {#csname}% + {\somefontfile}% + \d_font_scaled_font_size + \c_font_feature_inheritance_mode + {\m_font_class_features}% + {\m_font_features}% + {\m_font_class_fallbacks}% + {\m_font_fallbacks}% + \fontface + \d_font_scaled_text_face + \relativefontid + {\m_font_class_goodies}% + {\m_font_goodies}% + {\m_font_class_designsize}% + {\m_font_designsize}% + \scaledfontmode + \relax + \ifcase\scaledfontsize + %\scaledfontsize\plusone + \let\somefontspec\empty + \let\lastrawfontcall\relax + \expandafter\let\csname#csname\endcsname\relax + \else + \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) + \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname + \the\everydefinefont + \fi \c_font_feature_inheritance_mode\c_font_feature_inheritance_default} \def\font_helpers_check_body_scale#fontsize% gets character (x xx a etc) @@ -830,10 +851,10 @@ %D The following macros are used at the \LUA\ end. Watch the \type {\normal} %D hackery: this makes the mkvi parser happy. -\normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} % do before calling -\normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument -\normaldef\fntsetnopsize {\let\somefontsize\empty} % do before calling -\normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument +% \normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} % do before calling +% \normaldef\fntsetnopsize {\let\somefontsize\empty} % do before calling +% \normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument +% \normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument \newif\ifskipfontcharacteristics \skipfontcharacteristicstrue @@ -1190,10 +1211,10 @@ %D values are not consulted afterwards. \def\processbodyfontenvironmentlist#1% no \unexpanded as then we cannot use it in alignments - {\ctxcommand{processbodyfontsizes("\strippedcsname#1")}} + {\clf_processbodyfontsizes{\strippedcsname#1}} \def\bodyfontenvironmentlist - {\ctxcommand{getbodyfontsizes()}} + {\clf_getbodyfontsizes} \def\font_basics_define_body_font_environment_class[#class][#body][#settings]% {\edef\m_font_body{#body}% @@ -1204,7 +1225,7 @@ \normalizebodyfontsize\m_font_body_normalized\m_font_body \font_basics_define_body_font_environment_size[#class][\m_font_body_normalized][#settings]% %\addtocommalist\m_font_body_normalized\bodyfontenvironmentlist - \ctxcommand{registerbodyfontsize("\m_font_body_normalized")}% + \clf_registerbodyfontsize{\m_font_body_normalized}% \fi} %D The empty case uses the same code but needs to ignore the current class @@ -2207,11 +2228,6 @@ %D Handy for manuals: -\unexpanded\def\fontchar#character% - {\ctxcommand{fontchar(\!!bs#character\!!es)}} - -\unexpanded\def\fontcharbyindex#index% unofficial command, for idris' font building - {\ctxcommand{fontcharbyindex(\number#index)}} %D The \type {\tochar} commmand takes a specification: %D @@ -2227,14 +2243,13 @@ %D %D This is an expandable command! -\def\tochar#specifications% - {\ctxcommand{tochar(\!!bs#specifications\!!es)}} % expanded (also used in edef) +\unexpanded\def\fontchar #character{\clf_fontchar{#character}} +\unexpanded\def\fontcharbyindex #index{\clf_fontcharbyindex#index\relax} + \def\tochar #specifications{\clf_tochar{#specifications}} % expanded (also used in edef) -%D The next auxilliary macro is an alternative to \type -%D {\fontname}. +%D The next auxilliary macro is an alternative to \type {\fontname}. -\def\purefontname#font{\ctxcommand{purefontname(\!!bs\fontname#font\!!es)}} -%def\purefontname#font{\ctxcommand{purefontname(\number\fontid#font)}} +\def\purefontname#font{\clf_purefontname{\fontname#font}} %D \macros %D {switchstyleonly} diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi index be1e305b5..4b819f43a 100644 --- a/tex/context/base/font-lib.mkvi +++ b/tex/context/base/font-lib.mkvi @@ -102,6 +102,6 @@ % new: -\unexpanded\def\setfontofid#1{\ctxcommand{setfontofid(#1)}} +\unexpanded\def\setfontofid#1{\ctf_setfontofid#1\relax} \protect \endinput diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index 283d7dc72..751a6fa63 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -73,7 +73,9 @@ local new_latelua = nodes.pool.latelua local context = context +local implement = interfaces.implement local variables = interfaces.variables + local codeinjections = backends.codeinjections local nodeinjections = backends.nodeinjections @@ -192,6 +194,7 @@ end figures = figures or { } local figures = figures +figures.images = images figures.boxnumber = figures.boxnumber or 0 figures.defaultsearch = true figures.defaultwidth = 0 @@ -426,6 +429,9 @@ end function figures.registersuffix (suffix, target) register('list', target,suffix ) end function figures.registerpattern(pattern,target) register('pattern',target,pattern) end +implement { name = "registerfiguresuffix", actions = register, arguments = { "'list'", "string", "string" } } +implement { name = "registerfigurepattern", actions = register, arguments = { "'pattern'", "string", "string" } } + local last_locationset = last_locationset or nil local last_pathlist = last_pathlist or nil @@ -463,6 +469,8 @@ function figures.setpaths(locationset,pathlist) end end +implement { name = "setfigurepaths", actions = figures.setpaths, arguments = { "string", "string" } } + -- check conversions and handle it here function figures.hash(data) @@ -576,17 +584,13 @@ end figures.get = get -function commands.figurevariable(category,tag,default) - context(get(category,tag,default)) -end +implement { name = "figurestatus", actions = { get, context }, arguments = { "'status'", "string", "string" } } +implement { name = "figurerequest", actions = { get, context }, arguments = { "'request'", "string", "string" } } +implement { name = "figureused", actions = { get, context }, arguments = { "'used'", "string", "string" } } -function commands.figurestatus (tag,default) context(get("status", tag,default)) end -function commands.figurerequest(tag,default) context(get("request",tag,default)) end -function commands.figureused (tag,default) context(get("used", tag,default)) end - -function commands.figurefilepath() context(file.dirname (get("used","fullname"))) end -function commands.figurefilename() context(file.nameonly(get("used","fullname"))) end -function commands.figurefiletype() context(file.extname (get("used","fullname"))) end +implement { name = "figurefilepath", actions = { get, file.dirname, context }, arguments = { "'used'", "'fullname'" } } +implement { name = "figurefilename", actions = { get, file.nameonly, context }, arguments = { "'used'", "'fullname'" } } +implement { name = "figurefiletype", actions = { get, file.extname, context }, arguments = { "'used'", "'fullname'" } } -- todo: local path or cache path @@ -1098,8 +1102,8 @@ function figures.identify(data) local list = identifiers.list -- defined at the end for i=1,#list do local identifier = list[i] - data = identifier(data) - if data.status.status > 0 then + local data = identifier(data) + if data.status and data.status.status > 0 then break end end @@ -1560,8 +1564,8 @@ local epstopdf = { -dBATCH -dAutoRotatePages=/None -dPDFSETTINGS=/%presets% - -dCompatibilityLevel=%level% -dEPSCrop + -dCompatibilityLevel=%level% -sOutputFile="%newname%" "%oldname%" -c quit @@ -1615,6 +1619,7 @@ function epsconverter.pdf(oldname,newname,resolution) -- the resolution interfac newname = newname, oldname = tmpname, presets = presets, + level = tostring(level), } ) if tmpname ~= oldname then os.remove(tmpname) @@ -1634,10 +1639,11 @@ converters.pdf = pdfconverter -- pdfconverter.stripped = function(oldname,newname) -- local pdftoeps = programs.pdftoeps -- can be changed -- local epstopdf = programs.epstopdf -- can be changed --- local presets = epstopdf.resolutions[resolution or ""] or epstopdf.resolutions.high --- local tmpname = newname .. ".tmp" --- runprogram(pdftoeps.command, pdftoeps.argument, { oldname = oldname, newname = tmpname, presets = presets }) --- runprogram(epstopdf.command, epstopdf.argument, { oldname = tmpname, newname = newname, presets = presets }) +-- local presets = epstopdf.resolutions[resolution or ""] or epstopdf.resolutions.high +-- local level = codeinjections.getformatoption("pdf_level") or "1.3" +-- local tmpname = newname .. ".tmp" +-- runprogram(pdftoeps.command, pdftoeps.argument, { oldname = oldname, newname = tmpname, presets = presets, level = level }) +-- runprogram(epstopdf.command, epstopdf.argument, { oldname = tmpname, newname = newname, presets = presets, level = level }) -- os.remove(tmpname) -- end -- @@ -1833,6 +1839,8 @@ function bases.use(basename) end end +implement { name = "usefigurebase", actions = bases.use, arguments = "string" } + local function bases_find(basename,askedlabel) if trace_bases then report_inclusion("checking for %a in base %a",askedlabel,basename) @@ -1986,8 +1994,44 @@ end -- interfacing -commands.setfigurelookuporder = figures.setorder +implement { + name = "figure_push", + scope = "private", + actions = figures.push, + arguments = { + { + { "name" }, + { "label" }, + { "page" }, + { "size" }, + { "object" }, + { "prefix" }, + { "cache" }, + { "format" }, + { "preset" }, + { "controls" }, + { "resources" }, + { "preview" }, + { "display" }, + { "mask" }, + { "conversion" }, + { "resolution" }, + { "color" }, + { "repeat" }, + { "width", "dimen" }, + { "height", "dimen" }, + } + } +} + +-- beware, we get a number passed by default --- +implement { name = "figure_pop", scope = "private", actions = figures.pop } +implement { name = "figure_done", scope = "private", actions = figures.done } +implement { name = "figure_dummy", scope = "private", actions = figures.dummy } +implement { name = "figure_identify", scope = "private", actions = figures.identify } +implement { name = "figure_scale", scope = "private", actions = figures.scale } +implement { name = "figure_check", scope = "private", actions = figures.check } +implement { name = "figure_include", scope = "private", actions = figures.include } -figures.images = images +implement { name = "setfigurelookuporder", actions = figures.setorder, arguments = "string" } diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv index ca5fbc8c6..b3a21f073 100644 --- a/tex/context/base/grph-inc.mkiv +++ b/tex/context/base/grph-inc.mkiv @@ -310,56 +310,56 @@ \edef\p_label {\externalfigureparameter\c!label}% % \dostarttagged\t!image\empty - \ctxlua{figures.push { - name = "\p_grph_include_name", - label = "\ifx\p_label\empty\p_grph_include_label\else\p_label\fi", - page = "\externalfigureparameter\c!page", - size = "\externalfigureparameter\c!size", - object = "\externalfigureparameter\c!object", - prefix = "\externalfigureparameter\c!prefix", - cache = "\externalfigureparameter\c!cache", - format = "\externalfigureparameter\c!method", - preset = "\externalfigureparameter\c!prefix", - controls = "\externalfigureparameter\c!controls", - resources = "\externalfigureparameter\c!resources", - preview = "\externalfigureparameter\c!preview", - display = "\externalfigureparameter\c!display", - mask = "\externalfigureparameter\c!mask", - conversion = "\externalfigureparameter\c!conversion", - resolution = "\externalfigureparameter\c!resolution", - color = "\internalspotcolorparent{\externalfigureparameter\c!color}", % hack is needed - ["repeat"] = "\externalfigureparameter\c!repeat", - \ifx\p_width\empty \else - width = \number\dimexpr\p_width, - \fi - \ifx\p_height\empty \else - height = \number\dimexpr\p_height, - \fi - } }% - \ctxlua{figures.identify()}% - % also mode: checkpresense only + \clf_figure_push + name {\p_grph_include_name}% + label {\ifx\p_label\empty\p_grph_include_label\else\p_label\fi}% + page {\externalfigureparameter\c!page}% + size {\externalfigureparameter\c!size}% + object {\externalfigureparameter\c!object}% + prefix {\externalfigureparameter\c!prefix}% + cache {\externalfigureparameter\c!cache}% + format {\externalfigureparameter\c!method}% + preset {\externalfigureparameter\c!prefix}% + controls {\externalfigureparameter\c!controls}% + resources {\externalfigureparameter\c!resources}% + preview {\externalfigureparameter\c!preview}% + display {\externalfigureparameter\c!display}% + mask {\externalfigureparameter\c!mask}% + conversion {\externalfigureparameter\c!conversion}% + resolution {\externalfigureparameter\c!resolution}% + color {\internalspotcolorparent{\externalfigureparameter\c!color}}% hack is needed + repeat {\externalfigureparameter\c!repeat}% + \ifx\p_width\empty \else + width \dimexpr\p_width\relax + \fi + \ifx\p_height\empty \else + height \dimexpr\p_height\relax + \fi + \relax + \clf_figure_identify + \relax \ifconditional\c_grph_include_test_only \ifcase\figurestatus \else - \ctxlua{figures.check()}% - \ctxlua{figures.dummy()}% - \ctxlua{figures.scale()}% - \ctxlua{figures.done()}% + \clf_figure_check + \clf_figure_dummy + \clf_figure_scale + \clf_figure_done \fi \grph_include_set_mode \else \ifcase\figurestatus - \ctxlua{figures.dummy()}% - \ctxlua{figures.scale()}% + \clf_figure_dummy + \clf_figure_scale \else - \ctxlua{figures.check()}% - \ctxlua{figures.include()}% - \ctxlua{figures.scale()}% + \clf_figure_check + \clf_figure_include + \clf_figure_scale \fi - \ctxlua{figures.done()}% + \clf_figure_done \grph_include_set_mode \grph_include_finalize \fi - \ctxlua{figures.pop()}% + \clf_figure_pop \dotagfigure \naturalvbox attr \imageattribute 2 {\box\foundexternalfigure}% \dostoptagged @@ -426,13 +426,13 @@ {\dodoubleargument\grph_include_set_type_synonym} \def\grph_include_set_type_synonym[#1][#2]% - {\ctxlua{figures.registersuffix("#1","#2")}} + {\clf_registerfiguresuffix{#1}{#2}} %D Additional paths can be installed with the regular setup command. The next %D macro picks up the list. \unexpanded\def\setfigurepathlist - {\ctxlua{figures.setpaths("\externalfigureparameter\c!location",\!!bs\externalfigureparameter\c!directory\!!es)}} + {\clf_setfigurepaths{\externalfigureparameter\c!location}{\externalfigureparameter\c!directory}} %D Variables: @@ -442,36 +442,36 @@ \def\defaultfigurewidth {8\lineheight} \def\defaultfigureheight {6\lineheight} -\def\figurestatus {\numexpr\ctxcommand{figurestatus("status",0)}\relax} % number: 0 = not found -\def\figurewidth {\ctxcommand{figurestatus("width",0)}sp} -\def\figureheight {\ctxcommand{figurestatus("height",0)}sp} -\def\figurexscale {\ctxcommand{figurestatus("xscale",1)}} -\def\figureyscale {\ctxcommand{figurestatus("yscale",1)}} - -\def\figuresize {\ctxcommand{figurerequest("size")}} -\def\figurelabel {\ctxcommand{figurerequest("label")}} -\def\figurefileoriginal {\ctxcommand{figurerequest("name")}} -\def\figurefilepage {\ctxcommand{figurerequest("page",1)}} -\def\figurefileoptions {\ctxcommand{figurerequest("options")}} -\def\figurefileconversion{\ctxcommand{figurerequest("conversion")}} -\def\figurefilecache {\ctxcommand{figurerequest("cache")}} -\def\figurefileprefix {\ctxcommand{figurerequest("prefix")}} - -\def\figurenaturalwidth {\ctxcommand{figureused("width", \number\dimexpr\defaultfigurewidth \relax)}sp} -\def\figurenaturalheight {\ctxcommand{figureused("height",\number\dimexpr\defaultfigureheight\relax)}sp} -\def\figurexresolution {\ctxcommand{figureused("xresolution",0)}} -\def\figureyresolution {\ctxcommand{figureused("yresolution",0)}} -\def\figurexsize {\ctxcommand{figureused("xsize",0)}} -\def\figureysize {\ctxcommand{figureused("ysize",0)}} -\def\figurecolordepth {\ctxcommand{figureused("colordepth",0)}} -\def\figuredepth {\ctxcommand{figureused("depth",0)}} - -\def\figurefullname {\ctxcommand{figureused("fullname")}} -\def\noffigurepages {\ctxcommand{figureused("pages",0)}} - -\def\figurefilepath {\ctxcommand{figurefilepath()}} -\def\figurefilename {\ctxcommand{figurefilename()}} -\def\figurefiletype {\ctxcommand{figurefiletype()}} +\def\figurestatus {\numexpr\clf_figurestatus{status}{0}\relax} % number: 0 = not found +\def\figurewidth {\clf_figurestatus{width}{0}sp} +\def\figureheight {\clf_figurestatus{height}{0}sp} +\def\figurexscale {\clf_figurestatus{xscale}{1}} +\def\figureyscale {\clf_figurestatus{yscale}{1}} + +\def\figuresize {\clf_figurerequest{size}{}} +\def\figurelabel {\clf_figurerequest{label}{}} +\def\figurefileoriginal {\clf_figurerequest{name}{}} +\def\figurefilepage {\clf_figurerequest{page}{1}} +\def\figurefileoptions {\clf_figurerequest{options}{}} +\def\figurefileconversion{\clf_figurerequest{conversion}{}} +\def\figurefilecache {\clf_figurerequest{cache}{}} +\def\figurefileprefix {\clf_figurerequest{prefix}{}} + +\def\figurenaturalwidth {\clf_figureused{width}{\number\dimexpr\defaultfigurewidth\relax}sp} +\def\figurenaturalheight {\clf_figureused{height}{\number\dimexpr\defaultfigureheight\relax}sp} +\def\figurexresolution {\clf_figureused{xresolution}{0}} +\def\figureyresolution {\clf_figureused{yresolution}{0}} +\def\figurexsize {\clf_figureused{xsize}{0}} +\def\figureysize {\clf_figureused{ysize}{0}} +\def\figurecolordepth {\clf_figureused{colordepth}{0}} +\def\figuredepth {\clf_figureused{depth}{0}} + +\def\figurefullname {\clf_figureused{fullname}{}} +\def\noffigurepages {\clf_figureused{pages}{0}} + +\def\figurefilepath {\clf_figurefilepath} +\def\figurefilename {\clf_figurefilename} +\def\figurefiletype {\clf_figurefiletype} \let\naturalfigurewidth \figurenaturalwidth \let\naturalfigureheight \figurenaturalheight @@ -510,8 +510,8 @@ \fi} \appendtoks + \clf_setfigurepaths{\externalfigureparameter\c!location}{\externalfigureparameter\c!directory}% \ctxlua { % figures.defaultwidth .. maybe a dimen some day - figures.setpaths("\externalfigureparameter\c!location","\externalfigureparameter\c!directory") ; figures.defaultwidth = \number\dimexpr\defaultfigurewidth \relax ; figures.defaultheight = \number\dimexpr\defaultfigureheight\relax ; figures.boxnumber = \number\foundexternalfigure ; @@ -671,14 +671,14 @@ % Figure bases \unexpanded\def\usefigurebase[#1]% - {\ctxlua{figures.bases.use("#1")}} + {\clf_usefigurebase{#1}} \appendtoks \setfigurepathlist % the path may be used elsewhere too (as in x-res-04) \to \everysetupexternalfigure \appendtoks - \ctxcommand{setfigurelookuporder("\externalfigureparameter\c!order")}% + \clf_setfigurelookuporder{\externalfigureparameter\c!order}% \to \everysetupexternalfigure \definecolor[missingfigurecolor][s=.8] diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 0c8970609..9225b57b2 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -834,209 +834,45 @@ end -- experiment: --- local function make(t) --- local p --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if not p then --- if next(v) then --- p = P(k) * make(v) --- else --- p = P(k) --- end --- else --- if next(v) then --- p = p + P(k) * make(v) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end - --- local function make(t) --- local p = P(false) --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if next(v) then --- p = p + P(k) * make(v) --- else --- p = p + P(k) --- end --- end --- return p --- end - --- function lpeg.utfchartabletopattern(list) -- goes to util-lpg --- local tree = { } --- for i=1,#list do --- local t = tree --- for c in gmatch(list[i],".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- end --- return make(tree) --- end - local p_false = P(false) local p_true = P(true) --- local function make(t,hash) --- local p = p_false --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- local h = hash[v] --- if h then --- if next(v) then --- p = p + P(k) * (make(v,hash) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * make(v,hash) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end - --- local function make(t,hash) --- local p = p_false --- local keys = sortedkeys(t) --- local function making(t,w) --- local p = p_false --- local keys = sortedkeys(t) --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- if w then --- if next(v) then --- p = p + P(k) * (making(v,w) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * making(v,w) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end --- for i=1,#keys do --- local k = keys[i] --- local v = t[k] --- local h = hash[v] --- if h then --- if next(v) then --- p = p + P(k) * (making(v,true) + p_true) --- else --- p = p + P(k) * p_true --- end --- else --- if next(v) then --- p = p + P(k) * making(v,false) --- else --- p = p + P(k) --- end --- end --- end --- return p --- end --- --- function lpeg.utfchartabletopattern(list) -- goes to util-lpg --- local tree = { } --- local hash = { } --- local n = #list --- if n == 0 then --- for s in next, list do --- local t = tree --- for c in gmatch(s,".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- hash[t] = s --- end --- else --- for i=1,n do --- local t = tree --- local s = list[i] --- for c in gmatch(s,".") do --- local tc = t[c] --- if not tc then --- tc = { } --- t[c] = tc --- end --- t = tc --- end --- hash[t] = s --- end --- end --- return make(tree,hash) --- end - - -local function make(t,hash) - local p = p_false - local keys = sortedkeys(t) - local function making(t,w) +local function make(t) + local function making(t) local p = p_false local keys = sortedkeys(t) + local okay = t[""] for i=1,#keys do local k = keys[i] - local v = t[k] - if w then + if k ~= "" then + local v = t[k] if v == true then p = p + P(k) * p_true + elseif v == false then + -- can't happen + elseif okay then + p = p + P(k) * (making(v) + p_true) else - p = p + P(k) * (making(v,w) + p_true) - end - else - if v == true then - p = p + P(k) - else - p = p + P(k) * making(v,w) + p = p + P(k) * making(v) end end end return p end + local p = p_false + local keys = sortedkeys(t) for i=1,#keys do local k = keys[i] - local v = t[k] - local h = hash[v] - if h then + if k ~= "" then + local v = t[k] if v == true then p = p + P(k) * p_true + elseif v == false then + -- can't happen + elseif v[""] then + p = p + P(k) * (making(v) + p_true) else - p = p + P(k) * (making(v,true) + p_true) - end - else - if v == true then - p = p + P(k) - else - p = p + P(k) * making(v,false) + p = p + P(k) * making(v) end end end @@ -1045,61 +881,99 @@ end function lpeg.utfchartabletopattern(list) -- goes to util-lpg local tree = { } --- local hash = { } - local hash local n = #list if n == 0 then - hash = list for s in next, list do local t = tree local p, pk for c in gmatch(s,".") do if t == true then - t = { [c] = true } + t = { [c] = true, [""] = true } + p[pk] = t + p = t + t = false + elseif t == false then + t = { [c] = false } p[pk] = t p = t - t = true + t = false else local tc = t[c] if not tc then - tc = true - t[c] = tc + tc = false + t[c] = false end p = t t = tc end pk = c end + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end end else - hash = { } for i=1,n do - local t = tree local s = list[i] + local t = tree local p, pk for c in gmatch(s,".") do if t == true then - t = { [c] = true } + t = { [c] = true, [""] = true } p[pk] = t p = t - t = true + t = false + elseif t == false then + t = { [c] = false } + p[pk] = t + p = t + t = false else local tc = t[c] if not tc then - tc = true - t[c] = true + tc = false + t[c] = false end p = t t = tc end pk = c end - hash[s] = true + if t == false then + p[pk] = true + elseif t == true then + -- okay + else + t[""] = true + end end end - return make(tree,hash) +-- inspect(tree) + return make(tree) end +-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef" } +-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) +-- +-- inspect(lpegmatch(p,"a")) +-- inspect(lpegmatch(p,"aaaa")) +-- inspect(lpegmatch(p,"ac")) +-- inspect(lpegmatch(p,"bc")) +-- inspect(lpegmatch(p,"zzbczz")) +-- inspect(lpegmatch(p,"zzabezz")) +-- inspect(lpegmatch(p,"ab")) +-- inspect(lpegmatch(p,"abc")) +-- inspect(lpegmatch(p,"abe")) +-- inspect(lpegmatch(p,"xa")) +-- inspect(lpegmatch(p,"bx")) +-- inspect(lpegmatch(p,"bax")) +-- inspect(lpegmatch(p,"abxyz")) +-- inspect(lpegmatch(p,"foobarbefcrap")) + -- lpeg.utfchartabletopattern { -- utfchar(0x00A0), -- nbsp -- utfchar(0x2000), -- enquad diff --git a/tex/context/base/lang-hyp.lua b/tex/context/base/lang-hyp.lua index 68edcfc85..7bd307f8e 100644 --- a/tex/context/base/lang-hyp.lua +++ b/tex/context/base/lang-hyp.lua @@ -1433,6 +1433,7 @@ if context then local getcount = tex.getcount + hyphenators.methods = methods hyphenators.optimize = false function hyphenators.handler(head,groupcode) diff --git a/tex/context/base/lang-hyp.mkiv b/tex/context/base/lang-hyp.mkiv index b2281135c..24faed9cc 100644 --- a/tex/context/base/lang-hyp.mkiv +++ b/tex/context/base/lang-hyp.mkiv @@ -229,6 +229,9 @@ % \sethyphenationfeatures % [default,fences] +% \setuphyphenation % will be default +% [method=expanded] + \protect \endinput % \starttext diff --git a/tex/context/base/lxml-ini.mkiv b/tex/context/base/lxml-ini.mkiv index d82023c39..76d34032d 100644 --- a/tex/context/base/lxml-ini.mkiv +++ b/tex/context/base/lxml-ini.mkiv @@ -24,84 +24,86 @@ \registerctxluafile{lxml-ent}{1.001} % entity hacks \registerctxluafile{lxml-tex}{1.001} % tex finalizers \registerctxluafile{lxml-dir}{1.001} % ctx hacks +\registerctxluafile{lxml-ini}{1.001} % interface \unprotect % todo \!!bs \!!es where handy (slower) +% todo: { } mandate +% avoid # + \def\ctxlxml #1{\ctxlua{lxml.#1}} -\def\xmlmain #1{\ctxlxml{main("#1")}} -\def\xmlmatch #1{\ctxlxml{match("#1")}} -\def\xmlall #1#2{\ctxlxml{all("#1","#2")}} -\def\xmlatt #1#2{\ctxlxml{att("#1","#2")}} -\def\xmlattdef #1#2#3{\ctxlxml{att("#1","#2","#3")}} -\def\xmlchainatt #1#2{\ctxlxml{chainattribute("#1","/","#2")}} -\def\xmlchainattdef #1#2#3{\ctxlxml{chainattribute("#1","/","#2","#3")}} -\def\xmlattribute #1#2#3{\ctxlxml{attribute("#1","#2","#3")}} -\def\xmlattributedef #1#2#3#4{\ctxlxml{attribute("#1","#2","#3","#4")}} -\def\xmlcommand #1#2#3{\ctxlxml{command("#1","#2","#3")}} -\def\xmlconcat #1#2#3{\ctxlxml{concat("#1","#2",[[\detokenize{#3}]])}} -\def\xmlconcatrange #1#2#3#4#5{\ctxlxml{concatrange("#1","#2","#3","#4",[[\detokenize{#5}]])}} -\def\xmlcount #1#2{\ctxlxml{count("#1","#2")}} -\def\xmldelete #1#2{\ctxlxml{delete("#1","#2")}} -\def\xmldirectives #1{\ctxlxml{directives.setup("#1")}} -\def\xmldirectivesbefore #1{\ctxlxml{directives.before("#1")}} -\def\xmldirectivesafter #1{\ctxlxml{directives.after("#1")}} -\def\xmlfilter #1#2{\ctxlxml{filter("#1",\!!bs#2\!!es)}} -\def\xmlfilterlist #1#2{\ctxlxml{filterlist("#1",\!!bs#2\!!es)}} -\def\xmlfunction #1#2{\ctxlxml{applyfunction("#1",\!!bs#2\!!es)}} -\def\xmlfirst #1#2{\ctxlxml{first("#1","#2")}} -\def\xmlflush #1{\ctxlxml{flush("#1")}} -\def\xmlflushlinewise #1{\ctxlxml{flushlinewise("#1")}} -\def\xmlflushspacewise #1{\ctxlxml{flushspacewise("#1")}} -%def\xmlcontent #1{\ctxlxml{content("#1")}} -%def\xmlflushstripped #1{\ctxlxml{strip("#1",true)}} -\def\xmldirect #1{\ctxlxml{direct("#1")}} % in loops, not dt but root -\def\xmlinclude #1#2#3{\ctxlxml{include("#1","#2","#3",true)}} -\def\xmlincludeoptions#1#2#3#4{\ctxlxml{include("#1","#2","#3","#4")}} -\def\xmlinclusion #1{\ctxlxml{inclusion("#1")}} -\def\xmlinclusions #1{\ctxlxml{inclusions("#1")}} -\def\xmlsave #1#2{\ctxlxml{save("#1","#2")}} -\def\xmlindex #1#2#3{\ctxlxml{index("#1","#2",\number#3)}} -\def\xmlinfo #1{\hbox{\ttxx[\ctxlxml{info("#1")}]}} +%def\xmlcontent #1{\clf_xmlcontent {#1}} +%def\xmlflushstripped #1{\clf_xmlflushstripped {#1}} +\def\xmlall #1#2{\clf_xmlall {#1}{#2}} +\def\xmlatt #1#2{\clf_xmlatt {#1}{#2}} +\def\xmlattdef #1#2#3{\clf_xmlattdef {#1}{#2}{#3}} +\def\xmlattribute #1#2#3{\clf_xmlattribute {#1}{#2}{#3}} +\def\xmlattributedef #1#2#3#4{\clf_xmlattributedef {#1}{#2}{#3}{#4}} +\def\xmlchainatt #1#2{\clf_xmlchainatt {#1}{/}{#2}} +\def\xmlchainattdef #1#2#3{\clf_xmlchainattdef {#1}{/}{#2}{#3}} +\def\xmlchecknamespace #1#2#3{\clf_xmlchecknamespace {#1}{#2}{#3}} % element +\def\xmlcommand #1#2#3{\clf_xmlcommand {#1}{#2}{#3}} +\def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}} +\def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange {#1}{#2}{#3}{#4}{\detokenize{#5}}} +\def\xmlcontext #1#2{\clf_xmlcontext {#1}{#2}} +\def\xmlcount #1#2{\clf_xmlcount {#1}{#2}} +\def\xmldelete #1#2{\clf_xmldelete {#1}{#2}} +\def\xmldirect #1{\clf_xmldirect {#1}} % in loops, not dt but root +\def\xmldirectives #1{\clf_xmldirectives {#1}} +\def\xmldirectivesafter #1{\clf_xmldirectivesafter {#1}} +\def\xmldirectivesbefore #1{\clf_xmldirectivesbefore {#1}} +\def\xmldisplayverbatim #1{\clf_xmldisplayverbatim {#1}} +\def\xmlelement #1#2{\clf_xmlelement {#1}{#2}} +\def\xmlfilter #1#2{\clf_xmlfilter {#1}{#2}} +\def\xmlfilterlist #1#2{\clf_xmlfilterlist {#1}{#2}} +\def\xmlfirst #1#2{\clf_xmlfirst {#1}{#2}} +\def\xmlflush #1{\clf_xmlflush {#1}} +\def\xmlflushcontext #1{\clf_xmlflushcontext {#1}} +\def\xmlflushlinewise #1{\clf_xmlflushlinewise {#1}} +\def\xmlflushspacewise #1{\clf_xmlflushspacewise {#1}} +\def\xmlfunction #1#2{\clf_xmlfunction {#1}{#2}} +\def\xmlinclude #1#2#3{\clf_xmlinclude {#1}{#2}{#3}} +\def\xmlincludeoptions#1#2#3#4{\clf_xmlincludeoptions {#1}{#2}{#3}{#4}} +\def\xmlinclusion #1{\clf_xmlinclusion {#1}} +\def\xmlinclusions #1{\clf_xmlinclusions {#1}} +\def\xmlindex #1#2#3{\clf_xmlindex {#1}{#2}#3 } +\def\xmlinlineverbatim #1{\clf_xmlinlineverbatim {#1}} +\def\xmllast #1#2{\clf_xmllast {#1}{#2}} +\def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} +\def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} +\def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} +\def\xmlloaddirectives #1{\clf_xmlloaddirectives {#1}} +\def\xmlloadregistered #1#2{\clf_xmlloadregistered {#1}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} +\def\xmlmain #1{\clf_xmlmain {#1}} +\def\xmlmatch #1{\clf_xmlmatch {#1}} +\def\xmlname #1{\clf_xmlname {#1}} +\def\xmlnamespace #1{\clf_xmlnamespace {#1}} +\def\xmlnonspace #1#2{\clf_xmlnonspace {#1}{#2}} +\def\xmlpos #1{\clf_xmlpos {#1}} +\def\xmlraw #1#2{\clf_xmlraw {#1}{#2}} +\def\xmlregisterns #1#2{\clf_xmlregisterns {#1}{#2}} % document +\def\xmlremapname #1#2#3#4{\clf_xmlremapname {#1}{#2}{#3}{#4}} % element +\def\xmlremapnamespace #1#2#3{\clf_xmlremapnamespace {#1}{#2}{#3}} % document +\def\xmlsave #1#2{\clf_xmlsave {#1}{#2}} +\def\xmlsetfunction #1#2#3{\clf_xmlsetfunction {#1}{#2}{#3}} +\def\xmlsetsetup #1#2#3{\clf_xmlsetsetup {#1}{#2}{#3}} +\def\xmlsnippet #1#2{\clf_xmlsnippet {#1}{#2}} +\def\xmlstrip #1#2{\clf_xmlstrip {#1}{#2}} +\def\xmlstripanywhere #1#2{\clf_xmlstripanywhere {#1}{#2}} +\def\xmlstripnolines #1#2{\clf_xmlstripnolines {#1}{#2}} +\def\xmlstripped #1#2{\clf_xmlstripped {#1}{#2}} +\def\xmlstrippednolines #1#2{\clf_xmlstrippednolines {#1}{#2}} +\def\xmltag #1{\clf_xmltag {#1}} +\def\xmltext #1#2{\clf_xmltext {#1}{#2}} +\def\xmltobuffer #1#2#3{\clf_xmltobuffer {#1}{#2}{#3}} % id pattern name +\def\xmltobufferverbose #1#2#3{\clf_xmltobufferverbose {#1}{#2}{#3}} % id pattern name +\def\xmltofile #1#2#3{\clf_xmltofile {#1}{#2}{#3}} % id pattern filename +\def\xmltoparameters #1{\clf_xmltoparameters {#1}} +\def\xmlverbatim #1{\clf_xmlverbatim {#1}} + +\def\xmlinfo #1{\hbox{\ttxx[\clf_xmlinfo{#1}]}} \def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} -\def\xmllast #1#2{\ctxlxml{last("#1","#2")}} -\def\xmlname #1{\ctxlxml{name("#1")}} -\def\xmlnamespace #1{\ctxlxml{namespace("#1")}} -\def\xmlnonspace #1#2{\ctxlxml{nonspace("#1","#2")}} -\def\xmlraw #1#2{\ctxlxml{raw("#1","#2")}} -\def\xmlcontext #1#2{\ctxlxml{context("#1","#2")}} -\def\xmlflushcontext #1{\ctxlxml{context("#1")}} -\def\xmlsnippet #1#2{\ctxlxml{snippet("#1",#2)}} -\def\xmlelement #1#2{\ctxlxml{element("#1",#2)}} -\def\xmlregisterns #1#2{\ctxlua{xml.registerns("#1","#2")}} % document -\def\xmlremapname #1#2#3#4{\ctxlua{xml.remapname(lxml.id("#1"),"#2","#3","#4")}} % element -\def\xmlremapnamespace #1#2#3{\ctxlua{xml.renamespace(lxml.id("#1"),"#2","#3")}} % document -\def\xmlchecknamespace #1#2#3{\ctxlua{xml.checknamespace(lxml.id("#1"),"#2","#3")}} % element -\def\xmlsetfunction #1#2#3{\ctxlxml{setaction("#1",\!!bs#2\!!es,"#3")}} -\def\xmlsetsetup #1#2#3{\ctxlxml{setsetup("#1",\!!bs#2\!!es,"#3")}} -\def\xmlstrip #1#2{\ctxlxml{strip("#1","#2")}} -\def\xmlstripnolines #1#2{\ctxlxml{strip("#1","#2",true)}} -\def\xmlstripanywhere #1#2{\ctxlxml{strip("#1","#2",true,true)}} -\def\xmlstripped #1#2{\ctxlxml{stripped("#1","#2")}} -\def\xmlstrippednolines #1#2{\ctxlxml{stripped("#1","#2",true)}} -\def\xmltag #1{\ctxlxml{tag("#1")}} -\def\xmltext #1#2{\ctxlxml{text("#1","#2")}} -\def\xmlverbatim #1{\ctxlxml{verbatim("#1")}} -\def\xmldisplayverbatim #1{\ctxlxml{displayverbatim("#1")}} -\def\xmlinlineverbatim #1{\ctxlxml{inlineverbatim("#1")}} - -\def\xmlload #1#2{\ctxlxml{load("#1","#2","\directxmlparameter\c!entities","\directxmlparameter\c!compress")}} -\def\xmlloadbuffer #1#2{\ctxlxml{loadbuffer("#1","#2","\directxmlparameter\c!entities","\directxmlparameter\c!compress")}} -\def\xmlloaddata #1#2{\ctxlxml{loaddata("#1",\!!bs#2\!!es,"\directxmlparameter\c!entities","\directxmlparameter\c!compress")}} -\def\xmlloadregistered #1#2{\ctxlxml{loadregistered("#1","\directxmlparameter\c!entities","\directxmlparameter\c!compress")}} -\def\xmlloaddirectives #1{\ctxlxml{directives.load("any:///#1")}} -\def\xmlpos #1{\ctxlxml{pos("#1")}} - -\def\xmltoparameters #1{\ctxlxml{toparameters("#1")}} - -\def\xmltofile #1#2#3{\ctxlxml{tofile("#1","#2","#3")}} % id pattern filename -\def\xmltobuffer #1#2#3{\ctxlxml{tobuffer("#1","#2","#3")}} % id pattern name -\def\xmltobufferverbose #1#2#3{\ctxlxml{tobuffer("#1","#2","#3",true)}} % id pattern name % goodie: @@ -115,24 +117,24 @@ % kind of special: -\def\xmlstartraw{\ctxlxml{startraw()}} -\def\xmlstopraw {\ctxlxml{stopraw()}} +\def\xmlstartraw{\clf_xmlstartraw} % \let +\def\xmlstopraw {\clf_xmlstopraw} % \let % todo: \xmldoifelseattribute -\def\xmldoif #1#2{\ctxlxml{doif (\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable -\def\xmldoifnot #1#2{\ctxlxml{doifnot (\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable -\def\xmldoifelse #1#2{\ctxlxml{doifelse (\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable -\def\xmldoiftext #1#2{\ctxlxml{doiftext (\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable -\def\xmldoifnottext #1#2{\ctxlxml{doifnottext (\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable -\def\xmldoifelsetext #1#2{\ctxlxml{doifelsetext(\!!bs#1\!!es,\!!bs#2\!!es)}} % expandable +\def\xmldoif #1#2{\clf_xmldoif {#1}{#2}} % expandable +\def\xmldoifnot #1#2{\clf_xmldoifnot {#1}{#2}} % expandable +\def\xmldoifelse #1#2{\clf_xmldoifelse {#1}{#2}} % expandable +\def\xmldoiftext #1#2{\clf_xmldoiftext {#1}{#2}} % expandable +\def\xmldoifnottext #1#2{\clf_xmldoifnottext {#1}{#2}} % expandable +\def\xmldoifelsetext #1#2{\clf_xmldoifelsetext {#1}{#2}} % expandable -\def\xmldoifempty #1#2{\ctxlxml{doifempty ("#1","#2")}} -\def\xmldoifnotempty #1#2{\ctxlxml{doifnotempty ("#1","#2")}} -\def\xmldoifelseempty #1#2{\ctxlxml{doifelseempty("#1","#2")}} -\def\xmldoifselfempty #1{\ctxlxml{doifempty ("#1")}} -\def\xmldoifnotselfempty #1{\ctxlxml{doifnotempty ("#1")}} -\def\xmldoifelseselfempty #1{\ctxlxml{doifelseempty("#1")}} +\def\xmldoifempty #1#2{\clf_xmldoifempty {#1}{#2}} +\def\xmldoifnotempty #1#2{\clf_xmldoifnotempty {#1}{#2}} +\def\xmldoifelseempty #1#2{\clf_xmldoifelseempty {#1}{#2}} +\def\xmldoifselfempty #1{\clf_xmldoifselfempty {#1}} +\def\xmldoifnotselfempty #1{\clf_xmldoifnotselfempty {#1}} +\def\xmldoifelseselfempty #1{\clf_xmldoifelseselfempty{#1}} % \startxmlsetups xml:include % \xmlinclude{main}{include}{filename|href} @@ -153,21 +155,21 @@ % todo: 1:xml:whatever always before 3:xml:something -\unexpanded\def\xmlprependsetup #1{\ctxlxml{installsetup(1,"*","#1")}} -\unexpanded\def\xmlappendsetup #1{\ctxlxml{installsetup(2,"*","#1")}} -\unexpanded\def\xmlbeforesetup #1#2{\ctxlxml{installsetup(3,"*","#1","#2")}} -\unexpanded\def\xmlaftersetup #1#2{\ctxlxml{installsetup(4,"*","#1","#2")}} +\unexpanded\def\xmlprependsetup #1{\clf_xmlprependsetup {*}{#1}} +\unexpanded\def\xmlappendsetup #1{\clf_xmlappendsetup {*}{#1}} +\unexpanded\def\xmlbeforesetup #1#2{\clf_xmlbeforesetup {*}{#1}{#2}} +\unexpanded\def\xmlaftersetup #1#2{\clf_xmlaftersetup {*}{#1}{#2}} -\unexpanded\def\xmlprependdocumentsetup #1#2{\ctxlxml{installsetup(1,"#1","#2")}} -\unexpanded\def\xmlappenddocumentsetup #1#2{\ctxlxml{installsetup(2,"#1","#2")}} -\unexpanded\def\xmlbeforedocumentsetup#1#2#3{\ctxlxml{installsetup(3,"#1","#2","#3")}} -\unexpanded\def\xmlafterdocumentsetup #1#2#3{\ctxlxml{installsetup(4,"#1","#2","#3")}} +\unexpanded\def\xmlprependdocumentsetup #1#2{\clf_xmlprependdocumentsetup{#1}{#2}} +\unexpanded\def\xmlappenddocumentsetup #1#2{\clf_xmlappenddocumentsetup {#1}{#2}} +\unexpanded\def\xmlbeforedocumentsetup #1#2#3{\clf_xmlbeforedocumentsetup {#1}{#2}{#3}} +\unexpanded\def\xmlafterdocumentsetup #1#2#3{\clf_xmlafterdocumentsetup {#1}{#2}{#3}} -\unexpanded\def\xmlremovesetup #1{\ctxlxml{removesetup("*","#1")}} -\unexpanded\def\xmlremovedocumentsetup #1#2{\ctxlxml{removesetup("#1","#2")}} +\unexpanded\def\xmlremovesetup #1{\clf_xmlremovesetup {*}{#1}} +\unexpanded\def\xmlremovedocumentsetup #1#2{\clf_xmlremovedocumentsetup {#1}{#2}} -\unexpanded\def\xmlflushdocumentsetups #1#2{\ctxlxml{flushsetups("#1","*","#2")}} % #1 == id where to apply * and #2 -\unexpanded\def\xmlresetdocumentsetups #1{\ctxlxml{resetsetups("#1")}} +\unexpanded\def\xmlflushdocumentsetups #1#2{\clf_xmlflushdocumentsetups {#1}{*}{#2}} % #1 == id where to apply * and #2 +\unexpanded\def\xmlresetdocumentsetups #1{\clf_xmlresetdocumentsetups {#1}} \let\xmlregistersetup \xmlappendsetup \let\xmlregisterdocumentsetup\xmlappenddocumentsetup @@ -187,8 +189,8 @@ \xmldefaulttotext{#1}% after include \xmlstoptiming} -\unexpanded\def\xmlstarttiming{\ctxlua{statistics.starttiming(lxml)}} -\unexpanded\def\xmlstoptiming {\ctxlua{statistics.stoptiming (lxml)}} +\unexpanded\def\xmlstarttiming{\clf_xmlstarttiming} +\unexpanded\def\xmlstoptiming {\clf_xmlstoptiming} \def\lxml_process#1#2#3#4#5% flag \loader id name what initializersetup {\begingroup @@ -283,10 +285,6 @@ \def\inlinemessage #1{\dontleavehmode{\tttf#1}} \def\displaymessage#1{\blank\inlinemessage{#1}\blank} -% \def\xmltraceentities % settextcleanup is not defined -% {\ctxlua{xml.settextcleanup(lxml.trace_text_entities)}% -% \appendtoks\ctxlxml{showtextentities()}\to\everygoodbye} - % processing instructions \def\xmlcontextdirective#1% kind class key value @@ -313,15 +311,15 @@ \letvalue{\??xmldefaults\v!text }\plusone \letvalue{\??xmldefaults\v!hidden}\plustwo -\unexpanded\def\xmldefaulttotext#1% +\unexpanded\def\xmldefaulttotext {\ifcase\xmlprocessingmode - % unset + \expandafter\gobbleoneargument % unset \or - \ctxlxml{setcommandtotext("#1")}% 1 + \expandafter\clf_xmlsetcommandtotext % 1 \or - \ctxlxml{setcommandtonone("#1")}% 2 + \expandafter\clf_xmlsetcommandtonone % 2 \else - % unset + \expandafter\gobbleoneargument % unset \fi} \appendtoks @@ -343,16 +341,16 @@ %D Experimental: -\def\xmlgetindex #1{\ctxlxml{getindex("\xmldocument","#1")}} -\def\xmlwithindex #1#2{\ctxlxml{withindex("\xmldocument","#1","#2")}} +\def\xmlgetindex #1{\clf_xmlgetindex {\xmldocument}{#1}} +\def\xmlwithindex #1#2{\clf_xmlwithindex{\xmldocument}{#1}{#2}} \def\xmlreference #1#2{\string\xmlwithindex{#1}{#2}} %D Entities (might change): \setnewconstant\xmlautoentities\plusone % 0=off, 1=upper, 2=upper,lower -\def\xmlsetentity#1#2{\ctxlua{xml.registerentity('#1',\!!bs\detokenize{#2}\!!es)}} -\def\xmltexentity#1#2{\ctxlua{lxml.registerentity('#1',\!!bs\detokenize{#2}\!!es)}} +\def\xmlsetentity#1#2{\clf_xmlsetentity{#1}{\detokenize{#2}}} +\def\xmltexentity#1#2{\clf_xmltexentity{#1}{\detokenize{#2}}} % \xmlsetentity{tex}{\TEX{}} % {} needed diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv index 4ee7c6826..a194b7348 100644 --- a/tex/context/base/math-ini.mkiv +++ b/tex/context/base/math-ini.mkiv @@ -192,9 +192,9 @@ % these commands are semi-public but should not be used directly (lua names wil change) -\unexpanded\def\math_set_attribute #1#2{\ifmmode\ctxcommand{setmathattribute("#1","#2")}\fi} -\unexpanded\def\math_set_alphabet #1{\ifmmode\ctxcommand{setmathalphabet("#1")}\fi} -\unexpanded\def\math_set_font_style #1{\ifmmode\ctxcommand{setmathstyle("#1")}\fi} +\unexpanded\def\math_set_attribute #1#2{\ifmmode\clf_setmathattribute{#1}{#2}\fi} +\unexpanded\def\math_set_alphabet #1{\ifmmode\clf_setmathalphabet{#1}\fi} +\unexpanded\def\math_set_font_style #1{\ifmmode\clf_setmathstyle{#1}\fi} \unexpanded\def\math_set_font_alternate#1{\ifmmode\ctxcommand{setmathalternate(\number\defaultmathfamily,"#1")}\fi} \installcorenamespace{mathstylealternate} % might become a setuphandler @@ -218,13 +218,13 @@ \unexpanded\def\mathaltcal{\math_set_font_alternate{cal}\cal} % ss01 in xits -\let\setmathattribute \math_set_attribute -\let\setmathalphabet \math_set_alphabet -\let\setmathfontstyle \math_set_font_style -\let\setmathfontalternate \math_set_font_alternate +\let\setmathattribute \math_set_attribute +\let\setmathalphabet \math_set_alphabet +\let\setmathfontstyle \math_set_font_style +\let\setmathfontalternate \math_set_font_alternate \let\setmathfontstylealternate\math_set_font_style_alternate -\let\mathalternate \math_set_font_alternate % obsolete +\let\mathalternate \math_set_font_alternate % obsolete \unexpanded\def\mathupright {\math_set_attribute\s!regular\s!tf\math_set_font_style_alternate\s!tf} \unexpanded\def\mathdefault {\math_set_attribute\s!regular\s!it\math_set_font_style_alternate\s!it} diff --git a/tex/context/base/math-map.lua b/tex/context/base/math-map.lua index f3867876d..7b1ede666 100644 --- a/tex/context/base/math-map.lua +++ b/tex/context/base/math-map.lua @@ -53,6 +53,12 @@ local report_remapping = logs.reporter("mathematics","remapping") mathematics = mathematics or { } local mathematics = mathematics +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer + +local scanners = interfaces.scanners + -- Unfortunately some alphabets have gaps (thereby troubling all applications that -- need to deal with math). Somewhat strange considering all those weird symbols that -- were added afterwards. The following trickery (and data) is only to be used for @@ -617,6 +623,27 @@ function mathematics.syncname(alphabet) texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) end +scanners.setmathattribute = function() -- alphabet style + local data = alphabets[scanstring()] or regular + data = data[scanstring()] or data.tf + texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) +end + +scanners.setmathstyle = function() -- style + local r = mathremap[texgetattribute(mathalphabet)] + local alphabet = r and r.alphabet or "regular" + local data = alphabets[alphabet][scanstring()] + texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) +end + +scanners.setmathalphabet = function() -- alphabet + -- local r = mathremap[mathalphabet] + local r = mathremap[texgetattribute(mathalphabet)] + local style = r and r.style or "tf" + local data = alphabets[scanstring()][style] + texsetattribute(mathalphabet,data and data.attribute or texattribute[mathalphabet]) +end + local islcgreek = regular_tf.lcgreek local isucgreek = regular_tf.ucgreek local issygreek = regular_tf.symbols @@ -742,9 +769,3 @@ function mathematics.addfallbacks(main) checkedcopy(characters,regular.bi.ucgreek,regular.it.ucgreek) checkedcopy(characters,regular.bi.lcgreek,regular.it.lcgreek) end - --- interface - -commands.setmathattribute = mathematics.syncboth -commands.setmathalphabet = mathematics.syncname -commands.setmathstyle = mathematics.syncstyle diff --git a/tex/context/base/meta-ini.lua b/tex/context/base/meta-ini.lua index 713ba3d5d..8f7131263 100644 --- a/tex/context/base/meta-ini.lua +++ b/tex/context/base/meta-ini.lua @@ -15,34 +15,6 @@ local context = context metapost = metapost or { } --- for the moment downward compatible - -local report_metapost = logs.reporter ("metapost") -local status_metapost = logs.messenger("metapost") - -local patterns = { "meta-imp-%s.mkiv", "meta-imp-%s.tex", "meta-%s.mkiv", "meta-%s.tex" } -- we are compatible - -local function action(name,foundname) - status_metapost("library %a is loaded",name) - context.startreadingfile() - context.input(foundname) - context.stopreadingfile() -end - -local function failure(name) - report_metapost("library %a is unknown or invalid",name) -end - -function commands.useMPlibrary(name) - commands.uselibrary { - name = name, - patterns = patterns, - action = action, - failure = failure, - onlyonce = true, - } -end - -- experimental local colorhash = attributes.list[attributes.private('color')] diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index b6eab747d..3d70feb34 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -106,7 +106,7 @@ {\dosinglegroupempty\meta_start_extensions} \def\meta_start_extensions#1#2\stopMPextensions % we could use buffers instead - {\ctxlua{metapost.setextensions("#1",\!!bs#2\!!es)}} + {\clf_setmpextensions{#1}{#2}} \let\stopMPextensions\relax @@ -297,25 +297,46 @@ \edef\currentMPformat{\MPinstanceparameter\s!format}% \meta_process_graphic} +% \unexpanded\def\meta_process_graphic#1% todo: extensions and inclusions outside beginfig +% {\meta_start_current_graphic +% \forgetall +% \edef\p_extensions{\MPinstanceparameter\s!extensions}% +% \meta_process_graphic_start +% \normalexpanded{\noexpand\ctxlua{metapost.graphic { +% instance = "\currentMPinstance", +% format = "\currentMPformat", +% data = \!!bs#1;\!!es, +% initializations = \!!bs\meta_flush_current_initializations\!!es, +% % useextensions = "\MPinstanceparameter\s!extensions", +% \ifx\p_extensions\v!yes +% extensions = \!!bs\clf_getmpextensions{\currentMPinstance}\!!es, +% \fi +% inclusions = \!!bs\meta_flush_current_inclusions\!!es, +% definitions = \!!bs\meta_flush_current_definitions\!!es, +% figure = "\MPaskedfigure", +% method = "\MPinstanceparameter\c!method", +% }}}% +% \meta_process_graphic_stop +% \meta_stop_current_graphic} + \unexpanded\def\meta_process_graphic#1% todo: extensions and inclusions outside beginfig {\meta_start_current_graphic \forgetall \edef\p_extensions{\MPinstanceparameter\s!extensions}% \meta_process_graphic_start - \normalexpanded{\noexpand\ctxlua{metapost.graphic { - instance = "\currentMPinstance", - format = "\currentMPformat", - data = \!!bs#1;\!!es, - initializations = \!!bs\meta_flush_current_initializations\!!es, -% useextensions = "\MPinstanceparameter\s!extensions", -\ifx\p_extensions\v!yes - extensions = \!!bs\ctxcommand{getmpextensions("\currentMPinstance")}\!!es, -\fi - inclusions = \!!bs\meta_flush_current_inclusions\!!es, - definitions = \!!bs\meta_flush_current_definitions\!!es, - figure = "\MPaskedfigure", - method = "\MPinstanceparameter\c!method", - }}}% + \normalexpanded{\noexpand\clf_mpgraphic + instance {\currentMPinstance}% + format {\currentMPformat}% + data {#1;}% + initializations {\meta_flush_current_initializations}% + \ifx\p_extensions\v!yes + extensions {\clf_getmpextensions{\currentMPinstance}}% + \fi + inclusions {\meta_flush_current_inclusions}% + definitions {\meta_flush_current_definitions}% + figure {\MPaskedfigure}% + method {\MPinstanceparameter\c!method}% + \relax}% \meta_process_graphic_stop \meta_stop_current_graphic} @@ -439,17 +460,30 @@ \fi \endgroup} +% \def\meta_grab_clip_path_indeed +% {\meta_start_current_graphic +% \xdef\MPclippath{\normalexpanded{\noexpand\ctxlua{metapost.theclippath { +% instance = "\currentMPinstance", +% format = "\currentMPformat", +% data = \!!bs\csname\??mpclip\currentMPclip\endcsname\!!es, +% initializations = \!!bs\meta_flush_current_initializations\!!es, +% useextensions = "\MPinstanceparameter\s!extensions", +% inclusions = \!!bs\meta_flush_current_inclusions\!!es, +% method = "\MPinstanceparameter\c!method", +% }}}}% +% \meta_stop_current_graphic} + \def\meta_grab_clip_path_indeed {\meta_start_current_graphic - \xdef\MPclippath{\normalexpanded{\noexpand\ctxlua{metapost.theclippath { - instance = "\currentMPinstance", - format = "\currentMPformat", - data = \!!bs\csname\??mpclip\currentMPclip\endcsname\!!es, - initializations = \!!bs\meta_flush_current_initializations\!!es, - useextensions = "\MPinstanceparameter\s!extensions", - inclusions = \!!bs\meta_flush_current_inclusions\!!es, - method = "\MPinstanceparameter\c!method", - }}}}% + \normalexpanded{\noexpand\clf_mpsetclippath + instance {\currentMPinstance}% + format {\currentMPformat}% + data {\csname\??mpclip\currentMPclip\endcsname}% + initializations {\meta_flush_current_initializations}% + useextensions {\MPinstanceparameter\s!extensions}% + inclusions {\meta_flush_current_inclusions}% + method {\MPinstanceparameter\c!method}% + \relax}% \meta_stop_current_graphic} %D Since we want lables to follow the document settings, we @@ -459,7 +493,7 @@ {\dontleavehmode \begingroup \definedfont[#1]% - \hskip\cldcontext{fonts.hashes.parameters[font.current()].designsize}sp\relax + \hskip\cldcontext{fonts.hashes.parameters[font.current()].designsize}\scaledpoint\relax \endgroup} \definefontsynonym[MetafunDefault][Regular*default] @@ -909,7 +943,7 @@ \def\meta_process_buffer[#1]% {\meta_begin_graphic_group{#1}% - \meta_process_graphic{\ctxcommand{feedback("\currentMPgraphicname")}}% + \meta_process_graphic{\clf_feedback{\currentMPgraphicname}}% \meta_end_graphic_group} \unexpanded\def\runMPbuffer @@ -953,15 +987,15 @@ \else\ifx\m_meta_option\!!plustoken #2% % use in main doc too \fi\fi\fi - \ctxlua{metapost.tex.set(\!!bs\detokenize{#2}\!!es)}} + \clf_mptexset{\detokenize{#2}}} \let\stopMPenvironment\relax \unexpanded\def\resetMPenvironment - {\ctxlua{metapost.tex.reset()}} + {\clf_mptexreset} \unexpanded\def\useMPenvironmentbuffer[#1]% - {\ctxlua{metapost.tex.set(buffers.content("#1"))}} + {\clf_mpsetfrombuffer{#1}} %D This command takes \type {[reset]} as optional %D argument. @@ -1083,7 +1117,7 @@ %D Loading specific \METAPOST\ related definitions is %D accomplished by: -\unexpanded\def\useMPlibrary[#1]{\ctxcommand{useMPlibrary(\!!bs#1\!!es)}} +\unexpanded\def\useMPlibrary[#1]{\clf_useMPlibrary{#1}} %D \macros %D {setMPtext, MPtext, MPstring, MPbetex} @@ -1405,7 +1439,11 @@ \newconstant\MPcolormethod \appendtoks - \ctxlua{metapost.setoutercolor(\number\MPcolormethod,\number\attribute\colormodelattribute,\number\attribute\colorattribute,\number\dogetattribute{transparency})}% + \clf_mpsetoutercolor + \MPcolormethod\space + \attribute\colormodelattribute\space + \attribute\colorattribute\space + \dogetattribute{transparency}\relax \to \everyMPgraphic \startMPinitializations @@ -1436,9 +1474,9 @@ %D $(x,y) = (\MPrunset{point}{,})$ %D \stoptyping -\def\MPrunvar #1{\ctxcommand{mprunvar("#1")}} \let\mprunvar\MPrunvar -\def\MPruntab#1#2{\ctxcommand{mprunvar("#1",\number#2)}} \let\mpruntab\MPruntab -\def\MPrunset#1#2{\ctxcommand{mprunvar("#1","#2")}} \let\mprunset\MPrunset +\def\MPrunvar #1{\clf_mprunvar{#1}} \let\mprunvar\MPrunvar +\def\MPruntab#1#2{\clf_mpruntab{#1}#2\relax} \let\mpruntab\MPruntab % #2 is number +\def\MPrunset#1#2{\clf_mprunset{#1}{#2}} \let\mprunset\MPrunset %D We also provide an outputless run: diff --git a/tex/context/base/mlib-ctx.lua b/tex/context/base/mlib-ctx.lua index fe5218771..43c4b4c42 100644 --- a/tex/context/base/mlib-ctx.lua +++ b/tex/context/base/mlib-ctx.lua @@ -6,21 +6,33 @@ if not modules then modules = { } end modules ['mlib-ctx'] = { license = "see context related readme files", } --- todo +-- for the moment we have the scanners here but they migh tbe moved to +-- the other modules +local type, tostring = type, tostring local format, concat = string.format, table.concat local settings_to_hash = utilities.parsers.settings_to_hash local report_metapost = logs.reporter("metapost") -local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming -local mplib = mplib +local mplib = mplib -metapost = metapost or {} -local metapost = metapost +metapost = metapost or {} +local metapost = metapost -local v_no = interfaces.variables.no +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer +local setters = tokens.setters +local setmacro = setters.macro + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + +local v_no = interfaces.variables.no metapost.defaultformat = "metafun" metapost.defaultinstance = "metafun" @@ -78,13 +90,154 @@ function metapost.getextensions(instance,state) end end -function commands.getmpextensions(instance,state) - context(metapost.getextensions(instance,state)) +-- function commands.getmpextensions(instance,state) +-- context(metapost.getextensions(instance,state)) +-- end + +scanners.setmpextensions = compilescanner { + actions = metapost.setextensions, + arguments = { "string", "string" } +} + +scanners.getmpextensions = compilescanner { + actions = { metapost.getextensions, context } , + arguments = "string" +} + +local report_metapost = logs.reporter ("metapost") +local status_metapost = logs.messenger("metapost") + +local patterns = { "meta-imp-%s.mkiv", "meta-imp-%s.tex", "meta-%s.mkiv", "meta-%s.tex" } -- we are compatible + +local function action(name,foundname) + status_metapost("library %a is loaded",name) + context.startreadingfile() + context.input(foundname) + context.stopreadingfile() +end + +local function failure(name) + report_metapost("library %a is unknown or invalid",name) +end + +scanners.useMPlibrary = function() -- name + commands.uselibrary { + name = scanstring(), + patterns = patterns, + action = action, + failure = failure, + onlyonce = true, + } +end + +-- metapost.variables = { } -- to be stacked + +scanners.mprunvar = function() -- name + local value = metapost.variables[scanstring()] + if value ~= nil then + local tvalue = type(value) + if tvalue == "table" then + context(concat(value," ")) + elseif tvalue == "number" or tvalue == "boolean" then + context(tostring(value)) + elseif tvalue == "string" then + context(value) + end + end +end + +scanners.mpruntab = function() -- name n + local value = metapost.variables[scanstring()] + if value ~= nil then + local tvalue = type(value) + if tvalue == "table" then + context(value[scaninteger()]) + elseif tvalue == "number" or tvalue == "boolean" then + context(tostring(value)) + elseif tvalue == "string" then + context(value) + end + end end +scanners.mprunset = function() -- name connector + local value = metapost.variables[scanstring()] + if value ~= nil then + local tvalue = type(value) + if tvalue == "table" then + context(concat(value,scanstring())) + elseif tvalue == "number" or tvalue == "boolean" then + context(tostring(value)) + elseif tvalue == "string" then + context(value) + end + end +end + +-- we need to move more from pps to here as pps is the plugin .. the order is a mess +-- or just move the scanners to pps + function metapost.graphic(specification) - setmpsformat(specification) - metapost.graphic_base_pass(specification) + metapost.graphic_base_pass(setmpsformat(specification)) +end + +-- scanners.mpgraphic = compilescanner { +-- actions = { setmpsformat, metapost.graphic_base_pass }, -- not yet implemented +-- arguments = { +-- { +-- { "instance" }, +-- { "format" }, +-- { "data" }, +-- { "initializations" }, +-- { "extensions" }, +-- { "inclusions" }, +-- { "definitions" }, +-- { "figure" }, +-- { "method" }, +-- }, +-- } +-- } + +local get_mpgraphic_spec = compilescanner { + { + { "instance" }, + { "format" }, + { "data" }, + { "initializations" }, + { "extensions" }, + { "inclusions" }, + { "definitions" }, + { "figure" }, + { "method" }, + } +} + +scanners.mpgraphic = function() + metapost.graphic_base_pass(setmpsformat(get_mpgraphic_spec())) +end + +-- scanners.mpsetoutercolor = compilescanner { +-- action = metapost.setoutercolor, -- not yet implemented +-- arguments = { "integer", "integer", "integer", "integer" } +-- } + +scanners.mpsetoutercolor = function() + metapost.setoutercolor(scaninteger(),scaninteger(),scaninteger(),scaninteger()) +end + +-- scanners.mpflushreset = metapost.flushreset -- will become obsolete and internal + +scanners.mpflushreset = function() + metapost.flushreset() +end + +-- scanners.mpflushliteral = compilescanner { +-- action = metapost.flushliteral, -- not yet implemented +-- arguments = "string", +-- } + +scanners.mpflushliteral = function() + metapost.flushliteral(scanstring()) end function metapost.getclippath(specification) -- why not a special instance for this @@ -135,11 +288,29 @@ end function metapost.theclippath(...) local result = metapost.getclippath(...) if result then -- we could just print the table - result = concat(metapost.flushnormalpath(result),"\n") - context(result) +-- return concat(metapost.flushnormalpath(result),"\n") + return concat(metapost.flushnormalpath(result)," ") + else + return "" end end +local get_mpsetclippath_spec = compilescanner { + { + { "instance" }, + { "format" }, + { "data" }, + { "initializations" }, + { "useextensions" }, + { "inclusions" }, + { "method" }, + }, +} + +scanners.mpsetclippath = function() + setmacro("MPclippath",metapost.theclippath(get_mpsetclippath_spec()),"global") +end + statistics.register("metapost processing time", function() local n = metapost.n if n and n > 0 then @@ -165,17 +336,34 @@ end) -- only used in graphictexts metapost.tex = metapost.tex or { } +local mptex = metapost.tex local environments = { } -function metapost.tex.set(str) +function mptex.set(str) environments[#environments+1] = str end -function metapost.tex.reset() +function mptex.get() + return concat(environments,"\n") +end + +function mptex.reset() environments = { } end -function metapost.tex.get() - return concat(environments,"\n") +scanners.mptexset = function() + environments[#environments+1] = scanstring() +end + +scanners.mptexget = function() + context(concat(environments,"\n")) +end + +scanners.mptexsetfrombuffer = function() + environments[#environments+1] = buffers.content(scanstring()) +end + +scanners.mptexreset = function() + environments = { } end diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua index 11325b9fe..8de09f42a 100644 --- a/tex/context/base/mlib-pdf.lua +++ b/tex/context/base/mlib-pdf.lua @@ -30,6 +30,8 @@ local write_node = node.write local pen_info = mplib.pen_info local object_fields = mplib.fields +local save_table = false + metapost = metapost or { } local metapost = metapost @@ -56,6 +58,16 @@ local f_J = formatters["%i J"] local f_d = formatters["[%s] %F d"] local f_w = formatters["%F w"] +directives.register("metapost.savetable",function(v) + if type(v) == "string" then + save_table = file.addsuffix(v,"mpl") + elseif v then + save_table = file.addsuffix(environment.jobname .. "-graphic","mpl") + else + save_table = false + end +end) + local pdfliteral = function(pdfcode) local literal = copy_node(mpsliteral) literal.data = pdfcode @@ -74,7 +86,7 @@ local function getobjects(result,figure,index) robjects = { } result.objects = robjects end - local fobjects = robjects[index] + local fobjects = robjects[index or 1] if not fobjects then fobjects = figure:objects() robjects[index] = fobjects @@ -89,11 +101,17 @@ function metapost.convert(result, trialrun, flusher, multipass, askedfig) if trialrun then local multipassindeed = metapost.parse(result,askedfig) if multipass and not multipassindeed and metapost.optimize then + if save_table then + table.save(save_table,metapost.totable(result,1)) -- direct + end metapost.flush(result,flusher,askedfig) -- saves a run else return false end else + if save_table then + table.save(save_table,metapost.totable(result,1)) -- direct + end metapost.flush(result,flusher,askedfig) end return true -- done @@ -327,27 +345,6 @@ local pattern_lst = (variable * newline^0)^0 metapost.variables = { } -- to be stacked metapost.properties = { } -- to be stacked -function commands.mprunvar(key,n) -- should be defined in another lib - local value = metapost.variables[key] - if value ~= nil then - local tvalue = type(value) - if tvalue == "table" then - local ntype = type(n) - if ntype == "number" then - context(value[n]) - elseif ntype == "string" then - context(concat(value,n)) - else - context(concat(value," ")) - end - elseif tvalue == "number" or tvalue == "boolean" then - context(tostring(value)) - elseif tvalue == "string" then - context(value) - end - end -end - function metapost.untagvariable(str,variables) -- will be redone if variables == false then return lpegmatch(pattern_lst,str) @@ -632,13 +629,13 @@ function metapost.pdfliterals(result) return result end --- so far - -function metapost.totable(result) - local figure = result and result.fig and result.fig[1] +function metapost.totable(result,askedfig) + local askedfig = askedfig or 1 + local figure = result and result.fig and result.fig[1] if figure then local results = { } - local objects = figure:objects() + -- local objects = figure:objects() + local objects = getobjects(result,figure,askedfig) for o=1,#objects do local object = objects[o] local result = { } diff --git a/tex/context/base/mlib-pdf.mkiv b/tex/context/base/mlib-pdf.mkiv index 0913b3699..92bf86ea9 100644 --- a/tex/context/base/mlib-pdf.mkiv +++ b/tex/context/base/mlib-pdf.mkiv @@ -88,7 +88,7 @@ % MPLIB specific: -\def\MPLIBtoPDF#1{\ctxlua{metapost.flushliteral(#1)}} +\def\MPLIBtoPDF{\clf_mpflushliteral} \def\startMPLIBtoPDF#1#2#3#4% {\meta_process_graphic_figure_start @@ -109,7 +109,7 @@ \meta_process_graphic_figure_stop} \def\MPLIBflushreset % This can (will) move to the Lua end. - {\ctxlua{metapost.flushreset()}} + {\clf_mpflushreset} %D Kind of special: % @@ -134,27 +134,50 @@ \unexpanded\def\directMPgraphic {\dodoublegroupempty\mlib_direct_graphic} +% \def\mlib_direct_graphic#1#2% makes pages (todo: make boxes) +% {\meta_begin_graphic_group{#1}% +% \let\startMPLIBtoPDF\directstartMPLIBtoPDF +% \let\stopMPLIBtoPDF \directstopMPLIBtoPDF +% \meta_start_current_graphic +% \forgetall +% \edef\p_extensions{\MPinstanceparameter\s!extensions}% +% \normalexpanded{\noexpand\ctxlua{metapost.graphic { +% instance = "\currentMPinstance", +% format = "\currentMPformat", +% data = \!!bs#2;\!!es, +% initializations = \!!bs\meta_flush_current_initializations\!!es, +% % useextensions = "\MPinstanceparameter\s!extensions", +% \ifx\p_extensions\v!yes +% extensions = \!!bs\clf_getmpextensions{\currentMPinstance}\!!es, +% \fi +% inclusions = \!!bs\meta_flush_current_inclusions\!!es, +% definitions = \!!bs\meta_flush_current_definitions\!!es, +% figure = "all", +% method = "\MPinstanceparameter\c!method", +% }}}% +% \meta_stop_current_graphic +% \meta_end_graphic_group} + \def\mlib_direct_graphic#1#2% makes pages (todo: make boxes) {\meta_begin_graphic_group{#1}% \let\startMPLIBtoPDF\directstartMPLIBtoPDF \let\stopMPLIBtoPDF \directstopMPLIBtoPDF \meta_start_current_graphic - \forgetall - \edef\p_extensions{\MPinstanceparameter\s!extensions}% - \normalexpanded{\noexpand\ctxlua{metapost.graphic { - instance = "\currentMPinstance", - format = "\currentMPformat", - data = \!!bs#2;\!!es, - initializations = \!!bs\meta_flush_current_initializations\!!es, -% useextensions = "\MPinstanceparameter\s!extensions", -\ifx\p_extensions\v!yes - extensions = \!!bs\ctxcommand{getmpextensions("\currentMPinstance")}\!!es, -\fi - inclusions = \!!bs\meta_flush_current_inclusions\!!es, - definitions = \!!bs\meta_flush_current_definitions\!!es, - figure = "all", - method = "\MPinstanceparameter\c!method", - }}}% + \forgetall + \edef\p_extensions{\MPinstanceparameter\s!extensions}% + \normalexpanded{\noexpand\clf_mpgraphic + instance {\currentMPinstance}% + format {\currentMPformat}% + data {#2;}% + initializations {\meta_flush_current_initializations}% + \ifx\p_extensions\v!yes + extensions {\clf_getmpextensions{\currentMPinstance}}% + \fi + inclusions {\meta_flush_current_inclusions}% + definitions {\meta_flush_current_definitions}% + figure {all}% + method {\MPinstanceparameter\c!method}% + \relax}% \meta_stop_current_graphic \meta_end_graphic_group} diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua index c144a2501..d21ff3a76 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -19,6 +19,16 @@ local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context local context = context local context_setvalue = context.setvalue +local scanners = tokens.scanners +local scanstring = scanners.string +local scaninteger = scanners.integer +local scandimen = scanners.dimen +local setters = tokens.setters +local setmacro = setters.macro + +local compilescanner = tokens.compile +local scanners = interfaces.scanners + local texgetbox = tex.getbox local texsetbox = tex.setbox local textakebox = tex.takebox @@ -269,7 +279,7 @@ end -- end of new -function metapost.settext(box,slot) +local function settext(box,slot) if top then top.textexts[slot] = copy_list(texgetbox(box)) texsetbox(box,nil) @@ -280,7 +290,7 @@ function metapost.settext(box,slot) end end -function metapost.gettext(box,slot) +local function gettext(box,slot) if top then texsetbox(box,copy_list(top.textexts[slot])) if trace_textexts then @@ -292,6 +302,12 @@ function metapost.gettext(box,slot) end end +metapost.settext = settext +metapost.gettext = gettext + +scanners.mpsettext = compilescanner { actions = settext, arguments = { "integer", "integer" } } -- box slot +scanners.mpgettext = compilescanner { actions = gettext, arguments = { "integer", "integer" } } -- box slot + -- rather generic pdf, so use this elsewhere too it no longer pays -- off to distinguish between outline and fill (we now have both -- too, e.g. in arrows) @@ -481,7 +497,7 @@ end -- currently a a one-liner produces less code -- textext.*(".*") can have "'s but tricky parsing as we can have concatenated strings --- so this is something for a boring plain or train trip and we might assume proper mp +-- so this is something for a boring plane or train trip and we might assume proper mp -- input anyway local parser = Cs(( @@ -491,9 +507,15 @@ local parser = Cs(( + 1 )^0) +local checking_enabled = true directives.register("metapost.checktexts",function(v) checking_enabled = v end) + local function checktexts(str) - found, forced = false, false - return lpegmatch(parser,str), found, forced + if checking_enabled then + found, forced = false, false + return lpegmatch(parser,str), found, forced + else + return str + end end metapost.checktexts = checktexts @@ -506,6 +528,13 @@ function metapost.edefsxsy(wd,ht,dp) -- helper for figure context_setvalue("sy",hd ~= 0 and factor/hd or 0) end +scanners.mpsetsxsy = function() -- wd ht dp + local wd = scandimen() + local hd = scandimen() + scandimen() + setmacro("sx",wd ~= 0 and factor/wd or 0) + setmacro("sy",hd ~= 0 and factor/hd or 0) +end + local function sxsy(wd,ht,dp) -- helper for text local hd = ht + dp return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0 @@ -608,17 +637,18 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib top.nofruns = nofruns -- local done_1, done_2, done_3, forced_1, forced_2, forced_3 - data, done_1, forced_1 = checktexts(data) - -- we had preamble = extensions + inclusions - if extensions == "" then - extensions, done_2, forced_2 = "", false, false - else - extensions, done_2, forced_2 = checktexts(extensions) - end - if inclusions == "" then - inclusions, done_3, forced_3 = "", false, false - else - inclusions, done_3, forced_3 = checktexts(inclusions) + if checking_enabled then + data, done_1, forced_1 = checktexts(data) + if extensions == "" then + extensions, done_2, forced_2 = "", false, false + else + extensions, done_2, forced_2 = checktexts(extensions) + end + if inclusions == "" then + inclusions, done_3, forced_3 = "", false, false + else + inclusions, done_3, forced_3 = checktexts(inclusions) + end end top.intermediate = false top.multipass = false -- no needed here diff --git a/tex/context/base/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv index e38799dba..07ac84b8d 100644 --- a/tex/context/base/mlib-pps.mkiv +++ b/tex/context/base/mlib-pps.mkiv @@ -35,21 +35,21 @@ \def\doMPLIBflushenvironment {%\writestatus\m!metapost{flushing environment}% - \cldcontext{metapost.tex.get()}% + \clf_mptexget \let\MPLIBflushenvironment\relax}% MPenvironments are depricated} \let\MPLIBflushenvironment\doMPLIBflushenvironment \unexpanded\def\MPLIBsetNtext#1% #2% box text {\MPLIBflushenvironment - \dowithnextbox{\ctxlua{metapost.settext(\number\nextbox,#1)}}\hbox\bgroup + \dowithnextbox{\clf_mpsettext\nextbox #1}\hbox\bgroup \meta_set_current_color \let\MPLIBflushenvironment\doMPLIBflushenvironment \let\next} % gobble open brace \unexpanded\def\MPLIBsetCtext#1#2% #3% box colorspec text {\MPLIBflushenvironment - \dowithnextbox{\ctxlua{metapost.settext(\number\nextbox,#1)}}\hbox\bgroup + \dowithnextbox{\clf_mpsettext\nextbox #1}\hbox\bgroup \directcolored[#2]% \meta_set_current_color % so, textcolor wins ! \let\MPLIBflushenvironment\doMPLIBflushenvironment @@ -58,18 +58,18 @@ \let\MPLIBsettext\MPLIBsetNtext \unexpanded\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often - {\ctxlua{metapost.gettext(\number\MPtextbox,#1)}% + {\clf_mpgettext\MPtextbox #1% \vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}} \unexpanded\def\MPLIBfigure#1#2% {\setbox\scratchbox\hbox{\externalfigure[#1][\c!mask=#2]}% - \ctxlua{metapost.edefsxsy(\number\wd\scratchbox,\number\ht\scratchbox,0)}% + \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint \vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}} % horrible (we could inline scale and matrix code): \unexpanded\def\MPLIBgettextscaledcm#1#2#3#4#5#6#7#8#9% 2-7: sx,rx,ry,sy,tx,ty - {\ctxlua{metapost.gettext(\number\MPtextbox,#1)}% + {\clf_mpgettext\MPtextbox #1% \setbox\MPbox\hbox\bgroup \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop ... will be changed to proper lua call (avoid small numbers) \vbox to \zeropoint\bgroup diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index 62e983abc..9baf6574e 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -12,6 +12,7 @@ local serialize = table.serialize local context = context local commands = commands +local implement = interfaces.implement local allocate = utilities.storage.allocate local mark = utilities.storage.mark @@ -282,30 +283,37 @@ end -- interface -function commands.writestatus(category,message,...) - local r = reporters[category] - if r then - r(message,...) - end +function interfaces.writestatus(category,message) + reporters[category](message) -- could also be a setmetatablecall end -commands.registernamespace = interfaces.registernamespace -commands.setinterfaceconstant = interfaces.setconstant -commands.setinterfacevariable = interfaces.setvariable -commands.setinterfaceelement = interfaces.setelement -commands.setinterfacemessage = interfaces.setmessage -commands.setinterfacemessages = interfaces.setmessages -commands.showmessage = interfaces.showmessage +implement { name = "registernamespace", actions = interfaces.registernamespace, arguments = { "string", "string" } } +implement { name = "setinterfaceconstant", actions = interfaces.setconstant, arguments = { "string", "string" } } +implement { name = "setinterfacevariable", actions = interfaces.setvariable, arguments = { "string", "string" } } +implement { name = "setinterfaceelement", actions = interfaces.setelement, arguments = { "string", "string" } } +implement { name = "setinterfacemessage", actions = interfaces.setmessage, arguments = { "string", "string", "string" } } +implement { name = "setinterfacemessages", actions = interfaces.setmessages, arguments = { "string", "string" } } +implement { name = "showmessage", actions = interfaces.showmessage, arguments = { "string", "string", "string" } } + +implement { + name = "doifelsemessage", + actions = { interfaces.doifelsemessage, commands.doifelse }, + arguments = { "string", "string" }, +} -function commands.doifelsemessage(category,tag) - commands.doifelse(interfaces.doifelsemessage(category,tag)) -end +implement { + name = "getmessage", + actions = { interfaces.getmessage, context }, + arguments = { "string", "string", "string" }, +} -function commands.getmessage(category,tag,default) - context(interfaces.getmessage(category,tag,default)) -end +implement { + name = "writestatus", + actions = interfaces.writestatus, + arguments = { "string", "string" }, +} -function commands.showassignerror(namespace,key,line) +local function showassignerror(namespace,key,line) local ns, instance = match(namespace,"^(%d+)[^%a]+(%a*)") if ns then namespace = corenamespaces[tonumber(ns)] or ns @@ -317,6 +325,12 @@ function commands.showassignerror(namespace,key,line) end end +implement { + name = "showassignerror", + actions = showassignerror, + arguments = { "string", "string", "integer" }, +} + -- a simple helper local settings_to_hash = utilities.parsers.settings_to_hash diff --git a/tex/context/base/mult-ini.mkiv b/tex/context/base/mult-ini.mkiv index 09fc5daf0..319a8fe03 100644 --- a/tex/context/base/mult-ini.mkiv +++ b/tex/context/base/mult-ini.mkiv @@ -368,7 +368,7 @@ \doifinsetelse{#1}{\currentresponses,all}\mult_messages_start_yes\mult_messages_start_nop{#2}} \def\mult_messages_start_yes#1#2\stopmessages - {\ctxcommand{setinterfacemessages("#1",\!!bs#2\!!es)}% + {\clf_setinterfacemessages{#1}{#2}% \egroup} \def\mult_messages_start_nop#1#2\stopmessages @@ -378,13 +378,13 @@ \unexpanded\def\setinterfacemessage#1#2#3% {\ifcsname\m!prefix!#1\endcsname\else\setgvalue{\m!prefix!#1}{#1}\fi - \ctxcommand{setinterfacemessage("#1","#2",\!!bs#3\!!es)}} + \clf_setinterfacemessage{#1}{#2}{#3}} -\unexpanded\def\setmessagetext #1#2{\edef\currentmessagetext{\ctxcommand{getmessage("#1","#2")}}} -\unexpanded\def\getmessage #1#2{\ctxcommand{getmessage("#1","#2")}} -\unexpanded\def\doifelsemessage #1#2{\ctxcommand{doifelsemessage("#1","#2")}} -\unexpanded\def\showmessage #1#2#3{\ctxcommand{showmessage("#1","#2",\!!bs#3\!!es)}} -\unexpanded\def\writestatus #1#2{\ctxcommand{writestatus("#1",\!!bs#2\!!es)}} +\unexpanded\def\setmessagetext #1#2{\edef\currentmessagetext{\clf_getmessage{#1}{#2}}} +\unexpanded\def\getmessage #1#2{\clf_getmessage{#1}{#2}} +\unexpanded\def\doifelsemessage #1#2{\clf_doifelsemessage{#1}{#2}} +\unexpanded\def\showmessage #1#2#3{\clf_showmessage{#1}{#2}{#3}} +\unexpanded\def\writestatus #1#2{\clf_writestatus{#1}{#2}} %D \macros %D {ifshowwarnings, ifshowmessages} @@ -730,11 +730,11 @@ % temporary mkiv hack (we can best just store the whole table in memory) \unexpanded\def\setinterfaceconstant#1#2% - {\ctxcommand{setinterfaceconstant("#1","#2")}% + {\clf_setinterfaceconstant{#1}{#2}% \expandafter\def\csname\c!prefix!#1\endcsname{#1}} \unexpanded\def\setinterfacevariable#1#2% - {\ctxcommand{setinterfacevariable("#1","#2")}% + {\clf_setinterfacevariable{#1}{#2}% \expandafter\def\csname\v!prefix!#1\endcsname{#2}} %D \macros @@ -763,7 +763,7 @@ %D part is needed, we use a \type{-}: \unexpanded\def\setinterfaceelement#1#2% - {\ctxcommand{setinterfaceelement("#1","#2")}% + {\clf_setinterfaceelement{#1}{#2}% \ifcsname\e!prefix!#1\endcsname \doifnotvalue{\e!prefix!#1}{#2}{\setvalue{\e!prefix!#1}{#2}}% \else diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 8aa7a5b18..e1618d1f7 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -514,10 +514,6 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in elseif nslistwise then local a = getattr(current,attribute) if a and attrib ~= a and nslistwise[a] then -- viewerlayer --- if not stacked then --- stacked = true --- nsbegin() --- end head = insert_node_before(head,current,copied(nsdata[a])) local list = stacker(namespace,attribute,content,a) setfield(current,"list",list) @@ -540,10 +536,10 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in if check then local a = getattr(current,attribute) or unsetvalue if a ~= attrib then -if not stacked then - stacked = true - nsbegin() -end + if not stacked then + stacked = true + nsbegin() + end local n = nsstep(a) if n then head = insert_node_before(head,current,tonut(n)) -- a diff --git a/tex/context/base/node-fin.mkiv b/tex/context/base/node-fin.mkiv index 2eb033fc1..8c0189094 100644 --- a/tex/context/base/node-fin.mkiv +++ b/tex/context/base/node-fin.mkiv @@ -23,12 +23,12 @@ % we might have two variants at some point (efficiency) -\unexpanded\def\finalizeobjectbox #1{\ctxcommand{finalizebox(\number#1)}} -\unexpanded\def\finalizeshipoutbox#1{\ctxcommand{finalizebox(\number#1)}} +\unexpanded\def\finalizeobjectbox #1{\clf_finalizebox#1\relax} +\unexpanded\def\finalizeshipoutbox#1{\clf_finalizebox#1\relax} % Experimental (for Aditya): -\unexpanded\def\cleanupbox#1{\ctxcommand{cleanupbox(\number#1)}} +\unexpanded\def\cleanupbox#1{\clf_cleanupbox#1\relax} % Tricky stuff: this might become obsolete. diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua index a4fb5689d..42cc83b8f 100644 --- a/tex/context/base/node-shp.lua +++ b/tex/context/base/node-shp.lua @@ -32,6 +32,8 @@ local fulldisc_code = disccodes.discretionary local texgetbox = tex.getbox +local implement = interfaces.implement + local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode @@ -159,17 +161,12 @@ function handlers.finalize(head) -- problem, attr loaded before node, todo ... return actions(head) end -function commands.cleanupbox(n) - cleanup_flushed(texgetbox(n)) -end - -- handlers.finalize = actions -- interface -function commands.finalizebox(n) - actions(texgetbox(n)) -end +implement { name = "cleanupbox", actions = { texgetbox, cleanup_flushed }, arguments = "integer" } +implement { name = "finalizebox", actions = { texgetbox, actions }, arguments = "integer" } -- just in case we want to optimize lookups: diff --git a/tex/context/base/pack-obj.lua b/tex/context/base/pack-obj.lua index 70876a346..dc6a8d0df 100644 --- a/tex/context/base/pack-obj.lua +++ b/tex/context/base/pack-obj.lua @@ -11,19 +11,23 @@ if not modules then modules = { } end modules ['pack-obj'] = { reusable components.

--ldx]]-- -local commands, context = commands, context +local context = context +local commands = commands -local allocate = utilities.storage.allocate +local compilescanner = tokens.compile +local scanners = interfaces.scanners -local collected = allocate() -local tobesaved = allocate() +local allocate = utilities.storage.allocate -local jobobjects = { +local collected = allocate() +local tobesaved = allocate() + +local jobobjects = { collected = collected, tobesaved = tobesaved, } -job.objects = jobobjects +job.objects = jobobjects local function initializer() collected = jobobjects.collected @@ -32,45 +36,72 @@ end job.register('job.objects.collected', tobesaved, initializer, nil) -function jobobjects.save(tag,number,page) +local function saveobject(tag,number,page) local t = { number, page } tobesaved[tag], collected[tag] = t, t end -function jobobjects.set(tag,number,page) +local function setobject(tag,number,page) collected[tag] = { number, page } end -function jobobjects.get(tag) +local function getobject(tag) return collected[tag] or tobesaved[tag] end -function jobobjects.number(tag,default) +local function getobjectnumber(tag,default) local o = collected[tag] or tobesaved[tag] return o and o[1] or default end -function jobobjects.page(tag,default) +local function getobjectpage(tag,default) local o = collected[tag] or tobesaved[tag] return o and o[2] or default end +jobobjects.save = saveobject +jobobjects.set = setobject +jobobjects.get = getobject +jobobjects.number = getobjectnumber +jobobjects.page = getobjectpage + -- interface -commands.saveobject = jobobjects.save -commands.setobject = jobobjects.set +commands.saveobject = saveobject +commands.setobject = setobject function commands.objectnumber(tag,default) - local o = collected[tag] or tobesaved[tag] - context(o and o[1] or default) + context(getobjectnumber(tag,default)) end function commands.objectpage(tag,default) - local o = collected[tag] or tobesaved[tag] - context(o and o[2] or default) + context(getobjectpage (tag,default)) end function commands.doifobjectreferencefoundelse(tag) - commands.doifelse(collected[tag] or tobesaved[tag]) + commands.doifelse(getobject(tag)) end +-- new + +scanners.saveobject = saveobject + +scanners.setobject = compilescanner { + actions = setobject, + arguments = { "string", "integer", "integer" } +} + +scanners.objectnumber = compilescanner { + actions = { getobjectnumber, context }, + arguments = { "string", "string" }, +} + +scanners.objectpage = compilescanner { + actions = { getobjectpage, context }, + arguments = { "string", "string" }, +} + +scanners.doifobjectreferencefoundelse = compilescanner { + actions = { jobobjects.get, commands.doifelse }, + arguments = "string" +} diff --git a/tex/context/base/pack-obj.mkiv b/tex/context/base/pack-obj.mkiv index 356a0b7eb..180ed83b2 100644 --- a/tex/context/base/pack-obj.mkiv +++ b/tex/context/base/pack-obj.mkiv @@ -366,7 +366,7 @@ % no undefined test ! ! ! ! (pdftex fails on undefined objects) \unexpanded\def\pack_objects_register_reference#1#2#3{\normalexpanded{\noexpand\ctxlatecommand{saveobject("#1::#2",#3,\noexpand\the\realpageno)}}} -\unexpanded\def\pack_objects_overload_reference#1#2#3{\ctxcommand{setobject("#1::#2",#3,\the\realpageno)}} +\unexpanded\def\pack_objects_overload_reference#1#2#3{\clf_setobject{#1::#2}#3 \realpageno\relax} \unexpanded\def\dosetobjectreference {\ifcase\crossreferenceobject @@ -382,8 +382,8 @@ \def\defaultobjectreference#1#2{0} % driver dependent \def\defaultobjectpage #1#2{\realfolio} -\unexpanded\def\dogetobjectreference #1#2#3{\xdef#3{\ctxcommand{objectnumber("#1::#2","\defaultobjectreference{#1}{#2}")}}} -\unexpanded\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxcommand{objectpage("#1::#2","\defaultobjectpage{#1}{#2}")}}} +\unexpanded\def\dogetobjectreference #1#2#3{\xdef#3{\clf_objectnumber{#1::#2}{\defaultobjectreference{#1}{#2}}}} +\unexpanded\def\dogetobjectreferencepage#1#2#3{\xdef#3{\clf_objectpage {#1::#2}{\defaultobjectpage {#1}{#2}}}} \unexpanded\def\setobject {\driverreferenced\pack_objects_set1} \unexpanded\def\settightobject{\driverreferenced\pack_objects_set0} @@ -407,6 +407,6 @@ \fi} \unexpanded\def\doifobjectreferencefoundelse#1#2% - {\ctxcommand{doifobjectreferencefoundelse("#1::#2")}} + {\clf_doifobjectreferencefoundelse{#1::#2}} \protect \endinput diff --git a/tex/context/base/publ-aut.lua b/tex/context/base/publ-aut.lua index f91ba0039..820ac78ff 100644 --- a/tex/context/base/publ-aut.lua +++ b/tex/context/base/publ-aut.lua @@ -22,7 +22,11 @@ local P, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lp local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local context = context -local commands = commands +----- commands = commands + +local implement = interfaces.implement +local ctx_setmacro = interfaces.setmacro + local publications = publications local datasets = publications.datasets @@ -284,7 +288,6 @@ local function the_initials(initials,symbol,connector) end local ctx_btxsetconcat = context.btxsetconcat -local ctx_btxsetauthorindex = context.btxsetauthorindex local ctx_btxsetoverflow = context.btxsetoverflow local ctx_btxsetinitials = context.btxsetinitials local ctx_btxsetfirstnames = context.btxsetfirstnames @@ -320,13 +323,13 @@ local function value(i,field) end end -function commands.btx_a_i(i) local v = value(i,"initials") if v then context(concat(the_initials(v,currentauthorsymbol))) end end -function commands.btx_a_f(i) local v = value(i,"firstnames") if v then context(concat(v," ")) end end -function commands.btx_a_j(i) local v = value(i,"juniors") if v then context(concat(v," ")) end end -function commands.btx_a_s(i) local v = value(i,"surnames") if v then context(concat(v," ")) end end -function commands.btx_a_v(i) local v = value(i,"vons") if v then context(concat(v," ")) end end +implement { name = "btxcurrentfirstnames", arguments = "integer", actions = function(i) local v = value(i,"initials") if v then context(concat(the_initials(v,currentauthorsymbol))) end end } +implement { name = "btxcurrentinitials", arguments = "integer", actions = function(i) local v = value(i,"firstnames") if v then context(concat(v," ")) end end } +implement { name = "btxcurrentjuniors", arguments = "integer", actions = function(i) local v = value(i,"juniors") if v then context(concat(v," ")) end end } +implement { name = "btxcurrentsurnames", arguments = "integer", actions = function(i) local v = value(i,"surnames") if v then context(concat(v," ")) end end } +implement { name = "btxcurrentvons", arguments = "integer", actions = function(i) local v = value(i,"vons") if v then context(concat(v," ")) end end } -function commands.btxauthorfield(i,field) +local function btxauthorfield(i,field) if currentauthordata then local entry = currentauthordata[i] if entry then @@ -337,7 +340,7 @@ function commands.btxauthorfield(i,field) elseif manipulator then for i=1,#value do if i > 1 then - context(" ") -- symbol ? + context(" ") end context(applymanipulation(manipulator,value) or value) end @@ -346,7 +349,7 @@ function commands.btxauthorfield(i,field) else context(concat(value," ")) end - end + end end end @@ -355,7 +358,7 @@ end -- in. Also, authors can be combined with years and so and they -- might be called upon mixed with other calls. -function commands.btxauthor(dataset,tag,field,settings) +local function btxauthor(dataset,tag,field,settings) local split, usedfield, kind = getcasted(dataset,tag,field) if kind == "author" then local max = split and #split or 0 @@ -432,6 +435,29 @@ function commands.btxauthor(dataset,tag,field,settings) end end +implement { + name = "btxauthorfield", + actions = btxauthorfield, + arguments = { "integer", "string" } +} + +implement { + name = "btxauthor", + actions = btxauthor, + arguments = { + "string", + "string", + "string", + { + { "combiner" }, + { "kind" }, + { "etallimit" }, + { "etaldisplay" }, + { "symbol" }, + } + } +} + local function components(snippet,short) local vons = snippet.vons local surnames = snippet.surnames diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua index 9be765985..68e2c5a0c 100644 --- a/tex/context/base/publ-dat.lua +++ b/tex/context/base/publ-dat.lua @@ -52,6 +52,9 @@ local report_duplicates = logs.reporter("publications","duplicates") local allocate = utilities.storage.allocate +local commands = commands +local implement = interfaces.implement + publications = publications or { } local publications = publications @@ -1105,7 +1108,16 @@ do return dataset end - commands.btxsavedataset = publications.save + implement { + name = "btxsavedataset", + actions = publications.save, + arguments = { + { "dataset" }, + { "filename" }, + { "filetype" }, + { "criterium" }, + } + } end diff --git a/tex/context/base/publ-imp-apa.mkvi b/tex/context/base/publ-imp-apa.mkvi index 87a9c522b..84d263e5c 100644 --- a/tex/context/base/publ-imp-apa.mkvi +++ b/tex/context/base/publ-imp-apa.mkvi @@ -743,7 +743,7 @@ } \stoptexdefinition -\starttexdefinition btx:apa:suffixedyear +\starttexdefinition nospaces btx:apa:suffixedyear \btxdoifelse {year} { \btxflush{year} \btxflush{suffix} diff --git a/tex/context/base/publ-imp-default.mkvi b/tex/context/base/publ-imp-default.mkvi index c6657ffa9..8e7b151c7 100644 --- a/tex/context/base/publ-imp-default.mkvi +++ b/tex/context/base/publ-imp-default.mkvi @@ -565,7 +565,7 @@ \fastsetup{\s!btx:\s!cite:url} \stopsetups \startsetups \s!btx:\s!default:\s!cite:nocite - \fastsetup{\s!btx:\s!cite:nocite} + \fastsetup{\s!btx:\s!cite:nocite}% defined nowhere : \stopsetups \startsetups \s!btx:\s!default:\s!cite:entry @@ -575,10 +575,6 @@ \fastsetup{\s!btx:\s!cite:none} \stopsetups -\startsetups \s!btx:\s!default:\s!cite:nocite - \fastsetup{\s!btx:\s!cite:nocite} -\stopsetups - \startsetups \s!btx:\s!default:\s!list:page \fastsetup{\s!btx:\s!list:page} \stopsetups diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua index 789b772fe..42d4c4251 100644 --- a/tex/context/base/publ-ini.lua +++ b/tex/context/base/publ-ini.lua @@ -95,16 +95,12 @@ manipulatormethods.WORDS = converters.WORDS local context = context local commands = commands +local implement = interfaces.implement +local ctx_setmacro = interfaces.setmacro local ctx_doifelse = commands.doifelse local ctx_doif = commands.doif local ctx_doifnot = commands.doifnot - -local ctx_firstoftwoarguments = context.firstoftwoarguments -local ctx_secondoftwoarguments = context.secondoftwoarguments -local ctx_firstofoneargument = context.firstofoneargument - -local ctx_gobbleoneargument = context.gobbleoneargument local ctx_gobbletwoarguments = context.gobbletwoarguments local ctx_btxdirectlink = context.btxdirectlink @@ -112,8 +108,6 @@ local ctx_btxhandlelistentry = context.btxhandlelistentry local ctx_btxhandlelisttextentry = context.btxhandlelisttextentry local ctx_btxchecklistentry = context.btxchecklistentry local ctx_btxchecklistcombi = context.btxchecklistcombi ------ ctx_btxsetcitereference = context.btxsetcitereference ------ ctx_btxsetlistreference = context.btxsetlistreference local ctx_btxsetdataset = context.btxsetdataset local ctx_btxsettag = context.btxsettag @@ -154,9 +148,6 @@ local ctx_btxsetnoflistentries = context.btxsetnoflistentries local ctx_btxsetcurrentlistentry = context.btxsetcurrentlistentry local ctx_btxsetcurrentlistindex = context.btxsetcurrentlistindex -local implement = interfaces.implement -local ctx_setmacro = interfaces.setmacro - languages.data = languages.data or { } local data = languages.data @@ -174,7 +165,12 @@ local function setspecification(name) end publications.setspecification = setspecification -commands.setbtxspecification = setspecification + +implement { + name = "btxsetspecification", + actions = setspecification, + arguments = "string", +} local optionalspace = lpeg.patterns.whitespace^0 local prefixsplitter = optionalspace * lpeg.splitat(optionalspace * P("::") * optionalspace) @@ -638,7 +634,7 @@ local function flushmarked(dataset,list,todo) marked_list = list end -function commands.flushmarked() +local function btxflushmarked() if marked_list and tobemarked then for i=1,#marked_list do -- keep order @@ -658,6 +654,8 @@ function commands.flushmarked() marked_list = nil end +implement { name = "btxflushmarked", actions = btxflushmarked } + -- basic access local function getfield(dataset,tag,name) -- for the moment quick and dirty @@ -860,17 +858,16 @@ function nofmultiple.author(d) return type(d) == "table" and #d or 0 end -function commands.btxsingularorplural(dataset,tag,name) +function publications.singularorplural(dataset,tag,name) local data, field, kind = getcasted(dataset,tag,name) if data then local test = nofmultiple[kind] if test then local n = test(data) - ctx_doifelse(not n or n < 2) - return + return not n or n < 2 end end - ctx_doifelse(true) + return true end function firstandlast.range(d) @@ -881,52 +878,89 @@ end firstandlast.pagenumber = firstandlast.range -function commands.btxoneorrange(dataset,tag,name) +function publications.oneorrange(dataset,tag,name) local data, field, kind = getcasted(dataset,tag,name) if data then local test = firstandlast[kind] if test then local first, last = test(data) - ctx_doifelse(not (first and last)) - return + return not (first and last) end end - ctx_gobbletwoarguments() + return nil -- nothing at all end -function commands.btxfirstofrange(dataset,tag,name) +function publications.firstofrange(dataset,tag,name) local data, field, kind = getcasted(dataset,tag,name) if data then local test = firstandlast[kind] if test then local first = test(data) if first then - context(first) + return first end end end end -function commands.lastofrange(dataset,tag,name) +function publications.lastofrange(dataset,tag,name) local data, field, kind = getcasted(dataset,tag,name) if data then local test = firstandlast[kind] if test then local first, last = test(data) if last then - context(last) + return last end end end end +local three_strings = { "string", "string", "string" } + +implement { + name = "btxsingularorplural", + actions = { publications.singularorplural, ctx_doifelse }, + arguments = three_strings +} + +implement { + name = "btxoneorrange", + actions = { publications.oneorrange, function(b) if b == nil then ctx_gobbletwoarguments() else ctx_doifelse(b) end end }, + arguments = three_strings +} + +implement { + name = "btxfirstofrange", + actions = { publications.firstofrange, context }, + arguments = three_strings +} + +implement { + name = "btxlastofrange", + actions = { publications.lastofrange, context }, + arguments = three_strings +} + -- basic loading -function commands.usebtxdataset(specification) +function publications.usedataset(specification) specification.kind = "current" publications.load(specification) end +implement { + name = "btxusedataset", + actions = publications.usedataset, + arguments = { + { + { "specification" }, + { "dataset" }, + { "filename" }, + } + } +} + function commands.convertbtxdatasettoxml(name,nice) publications.converttoxml(name,nice) end @@ -1065,37 +1099,51 @@ do end -function commands.addbtxentry(name,settings,content) - local dataset = datasets[name] - if dataset then - publications.addtexentry(dataset,settings,content) - end -end +implement { + name = "btxaddentry", + actions = function(name,settings,content) + local dataset = datasets[name] + if dataset then + publications.addtexentry(dataset,settings,content) + end + end, + arguments = { "string", "string", "string" } +} -function commands.setbtxdataset(name,default) +function publications.checkeddataset(name,default) local dataset = rawget(datasets,name) if dataset then - context(name) + return name elseif default and default ~= "" then - context(default) + return default else - context(v_default) report("unknown dataset %a, forcing %a",name,v_default) + return v_default end end -function commands.setbtxentry(name,tag) - local dataset = rawget(datasets,name) - if dataset then - if dataset.luadata[tag] then - context(tag) +implement { + name = "btxsetdataset", + actions = { publications.checkeddataset, context }, + arguments = { "string", "string"} +} + +implement { + name = "btxsetentry", + actions = function(name,tag) + local dataset = rawget(datasets,name) + if dataset then + if dataset.luadata[tag] then + context(tag) + else + report("unknown tag %a in dataset %a",tag,name) + end else - report("unknown tag %a in dataset %a",tag,name) + report("unknown dataset %a",name) end - else - report("unknown dataset %a",name) - end -end + end, + arguments = { "string", "string" }, +} -- rendering of fields @@ -1374,41 +1422,19 @@ do publications.okay = okay - if implement then - - implement { name = "btxfield", actions = btxfield, arguments = { "string", "string", "string" } } - implement { name = "btxdetail", actions = btxdetail, arguments = { "string", "string", "string" } } - implement { name = "btxflush", actions = btxflush, arguments = { "string", "string", "string" } } - implement { name = "btxdirect", actions = btxdirect, arguments = { "string", "string", "string" } } - - implement { name = "btxfieldname", actions = { get, context }, arguments = { "string", "string", "string", false, false } } - implement { name = "btxfieldtype", actions = { get, context }, arguments = { "string", "string", "string", true, false } } - implement { name = "btxfoundname", actions = { get, context }, arguments = { "string", "string", "string", false, true } } - implement { name = "btxfoundtype", actions = { get, context }, arguments = { "string", "string", "string", true, true } } + implement { name = "btxfield", actions = btxfield, arguments = { "string", "string", "string" } } + implement { name = "btxdetail", actions = btxdetail, arguments = { "string", "string", "string" } } + implement { name = "btxflush", actions = btxflush, arguments = { "string", "string", "string" } } + implement { name = "btxdirect", actions = btxdirect, arguments = { "string", "string", "string" } } - implement { name = "btxdoifelse", actions = { okay, ctx_btxdoifelse }, arguments = { "string", "string", "string" } } - implement { name = "btxdoif", actions = { okay, ctx_btxdoif }, arguments = { "string", "string", "string" } } - implement { name = "btxdoifnot", actions = { okay, ctx_btxdoifnot }, arguments = { "string", "string", "string" } } - - - else - - commands.btxflush = btxflush - commands.btxfield = btxfield - commands.btxdetail = btxdetail - commands.btxdirect = btxdirect - - function commands.btxfieldname(name,tag,field) context(get(name,tag,field,false,false)) end - function commands.btxfieldtype(name,tag,field) context(get(name,tag,field,true, false)) end - function commands.btxfoundname(name,tag,field) context(get(name,tag,field,false,true )) end - function commands.btxfoundtype(name,tag,field) context(get(name,tag,field,true, true )) end - - function commands.btxdoifelse (name,tag,field) ctx_doifelse(okay(name,tag,field)) end - function commands.btxdoif (name,tag,field) ctx_doif (okay(name,tag,field)) end - function commands.btxdoifnot (name,tag,field) ctx_doifnot (okay(name,tag,field)) end - - end + implement { name = "btxfieldname", actions = { get, context }, arguments = { "string", "string", "string", false, false } } + implement { name = "btxfieldtype", actions = { get, context }, arguments = { "string", "string", "string", true, false } } + implement { name = "btxfoundname", actions = { get, context }, arguments = { "string", "string", "string", false, true } } + implement { name = "btxfoundtype", actions = { get, context }, arguments = { "string", "string", "string", true, true } } + implement { name = "btxdoifelse", actions = { okay, ctx_doifelse }, arguments = { "string", "string", "string" } } + implement { name = "btxdoif", actions = { okay, ctx_doif }, arguments = { "string", "string", "string" } } + implement { name = "btxdoifnot", actions = { okay, ctx_doifnot }, arguments = { "string", "string", "string" } } end @@ -1440,7 +1466,7 @@ do context.input(foundname) end - function commands.loadbtxdefinitionfile(name) -- a more specific name + function publications.loaddefinitionfile(name) -- a more specific name commands.uselibrary { name = string.gsub(name,"^publ%-",""), patterns = patterns, @@ -1454,7 +1480,7 @@ do "publ-imp-%s.lua", } - function commands.loadbtxreplacementfile(name) -- a more specific name + function publications.loadreplacementfile(name) -- a more specific name commands.uselibrary { name = string.gsub(name,"^publ%-",""), patterns = patterns, @@ -1464,6 +1490,9 @@ do } end + implement { name = "btxloaddefinitionfile", actions = publications.loaddefinitionfile, arguments = "string" } + implement { name = "btxloadreplacementfile", actions = publications.loadreplacementfile, arguments = "string" } + end -- lists @@ -1656,7 +1685,7 @@ do methods[v_global] = methods[v_local] function lists.collectentries(specification) - local dataset = specification.btxdataset + local dataset = specification.dataset if not dataset then return end @@ -1764,7 +1793,7 @@ do -- setspecification - function commands.btxflushpages(dataset,tag) + local function btxflushpages(dataset,tag) -- todo: interaction local rendering = renderings[dataset] local pages = rendering.pages @@ -1830,6 +1859,12 @@ do end end + implement { + name = "btxflushpages", + actions = btxflushpages, + arguments = { "string", "string" } + } + function lists.sameasprevious(dataset,i,name) local rendering = renderings[dataset] local list = rendering.list @@ -1850,7 +1885,6 @@ do function lists.flushentry(dataset,i,textmode) local rendering = renderings[dataset] local list = rendering.list --- local result = rendering.result local luadata = datasets[dataset].luadata local li = list[i] if li then @@ -1861,7 +1895,7 @@ do -- ctx_btxstartlistentry() ctx_btxsetcurrentlistentry(i) -- redundant - ctx_btxsetcurrentlistindex(listindex) + ctx_btxsetcurrentlistindex(listindex or 0) local combined = entry.combined local language = entry.language if combined then @@ -1910,73 +1944,6 @@ do end end - -if ctx_setmacro then -- no real gain, but nice as test - - function lists.flushentry(dataset,i,textmode) - local rendering = renderings[dataset] - local list = rendering.list - local luadata = datasets[dataset].luadata - local li = list[i] - if li then - local tag = li[1] - local listindex = li[2] - local n = li[3] - local entry = luadata[tag] - -- - ctx_btxstartlistentry() - ctx_setmacro("currentbtxlistentry",i) -- redundant - ctx_setmacro("currentbtxlistindex",listindex) - local combined = entry.combined - local language = entry.language - if combined then - ctx_setmacro("currentbtxcombis",concat(combined,",")) - end - ctx_setmacro("currentbtxcategory",entry.category or "unknown") - ctx_setmacro("currentbtxtag",tag) - ctx_setmacro("currentbtxnumber",n) - if language then - ctx_setmacro("currentbtxlanguage",language) - end - local bl = li[5] - if bl and bl ~= "" then - ctx_setmacro("currentbtxbacklink",bl) - ctx_setmacro("currentbtxbacktrace",concat(li," ",5)) - local uc = citetolist[tonumber(bl)] - if uc then - ctx_setmacro("currentbtxinternal",uc.references.internal or "") - end - else - -- nothing - end - local userdata = li[4] - if userdata then - local b = userdata.btxbtx - local a = userdata.btxatx - if b then - ctx_setmacro("currentbtxbefore",b) - end - if a then - ctx_setmacro("currentbtxafter",a) - end - end - rendering.userdata = userdata - if textmode then - ctx_btxhandlelisttextentry() - else - ctx_btxhandlelistentry() - end - ctx_btxstoplistentry() - -- - -- context(function() - -- -- wrapup - -- rendering.ignoredfields = nil - -- end) - end - end - -end - local function getuserdata(dataset,key) local rendering = renderings[dataset] if rendering then @@ -1992,21 +1959,6 @@ end lists.uservariable = getuserdata - function commands.btxuservariable(dataset,key) - local value = getuserdata(dataset,key) - if value then - context(value) - end - end - - function commands.btxdoifelseuservariable(dataset,key) - if getuserdata(dataset,key) then - ctx_firstoftwoarguments() - else - ctx_secondoftwoarguments() - end - end - function lists.filterall(dataset) local r = renderings[dataset] local list = r.list @@ -2016,14 +1968,66 @@ end end end - commands.btxresolvelistreference = lists.resolve - commands.btxaddtolist = lists.addentry - commands.btxcollectlistentries = lists.collectentries - commands.btxpreparelistentries = lists.prepareentries - commands.btxfetchlistentries = lists.fetchentries - commands.btxflushlistentry = lists.flushentry + implement { + name = "btxuservariable", + actions = { getuserdata, context }, + arguments = { "string", "string" } + } + + implement { + name = "btxdoifelseuservariable", + actions = { getuserdata, ctx_doifelse }, + arguments = { "string", "string" } + } + + implement { + name = "btxresolvelistreference", + actions = lists.resolve, + arguments = { "string", "string" } + } + + implement { + name = "btxcollectlistentries", + actions = lists.collectentries, + arguments = { + { + { "names" }, + { "criterium" }, + { "reference" }, + { "method" }, + { "dataset" }, + { "keyword" }, + { "sorttype" }, + { "repeated" }, + { "ignored" }, + { "group" }, + }, + } + } + + implement { + name = "btxpreparelistentries", + actions = lists.prepareentries, + arguments = { "string" }, + } - commands.btxdoifelsesameasprevious = function(...) ctx_doifelse(lists.sameasprevious(...)) end + implement { + name = "btxfetchlistentries", + actions = lists.fetchentries, + arguments = { "string" }, + } + + implement { + name = "btxflushlistentry", + actions = lists.flushentry, + arguments = { "string", "integer" } + } + + implement { + name = "btxdoifelsesameasprevious", + actions = { lists.sameasprevious, ctx_doifelse }, + arguments = { "string", "integer", "string" } + } end @@ -2032,7 +2036,7 @@ do local citevariants = { } publications.citevariants = citevariants - function commands.btxhandlecite(specification) + local function btxhandlecite(specification) local dataset = specification.dataset or v_default local reference = specification.reference local variant = specification.variant @@ -2067,8 +2071,7 @@ do citevariants[variant](specification) -- we always fall back on default end - - function commands.btxhandlenocite(specification) + local function btxhandlenocite(specification) local dataset = specification.dataset or v_default local reference = specification.reference if not reference or reference == "" then @@ -2095,9 +2098,41 @@ do tobemarked = markentry and todo if found and tobemarked then flushmarked(dataset,list) - commands.flushmarked() -- here (could also be done in caller) - end - end + btxflushmarked() -- here (could also be done in caller) + end + end + + implement { + name = "btxhandlecite", + actions = btxhandlecite, + arguments = { + { + { "dataset" }, + { "reference" }, + { "markentry", "boolean" }, + { "variant" }, + { "sorttype" }, + { "compress" }, + { "author" }, + { "lefttext" }, + { "righttext" }, + { "before" }, + { "after" }, + } + } + } + + implement { + name = "btxhandlenocite", + actions = btxhandlenocite, + arguments = { + { + { "dataset" }, + { "reference" }, + { "markentry", "boolean" }, + } + } + } -- sorter @@ -2344,7 +2379,7 @@ do end if tobemarked then flushmarked(dataset,list) - commands.flushmarked() -- here (could also be done in caller) + btxflushmarked() -- here (could also be done in caller) end end @@ -2909,13 +2944,19 @@ do local listvariants = { } publications.listvariants = listvariants - function commands.btxlistvariant(dataset,block,tag,variant,listindex) + local function btxlistvariant(dataset,block,tag,variant,listindex) local action = listvariants[variant] or listvariants.default if action then action(dataset,block,tag,variant,tonumber(listindex) or 0) end end + implement { + name = "btxlistvariant", + actions = btxlistvariant, + arguments = { "string", "string", "string", "string", "string" } -- not integer here + } + function listvariants.default(dataset,block,tag,variant) ctx_btxsetfirst("?") if trace_detail then diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv index f376d3e7e..6c96aaf2a 100644 --- a/tex/context/base/publ-ini.mkiv +++ b/tex/context/base/publ-ini.mkiv @@ -112,11 +112,8 @@ {\popmacro\currentbtxspecification \protect} -\unexpanded\def\loadbtxdefinitionfile[#1]% - {\ctxcommand{loadbtxdefinitionfile("#1")}} - -\unexpanded\def\loadbtxreplacementfile[#1]% - {\ctxcommand{loadbtxreplacementfile("#1")}} +\unexpanded\def\loadbtxdefinitionfile [#1]{\clf_btxloaddefinitionfile {#1}} +\unexpanded\def\loadbtxreplacementfile[#1]{\clf_btxloadreplacementfile{#1}} \unexpanded\def\publ_specification_push#1% {\pushmacro\currentbtxspecification @@ -126,12 +123,12 @@ \ifx\currentbtxspecificationfallback\currentbtxspecification \let\currentbtxspecificationfallback\empty \fi - \ctxcommand{setbtxspecification("\currentbtxspecification")}} + \clf_btxsetspecification{\currentbtxspecification}} \unexpanded\def\publ_specification_pop {\popmacro\currentbtxspecificationfallback \popmacro\currentbtxspecification - \ctxcommand{setbtxspecification("\currentbtxspecification")}} + \clf_btxsetspecification{\currentbtxspecification}} \unexpanded\def\publ_specification_set#1% beware: is global {\edef\currentbtxspecification{#1}% @@ -140,7 +137,7 @@ \let\currentbtxspecificationfallback\empty \fi % has to be done explicitly: \loadbtxdefinitionfile[\currentbtxspecification]% - \ctxcommand{setbtxspecification("\currentbtxspecification")}}% todo: ,true == also load + \clf_btxsetspecification{\currentbtxspecification}}% todo: ,true == also load \installcorenamespace {btx} @@ -156,7 +153,7 @@ \appendtoks \ifnum\btxsetupmode=\doingrootsetuproot - \edef\currentbtxdataset{\ctxcommand{setbtxdataset("\btxparameter\c!dataset","\currentbtxdataset")}}% + \edef\currentbtxdataset{\clf_btxsetdataset{\btxparameter\c!dataset}{\currentbtxdataset}}% \fi \to \everysetupbtx @@ -236,17 +233,17 @@ \def\publ_use_dataset[#1][#2][#3]% {\getdummyparameters[\c!specification=\currentbtxspecification,#3]% \ifsecondargument - \ctxcommand{usebtxdataset{ - specification = "\dummyparameter\c!specification", - dataset = "#1", - filename = "#2", - }}% + \clf_btxusedataset + specification {\dummyparameter\c!specification}% + dataset {#1}% + filename {#2}% + \relax \else\iffirstargument - \ctxcommand{usebtxdataset{ - specification = "\dummyparameter\c!specification", - dataset = "\v!default", - filename = "#1", - }}% + \clf_btxusedataset + specification {\dummyparameter\c!specification}% + dataset {\v!default}% + filename {#1}% + \relax \fi\fi \endgroup} @@ -284,7 +281,7 @@ {\publ_set_publication_indeed{#1}{}}} \def\publ_set_publication_indeed#1#2#3\stoppublication - {\ctxcommand{addbtxentry("#1",\!!bs#2\!!es,\!!bs\detokenize{#3}\!!es)}% + {\clf_btxaddentry{#1}{#2}{\detokenize{#3}}% \endgroup \ignorespaces} @@ -334,8 +331,8 @@ \let\currentbtxtag \empty \let\currentbtxdataset\v!default -\unexpanded\def\setbtxentry[#1]% - {\edef\currentbtxtag{\ctxcommand{setbtxentry("\currentbtxdataset","#1")}}} +\unexpanded\def\setbtxentry[#1]% or maybe btxsetentry + {\edef\currentbtxtag{\clf_btxsetentry{\currentbtxdataset}{#1}}} % \let\btxsetdataset\setbtxdataset % \let\btxsetentry \setbtxentry @@ -345,39 +342,18 @@ % \btxfield : current % \btxspecificfield : dataset,tag,key -\ifdefined\clf_btxfield % {#1} will go - - \def\btxfield #1{\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxdetail #1{\clf_btxdetail {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxflush #1{\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxdirect #1{\clf_btxdirect {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxfieldname #1{\clf_btxfieldname {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxfieldtype #1{\clf_btxfieldtype {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxfoundname #1{\clf_btxfoundname {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxfoundtype #1{\clf_btxfoundtype {\currentbtxdataset}{\currentbtxtag}{#1}} - % \def\btxauthorfield#1{\clf_btxauthorfield\currentbtxauthorindex{#1}} - \def\btxdoifelse #1{\clf_btxdoifelse {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxdoif #1{\clf_btxdoif {\currentbtxdataset}{\currentbtxtag}{#1}} - \def\btxdoifnot #1{\clf_btxdoifnot {\currentbtxdataset}{\currentbtxtag}{#1}} - -\else - - \def\btxfield #1{\ctxcommand{btxfield("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxdetail #1{\ctxcommand{btxdetail("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxflush #1{\ctxcommand{btxflush("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxdirect #1{\ctxcommand{btxdirect("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxfieldname #1{\ctxcommand{btxfieldname("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxfieldtype #1{\ctxcommand{btxfieldtype("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxfoundname #1{\ctxcommand{btxfoundname("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxfoundtype #1{\ctxcommand{btxfoundtype("\currentbtxdataset","\currentbtxtag","#1")}} - % \def\btxauthorfield#1{\ctxcommand{btxauthorfield(\number\currentbtxauthorindex,"#1")}} - \def\btxdoifelse #1{\ctxcommand{btxdoifelse("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxdoif #1{\ctxcommand{btxdoif("\currentbtxdataset","\currentbtxtag","#1")}} - \def\btxdoifnot #1{\ctxcommand{btxdoifnot("\currentbtxdataset","\currentbtxtag","#1")}} - -\fi - -\def\btxauthorfield#1{\ctxcommand{btxauthorfield(\number\currentbtxauthorindex,"#1")}} +\def\btxfield #1{\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxdetail #1{\clf_btxdetail {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxflush #1{\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxdirect #1{\clf_btxdirect {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxfieldname #1{\clf_btxfieldname {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxfieldtype #1{\clf_btxfieldtype {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxfoundname #1{\clf_btxfoundname {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxfoundtype #1{\clf_btxfoundtype {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxauthorfield#1{\clf_btxauthorfield \currentbtxauthorindex{#1}} +\def\btxdoifelse #1{\clf_btxdoifelse {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxdoif #1{\clf_btxdoif {\currentbtxdataset}{\currentbtxtag}{#1}} +\def\btxdoifnot #1{\clf_btxdoifnot {\currentbtxdataset}{\currentbtxtag}{#1}} \let\btxsetup\fastsetup @@ -425,24 +401,24 @@ \let\currentbtxnumber \empty \unexpanded\def\btxsetnumber {\def\currentbtxnumber} \let\currentbtxauthorvariant\v!normal \unexpanded\def\btxsetauthorvariant{\def\currentbtxauthorvariant} -\unexpanded\def\currentbtxfirstnames_indeed{\ctxcommand{btx_a_f(\number\currentbtxauthorindex)}} -\unexpanded\def\currentbtxinitials_indeed {\ctxcommand{btx_a_i(\number\currentbtxauthorindex)}} -\unexpanded\def\currentbtxjuniors_indeed {\ctxcommand{btx_a_j(\number\currentbtxauthorindex)}} -\unexpanded\def\currentbtxsurnames_indeed {\ctxcommand{btx_a_s(\number\currentbtxauthorindex)}} -\unexpanded\def\currentbtxvons_indeed {\ctxcommand{btx_a_v(\number\currentbtxauthorindex)}} - \let\currentbtxfirstnames \empty \unexpanded\def\btxsetfirstnames{\let\currentbtxfirstnames\currentbtxfirstnames_indeed} \let\currentbtxinitials \empty \unexpanded\def\btxsetinitials {\let\currentbtxinitials \currentbtxinitials_indeed } \let\currentbtxjuniors \empty \unexpanded\def\btxsetjuniors {\let\currentbtxjuniors \currentbtxjuniors_indeed } \let\currentbtxsurnames \empty \unexpanded\def\btxsetsurnames {\let\currentbtxsurnames \currentbtxsurnames_indeed } \let\currentbtxvons \empty \unexpanded\def\btxsetvons {\let\currentbtxvons \currentbtxvons_indeed } -\newconstant\currentbtxoverflow \unexpanded\def\btxsetoverflow #1{\currentbtxoverflow #1\relax} -\newconstant\currentbtxconcat \unexpanded\def\btxsetconcat #1{\currentbtxconcat #1\relax} -\newconstant\currentbtxcount \unexpanded\def\btxsetcount #1{\currentbtxcount #1\relax} -\newconstant\currentbtxauthorindex %unexpanded\def\btxsetauthorindex#1{\currentbtxauthorindex#1\relax} % passed directly -\newconstant\currentbtxauthorcount %unexpanded\def\btxsetauthorcount#1{\currentbtxauthorcount#1\relax} % passed directly -\newconstant\currentbtxauthorstate \unexpanded\def\btxsetauthorstate#1{\currentbtxauthorstate#1\relax} +\newconstant\currentbtxoverflow \unexpanded\def\btxsetoverflow #1{\currentbtxoverflow #1\relax} +\newconstant\currentbtxconcat \unexpanded\def\btxsetconcat #1{\currentbtxconcat #1\relax} +\newconstant\currentbtxcount \unexpanded\def\btxsetcount #1{\currentbtxcount #1\relax} +\newconstant\currentbtxauthorindex %unexpanded\def\btxsetauthorindex#1{\currentbtxauthorindex#1\relax} % passed directly +\newconstant\currentbtxauthorcount %unexpanded\def\btxsetauthorcount#1{\currentbtxauthorcount#1\relax} % passed directly +\newconstant\currentbtxauthorstate \unexpanded\def\btxsetauthorstate#1{\currentbtxauthorstate#1\relax} + +\unexpanded\def\currentbtxfirstnames_indeed{\clf_btxcurrentfirstnames\numexpr\currentbtxauthorindex\relax} +\unexpanded\def\currentbtxinitials_indeed {\clf_btxcurrentinitials \numexpr\currentbtxauthorindex\relax} +\unexpanded\def\currentbtxjuniors_indeed {\clf_btxcurrentjuniors \numexpr\currentbtxauthorindex\relax} +\unexpanded\def\currentbtxsurnames_indeed {\clf_btxcurrentsurnames \numexpr\currentbtxauthorindex\relax} +\unexpanded\def\currentbtxvons_indeed {\clf_btxcurrentvons \numexpr\currentbtxauthorindex\relax} \def\currentbtxauthorvariant{normal} @@ -606,7 +582,7 @@ \btxparameter\c!command {\usebtxstyleandcolor\c!style\c!color \btxparameter\c!pageleft - \ctxcommand{btxflushpages("\currentbtxdataset","\currentbtxtag")}% + \clf_btxflushpages{\currentbtxdataset}{\currentbtxtag}% \btxparameter\c!pageright}% \endgroup} @@ -695,7 +671,7 @@ \unexpanded\def\btxsetcurrentlistindex#1{\edef\currentbtxlistindex{#1}} \unexpanded\def\btxdoifsameaspreviouselse#1% - {\ctxcommand{btxdoifelsesameasprevious("\currentbtxdataset",\number\currentbtxlistentry,"#1")}} + {\clf_btxdoifelsesameasprevious{\currentbtxdataset}\currentbtxlistentry{#1}} \def\publ_place_list_indeed#1[#2][#3]% {\begingroup @@ -747,29 +723,29 @@ \forgetall % why not pass this with collect .. todo % here we just collect items - \ctxcommand{btxcollectlistentries { - names = "btx", - criterium = "\currentbtxcriterium", - reference = "\btxrenderingparameter\c!reference", - method = "\btxrenderingparameter\c!method", - btxdataset = "\currentbtxdataset", - keyword = "\btxrenderingparameter\c!keyword", - sorttype = "\btxrenderingparameter\c!sorttype", - repeated = "\btxrenderingparameter\c!repeat", - ignored = "\btxrenderingparameter\c!ignore", - group = "\btxrenderingparameter\c!group", - }}% + \clf_btxcollectlistentries + names {\s!btx}% + criterium {\currentbtxcriterium}% + reference {\btxrenderingparameter\c!reference}% + method {\btxrenderingparameter\c!method}% + dataset {\currentbtxdataset}% + keyword {\btxrenderingparameter\c!keyword}% + sorttype {\btxrenderingparameter\c!sorttype}% + repeated {\btxrenderingparameter\c!repeat}% + ignored {\btxrenderingparameter\c!ignore}% + group {\btxrenderingparameter\c!group}% + \relax \ifnum\nofbtxlistentries>\zerocount \startpacked[\v!blank]% % sorting and so - \ctxcommand{btxpreparelistentries("\currentbtxdataset")}% could be put in collect + \clf_btxpreparelistentries{\currentbtxdataset}% could be put in collect % next we analyze the width \ifx\currentbtxnumbering\empty \else \edef\p_width{\listparameter\c!width}% \ifx\p_width\v!auto \setbox\scratchbox\vbox \bgroup \settrialtypesetting - \ctxcommand{btxfetchlistentries("\currentbtxdataset")}% + \clf_btxfetchlistentries{\currentbtxdataset}% \egroup \d_publ_number_width\wd\scratchbox \letlistparameter\c!width\d_publ_number_width @@ -780,7 +756,7 @@ % bunch gets flushed at once \dorecurse\nofbtxlistentries {\let\currentbtxlistentry\recurselevel - \ctxcommand{btxflushlistentry("\currentbtxdataset",\currentbtxlistentry)}}% + \clf_btxflushlistentry{\currentbtxdataset}\currentbtxlistentry\relax}% \stoppacked \fi \btxrenderingparameter\c!after @@ -852,7 +828,13 @@ \else \btxparameter\c!left \ifconditional\c_publ_prefixed\btxlistprefixednumber\fi - \ctxcommand{btxlistvariant("\currentbtxdataset","\currentbtxblock","\currentbtxtag","\currentbtxnumbering","\currentbtxnumber")}% some can go + \clf_btxlistvariant % some can go + {\currentbtxdataset}% + {\currentbtxblock}% + {\currentbtxtag}% + {\currentbtxnumbering}% + {\currentbtxnumber}% + \relax \btxparameter\c!right \fi\fi \endgroup} @@ -927,8 +909,8 @@ \s!btxint=\number\currentbtxbacklink \ifx\currentbtxciteuservariables\empty\else,\currentbtxciteuservariables\fi]}} -\def\currentbtxuservariable #1{\ctxcommand{btxuservariable("\currentbtxdataset","#1")}} -\def\btxdoifelseuservariable#1{\ctxcommand{btxdoifelseuservariable("\currentbtxdataset","#1")}} +\def\currentbtxuservariable #1{\clf_btxuservariable {\currentbtxdataset}{#1}} +\def\btxdoifelseuservariable#1{\clf_btxdoifelseuservariable{\currentbtxdataset}{#1}} \let\btxcitereference\btx_cite_reference_inject @@ -965,13 +947,18 @@ \edef\currentbtxfield{#2}% \setbtxparameterset\s!list\currentbtxfield %let\currentbtxlistvariant\currentbtxfield - \ctxcommand{btxauthor("\currentbtxdataset","\currentbtxtag","\currentbtxfield",{ - combiner = "#1", - kind = "list", - etallimit = "\btxparameter\c!etallimit", - etaldisplay = "\btxparameter\c!etaldisplay", - symbol = "\btxparameter{\c!stopper:initials}", - })}% + \clf_btxauthor + {\currentbtxdataset}% + {\currentbtxtag}% + {\currentbtxfield}% + { + combiner {#1}% + kind {list}% + etallimit {\btxparameter\c!etallimit}% + etaldisplay {\btxparameter\c!etaldisplay}% + symbol {\btxparameter{\c!stopper:initials}}% + }% + \relax \endgroup} % yes or no: maybe just \flushauthor{...}{...} @@ -985,13 +972,18 @@ \unexpanded\def\currentbtxciteauthor % always author {\begingroup \setbtxparameterset\s!cite\s!author - \ctxcommand{btxauthor("\currentbtxdataset","\currentbtxtag","\s!author",{ - combiner = "\btxparameter\c!authorconversion", - kind = "cite", - etallimit = "\btxparameter\c!etallimit", - etaldisplay = "\btxparameter\c!etaldisplay", - symbol = "\btxparameter{\c!stopper:initials}", - })}% + \clf_btxauthor + {\currentbtxdataset}% + {\currentbtxtag}% + {\s!author}% + { + combiner {\btxparameter\c!authorconversion}% + kind {cite}% + etallimit {\btxparameter\c!etallimit}% + etaldisplay {\btxparameter\c!etaldisplay}% + symbol {\btxparameter{\c!stopper:initials}}% + }% + \relax \endgroup} \unexpanded\def\btxstartauthor#1#2#3% a state > 0 signals that some authors can clash @@ -1070,7 +1062,7 @@ \begingroup \btxparameter\v!left \penalty\plustenthousand % todo - \ctxcommand{btxresolvelistreference("\currentbtxdataset","#1")}% todo: split dataset from #1, so another call + \clf_btxresolvelistreference{\currentbtxdataset}{#1}% todo: split dataset from #1, so another call \btxparameter\v!right \endgroup} @@ -1187,22 +1179,22 @@ \dosingleargument\publ_cite_handle_variant_indeed} \unexpanded\def\publ_cite_handle_variant_blob - {\btxparameter\v!left - \ctxcommand{btxhandlecite{% - dataset = "\currentbtxdataset",% - reference = \!!bs\currentbtxreference\!!es,% - markentry = \iftrialtypesetting false\else true\fi,% - variant = "\currentbtxcitealternative",% - sorttype = "\btxparameter\c!sorttype",% - compress = "\btxparameter\c!compress",% - author = "\btxparameter\c!author",% - lefttext = \!!bs\p_publ_cite_lefttext\!!es,% - righttext = \!!bs\p_publ_cite_righttext\!!es,% - before = \!!bs\p_publ_cite_before\!!es,% - after = \!!bs\p_publ_cite_after\!!es,% - }}% - \ctxcommand{flushmarked()}% maybe: \iftrialtypesetting\else ... \fi - \btxparameter\v!right} + {\btxparameter\v!left\relax + \clf_btxhandlecite + dataset {\currentbtxdataset}% + reference {\currentbtxreference}% + markentry \iftrialtypesetting\s!false\else\s!true\fi\space + variant {\currentbtxcitealternative}% + sorttype {\btxparameter\c!sorttype}% + compress {\btxparameter\c!compress}% + author {\btxparameter\c!author}% + lefttext {\p_publ_cite_lefttext}% + righttext {\p_publ_cite_righttext}% + before {\p_publ_cite_before}% + after {\p_publ_cite_after}% + \relax + \clf_btxflushmarked % maybe: \iftrialtypesetting\else ... \fi + \btxparameter\v!right\relax} \def\publ_cite_handle_variant_indeed[#1]% {\letbtxparameter\c!alternative\currentbtxcitealternative @@ -1231,12 +1223,12 @@ {\iftrialtypesetting \else \begingroup \edef\currentbtxreference{#1}% - \ctxcommand{btxhandlenocite{% - dataset = "\currentbtxdataset",% - reference = \!!bs\currentbtxreference#1\!!es,% - markentry = true,% - }}% - % \ctxcommand{flushmarked()}% + \clf_btxhandlenocite + dataset {\currentbtxdataset}% + reference {\currentbtxreference#1}% + markentry true% + \relax + % \clf_btxflushmarked \endgroup \fi} @@ -1409,9 +1401,9 @@ %D Whatever helpers: -\unexpanded\def\btxsingularplural#1{\ctxcommand{btxsingularorplural("\currentbtxdataset","\currentbtxtag","#1")}} -\unexpanded\def\btxoneorrange #1{\ctxcommand{btxoneorrange("\currentbtxdataset","\currentbtxtag","#1")}} -\unexpanded\def\btxfirstofrange #1{\ctxcommand{btxfirstofrange("\currentbtxdataset","\currentbtxtag","#1")}} +\unexpanded\def\btxsingularplural#1{\clf_btxsingularorplural{\currentbtxdataset}{\currentbtxtag}{#1}} +\unexpanded\def\btxoneorrange #1{\clf_btxoneorrange {\currentbtxdataset}{\currentbtxtag}{#1}} +\unexpanded\def\btxfirstofrange #1{\clf_btxfirstofrange {\currentbtxdataset}{\currentbtxtag}{#1}} \let\btxsingularorplural\btxsingularplural @@ -1467,12 +1459,12 @@ \c!dataset=#1,% \c!file=#2,% #3]% % all or used - \ctxcommand{btxsavedataset{ - dataset = "\dummyparameter\c!dataset", - filename = "\dummyparameter\c!file", - filetype = "\dummyparameter\c!type", - criterium = "\dummyparameter\c!criterium" - }}% + \clf_btxsavedataset + dataset {\dummyparameter\c!dataset}% + filename {\dummyparameter\c!file}% + filetype {\dummyparameter\c!type}% + criterium {\dummyparameter\c!criterium}% + \relax \endgroup} % \savebtxdataset[default][e:/tmp/foo.bib] @@ -1501,16 +1493,16 @@ \unexpanded\def\publ_registers_set {\ifx\currentbtxregister\empty \else - \ctxcommand{setbtxregister { - specification = "\currentbtxspecification", - name = "\currentbtxregister", - state = "\btxregisterparameter\c!state", - dataset = "\btxregisterparameter\c!dataset", - field = "\btxregisterparameter\c!field", - register = "\btxregisterparameter\c!register", - method = "\btxregisterparameter\c!method", - alternative = "\btxregisterparameter\c!alternative", - }}% + \clf_btxsetregister + specification {\currentbtxspecification}% + name {\currentbtxregister}% + state {\btxregisterparameter\c!state}% + dataset {\btxregisterparameter\c!dataset}% + field {\btxregisterparameter\c!field}% + register {\btxregisterparameter\c!register}% + method {\btxregisterparameter\c!method}% + alternative {\btxregisterparameter\c!alternative}% + \relax \fi} \appendtoks @@ -1530,7 +1522,7 @@ \to \everydefinebtxregister \appendtoks - \ctxcommand{btxtoregister("\currentbtxdataset","\currentbtxtag")}% + \clf_btxtoregister{\currentbtxdataset}{\currentbtxtag}% \to \t_btx_reference_inject \unexpanded\def\btxindexedauthor#1#2#3#4#5#6% alternative von last first junior diff --git a/tex/context/base/publ-reg.lua b/tex/context/base/publ-reg.lua index 0a0815eeb..39469e510 100644 --- a/tex/context/base/publ-reg.lua +++ b/tex/context/base/publ-reg.lua @@ -12,8 +12,8 @@ local sortedhash = table.sortedhash local lpegmatch = lpeg.match local context = context -local commands = commands +local implement = interfaces.implement local variables = interfaces.variables local v_once = variables.once @@ -30,7 +30,7 @@ local registrations = { } local sequence = { } local flushers = table.setmetatableindex(function(t,k) local v = t.default t[k] = v return v end) -function commands.setbtxregister(specification) +local function btxsetregister(specification) local name = specification.name local register = specification.register local dataset = specification.dataset @@ -84,7 +84,7 @@ function commands.setbtxregister(specification) end end -function commands.btxtoregister(dataset,tag) +local function btxtoregister(dataset,tag) local current = datasets[dataset] for i=1,#sequence do local step = sequence[i] @@ -102,6 +102,29 @@ function commands.btxtoregister(dataset,tag) end end +implement { + name = "btxsetregister", + actions = btxsetregister, + arguments = { + { + { "specification" }, + { "name" }, + { "state" }, + { "dataset" }, + { "field" }, + { "register" }, + { "method" }, + { "alternative" }, + } + } +} + +implement { + name = "btxtoregister", + actions = btxtoregister, + arguments = { "string", "string" } +} + -- context.setregisterentry ( -- { register }, -- { diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua index c0a23cf42..179fd7448 100644 --- a/tex/context/base/regi-ini.lua +++ b/tex/context/base/regi-ini.lua @@ -27,6 +27,13 @@ local sequencers = utilities.sequencers local textlineactions = resolvers.openers.helpers.textlineactions local setmetatableindex = table.setmetatableindex +local scanners = tokens.scanners +local scanstring = scanners.string +local setters = tokens.setters +local setmacro = setters.macro + +local scanners = interfaces.scanners + --[[ldx--

We will hook regime handling code into the input methods.

--ldx]]-- @@ -197,6 +204,7 @@ end local function disable() currentregime = "utf" sequencers.disableaction(textlineactions,"regimes.process") + return currentregime end local function enable(regime) @@ -207,6 +215,7 @@ local function enable(regime) currentregime = regime sequencers.enableaction(textlineactions,"regimes.process") end + return currentregime end regimes.toregime = toregime @@ -258,33 +267,34 @@ end -- interface: -commands.enableregime = enable -commands.disableregime = disable - -commands.pushregime = push -commands.popregime = pop +scanners.enableregime = function() + setmacro("currentregime",enable(scanstring())) +end -function commands.currentregime() - context(currentregime) +scanners.disableregime = function() + setmacro("currentregime",disable()) end +scanners.pushregime = push +scanners.popregime = pop + local stack = { } -function commands.startregime(regime) +scanners.startregime = function(regime) insert(stack,currentregime) if trace_translating then report_translating("start using %a",regime) end - enable(regime) + setmacro("currentregime",enable(regime)) end -function commands.stopregime() +scanners.stopregime = function() if #stack > 0 then local regime = remove(stack) if trace_translating then report_translating("stop using %a",regime) end - enable(regime) + setmacro("currentregime",enable(regime)) end end diff --git a/tex/context/base/regi-ini.mkiv b/tex/context/base/regi-ini.mkiv index 651e2f13c..71add44a1 100644 --- a/tex/context/base/regi-ini.mkiv +++ b/tex/context/base/regi-ini.mkiv @@ -16,34 +16,18 @@ \unprotect %D \macros -%D {enableregime,disableregime,currentregime} +%D {enableregime,disableregime, +%D startregime,stopregime, +%D currentregime} %D %D Beware, the enable and disable commands are global switches, so %D best use the start|/|stop commands. -\unexpanded\def\enableregime[#1]{\ctxcommand{enableregime("#1")}} -\unexpanded\def\disableregime {\ctxcommand{disableregime()}} -\unexpanded\def\startregime [#1]{\ctxcommand{startregime("#1")}} -\unexpanded\def\stopregime {\ctxcommand{stopregime()}} - \def\currentregime {\ctxcommand{currentregime()}} +\let\currentregime\empty -% D \macros -% D {defineregimesynonym,trueregimename} -% -% \unexpanded\def\defineregimesynonym % more or less obsolete -% {\dodoubleargument\dodefineregimesynonym} -% -% \def\dodefineregimesynonym[#1][#2]% -% {\ctxcommand{setregimesynonym("#1","#2")}} -% -% \def\trueregimename#1% -% {\ctxcommand{trueregimename("#1")}} - -% D \macros -% D {useregime} -% D -% D This one is sort of obsolete but we keep them around. - -\unexpanded\def\useregime[#1]{} +\unexpanded\def\enableregime[#1]{\clf_enableregime} +\unexpanded\def\disableregime {\clf_disableregime} +\unexpanded\def\startregime [#1]{\clf_startregime} +\unexpanded\def\stopregime {\clf_stopregime} \protect \endinput diff --git a/tex/context/base/s-fonts-ligatures.mkiv b/tex/context/base/s-fonts-ligatures.mkiv index 3453aa010..e6ff2461e 100644 --- a/tex/context/base/s-fonts-ligatures.mkiv +++ b/tex/context/base/s-fonts-ligatures.mkiv @@ -73,7 +73,7 @@ \def\showotfligaturescells{3} %def\showotfligaturesnx {12} %def\showotfligatureswidth{18em} -\def\showotfligaturesnx {\the\numexpr 3*\showotfligaturescells} +\def\showotfligaturesnx {\the\numexpr 4*\showotfligaturescells} \def\showotfligatureswidth{\the\dimexpr6em*\showotfligaturescells} \starttexdefinition showotfligaturesbanner #1 diff --git a/tex/context/base/s-languages-hyphenation.lua b/tex/context/base/s-languages-hyphenation.lua index c16c5bd2d..c5a4f91f1 100644 --- a/tex/context/base/s-languages-hyphenation.lua +++ b/tex/context/base/s-languages-hyphenation.lua @@ -13,8 +13,8 @@ local a_colormodel = attributes.private('colormodel') local nodecodes = nodes.nodecodes local nodepool = nodes.pool -local disc = nodecodes.disc -local glyph = nodecodes.glyph +local disc_code = nodecodes.disc +local glyph_code = nodecodes.glyph local emwidths = fonts.hashes.emwidths local exheights = fonts.hashes.exheights local newkern = nodepool.kern @@ -23,7 +23,7 @@ local newglue = nodepool.glue local insert_node_after = node.insert_after local traverse_by_id = node.traverse_id -local hyphenate = lang.hyphenate +local hyphenate = languages.hyphenators.handler -- lang.hyphenate local find_tail = node.tail local remove_node = nodes.remove @@ -36,11 +36,11 @@ local function identify(head,marked) while current do local id = current.id local next = current.next - if id == disc then - if prev and next.id == glyph then -- catch other usage of disc + if id == disc_code then + if prev and next then -- and next.id == glyph_code then -- catch other usage of disc marked[#marked+1] = prev end - elseif id == glyph then + elseif id == glyph_code then prev = current end current = next @@ -81,10 +81,10 @@ function moduledata.languages.hyphenation.showhyphens(head) local m = { } local l = langs[i] marked[i] = m - for n in traverse_by_id(glyph,head) do + for n in traverse_by_id(glyph_code,head) do n.lang = l end - hyphenate(head,find_tail(head)) + languages.hyphenators.methods.original(head) identify(head,m) strip(head,m) end diff --git a/tex/context/base/s-languages-hyphenation.mkiv b/tex/context/base/s-languages-hyphenation.mkiv index 769c3d059..6662dbf2f 100644 --- a/tex/context/base/s-languages-hyphenation.mkiv +++ b/tex/context/base/s-languages-hyphenation.mkiv @@ -26,7 +26,7 @@ {\begingroup \par % \language\zerocount - \setupalign[\v!nothyphenated]% + % \setupalign[\v!nothyphenated]% \ctxlua{moduledata.languages.hyphenation.startcomparepatterns("#1")}} \unexpanded\def\stopcomparepatterns @@ -56,13 +56,15 @@ \starttext +\def|#1|{-} + \startsubject{Normal text} \input tufte \stopsubject \startsubject{Compare hyphenation points of \showcomparepatternslegend[en,de]} \startcomparepatterns - \input tufte \quad (\showcomparepatternslegend) + \input tufte \quad (\showcomparepatternslegend) \stopcomparepatterns \stopsubject diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 88c6d30da..d222705ca 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -38,7 +38,12 @@ local formatters = string.formatters local P, C, R, S, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc -local nodes, node, trackers, attributes, context, commands, tex = nodes, node, trackers, attributes, context, commands, tex +local nodes = nodes +local node = node +local trackers = trackers +local attributes = attributes +local context = context +local tex = tex local texlists = tex.lists local texgetdimen = tex.getdimen @@ -46,6 +51,7 @@ local texsetdimen = tex.setdimen local texnest = tex.nest local variables = interfaces.variables +local implement = interfaces.implement -- vertical space handler @@ -1718,10 +1724,51 @@ end -- interface -commands.vspacing = vspacing.analyze -commands.vspacingsetamount = vspacing.setskip -commands.vspacingdefine = vspacing.setmap -commands.vspacingcollapse = vspacing.collapsevbox -commands.vspacingsnap = vspacing.snapbox -commands.resetprevdepth = vspacing.resetprevdepth -commands.definesnapmethod = vspacing.definesnapmethod +implement { + name = "vspacing", + actions = vspacing.analyze, + scope = "private", + arguments = "string" +} + +implement { + name = "resetprevdepth", + actions = vspacing.resetprevdepth, + scope = "private" +} + +implement { + name = "vspacingsetamount", + actions = vspacing.setskip, + scope = "private", + arguments = "string", +} + +implement { + name = "vspacingdefine", + actions = vspacing.setmap, + scope = "private", + arguments = { "string", "string" } +} + +implement { + name = "vspacingcollapse", + actions = vspacing.collapsevbox, + scope = "private", + arguments = "integer" +} + +implement { + name = "vspacingsnap", + actions = vspacing.snapbox, + scope = "private", + arguments = { "integer", "integer" } +} + +implement { + name = "definesnapmethod", + actions = vspacing.definesnapmethod, + scope = "private", + arguments = { "string", "string" } +} + diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index d635d1435..5c6e994fa 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -1217,7 +1217,7 @@ \let\normaloffinterlineskip\offinterlineskip % knuth's original \appendtoks - \ifvmode\ctxcommand{resetprevdepth()}\fi % a nasty hack (tested for a while now) + \ifvmode\clf_resetprevdepth\fi % a nasty hack (tested for a while now) \to \everyafteroutput %D My own one: @@ -1391,7 +1391,7 @@ \unexpanded\def\installsnapvalues#1#2% todo: a proper define {\edef\currentsnapper{#1:#2}% \ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else - \setevalue{\??gridsnapperattributes\currentsnapper}{\ctxcommand{definesnapmethod("#1","#2")}}% + \setevalue{\??gridsnapperattributes\currentsnapper}{\clf_definesnapmethod{#1}{#2}}% \fi \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}} @@ -1548,10 +1548,10 @@ \def\spac_grids_snap_to_finish#1% {\ifvbox\nextbox % this will go away - \ctxcommand{vspacingcollapse(\number\nextbox)}% isn't that already done? + \clf_vspacingcollapse\nextbox\relax % isn't that already done? \fi \doifelsenothing{#1}{\spac_grids_snap_value_set\v!normal}{\spac_grids_snap_value_set{#1}}% - \ctxcommand{vspacingsnap(\number\nextbox,\number\attribute\snapmethodattribute)}% + \clf_vspacingsnap\nextbox\attribute\snapmethodattribute\relax \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% \egroup} @@ -1701,7 +1701,7 @@ \def\spac_vspacing_define_amount[#1][#2][#3]% can be combined {\setvalue{\??vspacingamount#1}{\ifgridsnapping#3\else#2\fi}% - \ctxcommand{vspacingsetamount("#1")}} + \clf_vspacingsetamount{#1}} % \installcorenamespace{vspacingamountnormal} % \installcorenamespace{vspacingamountgrid} @@ -1713,13 +1713,13 @@ % \fi % \csname n>#1\endcsname{#2}% % \csname g>#1\endcsname{#3}% -% \ctxcommand{vspacingsetamount("#1")}} +% \clf_vspacingsetamount{#1}} \unexpanded\def\definevspacing {\dodoubleempty\spac_vspacing_define} \def\spac_vspacing_define[#1][#2]% - {\ctxcommand{vspacingdefine("#1","#2")}} + {\clf_vspacingdefine{#1}{#2}} %D The injector code (generated at the \LUA\ end): @@ -1841,19 +1841,19 @@ \fi\fi} \def\spac_vspacing_yes_indeed[#1]% - {\ifmmode\else\par\ctxcommand{vspacing("#1")}\fi} + {\ifmmode\else\par\clf_vspacing{#1}\fi} \def\spac_vspacing_yes_ignore[#1]% {\ifmmode\else\par\fi} \def\spac_vspacing_nop_indeed - {\ifmmode\else\par\ctxcommand{vspacing("\currentvspacing")}\fi} + {\ifmmode\else\par\clf_vspacing{\currentvspacing}\fi} \def\spac_vspacing_nop_ignore {\ifmmode\else\par\fi} \def\directvspacing#1% - {\par\ctxcommand{vspacing("#1")}} + {\par\clf_vspacing{#1}} % handy (and faster): @@ -2206,7 +2206,7 @@ % as encountered in forced blank skips (see lua code) % % \appendtoks -% \ifvmode\ctxcommand{resetprevdepth()}\fi +% \ifvmode\clf_resetprevdepth\fi % \to \everyafteroutput % % this should only happen when there is nothing left over (how to detemine that) .. testcase: diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index d42a70729..0017ae535 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 1905df03e..90483d642 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi index 4a9315f33..d3d698481 100644 --- a/tex/context/base/strc-con.mkvi +++ b/tex/context/base/strc-con.mkvi @@ -215,7 +215,7 @@ \constructionparameter\c!headcommand {\strut \constructionparameter\c!text - \ctxcommand{savedlisttitle("\currentconstructionmain",\currentconstructionlistentry)}}% + \clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax}% \endgroup} \unexpanded\def\strc_constructions_stored_start @@ -856,7 +856,7 @@ \let\currentconstructionlistentry\!!zerocount \def\strc_constructions_register - {\ctxcommand{doiflisthasentry(\currentconstructionlistentry)}% + {\clf_doiflisthasentry\numexpr\currentconstructionlistentry\relax \strc_constructions_register_nop \strc_constructions_register_yes} @@ -869,7 +869,7 @@ \def\strc_constructions_discard {\iftrialtypesetting % \writestatus{constructions}{discarding \currentconstruction: \number\currentconstructionlistentry}% - \ctxcommand{discardfromlist(\currentconstructionlistentry)}% + \clf_discardfromlist\currentconstructionlistentry\relax \fi} \let\currentconstructionlistnumber \!!zerocount @@ -939,59 +939,63 @@ \else \setnextinternalreferences{construction}\currentconstructionmain % plural \relax - \scratchcounter\ctxcommand{addtolist{ % we can set a counter at the lua end - metadata = { - kind = "construction", - name = "\currentconstructionmain", - level = structures.sections.currentlevel(), - catcodes = \the\catcodetable, - % \currentdirectionparameters - }, - references = { - internal = \nextinternalreference, - order = \nextinternalorderreference, - reference = "\currentconstructionreference", - referenceprefix = "\referenceprefix", - block = "\currentsectionblock", - section = structures.sections.currentid(), - }, - titledata = { - label = \!!bs\detokenize\expandafter{\currentconstructionlabel }\!!es, - title = \!!bs\detokenize\expandafter{\currentconstructiontitle }\!!es, + \scratchcounter\clf_addtolist + metadata { + kind {construction} + name {\currentconstructionmain} + % level structures.sections.currentlevel() + catcodes \catcodetable + % \currentdirectionparameters + } + references { + internal \nextinternalreference + order \nextinternalorderreference + reference {\currentconstructionreference} + referenceprefix {\referenceprefix} + block {\currentsectionblock} + % section structures.sections.currentid(), + } + titledata { + label {\detokenize\expandafter{\currentconstructionlabel}} + title {\detokenize\expandafter{\currentconstructiontitle}} \ifx\currentconstructionbookmark\currentconstructiontitle \else - bookmark = \!!bs\detokenize\expandafter{\currentconstructionbookmark}\!!es, + bookmark {\detokenize\expandafter{\currentconstructionbookmark}} \fi \ifx\currentconstructionlist\currentconstructiontitle \else - list = \!!bs\detokenize\expandafter{\currentconstructionlist }\!!es, + list {\detokenize\expandafter{\currentconstructionlist}} \fi - }, + } \ifconditional\c_strc_constructions_number_state - prefixdata = { - prefix = "\constructionparameter\c!prefix", - separatorset = "\constructionparameter\c!prefixseparatorset", - conversion = \!!bs\constructionparameter\c!prefixconversion\!!es, - conversionset = "\constructionparameter\c!prefixconversionset", - set = "\constructionparameter\c!prefixset", - segments = "\constructionparameter\c!prefixsegments", - connector = \!!bs\constructionparameter\c!prefixconnector\!!es, - }, - numberdata = { - numbers = structures.counters.compact("\currentconstructionnumber",nil,true), % ! number can be cloned - separatorset = "\constructionparameter\c!numberseparatorset", - conversion = "\constructionparameter\c!numberconversion", - conversionset = "\constructionparameter\c!numberconversionset", - starter = \!!bs\constructionparameter\c!numberstarter\!!es, - stopper = \!!bs\constructionparameter\c!numberstopper\!!es, - segments = "\constructionparameter\c!numbersegments", - }, + prefixdata { + prefix {\constructionparameter\c!prefix} + separatorset {\constructionparameter\c!prefixseparatorset} + conversion {\constructionparameter\c!prefixconversion} + conversionset {\constructionparameter\c!prefixconversionset} + set {\constructionparameter\c!prefixset} + segments {\constructionparameter\c!prefixsegments} + connector {\constructionparameter\c!prefixconnector} + } + numberdata { + numbers {\currentconstructionnumber} + separatorset {\constructionparameter\c!numberseparatorset} + conversion {\constructionparameter\c!numberconversion} + conversionset {\constructionparameter\c!numberconversionset} + starter {\constructionparameter\c!numberstarter} + stopper {\constructionparameter\c!numberstopper} + segments {\constructionparameter\c!numbersegments} + } \or % symbol \fi - userdata = \!!bs\detokenize{#2}\!!es % will be converted to table at the lua end - } - }\relax + userdata {\detokenize{#2}} + \relax % \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}% - \ctxcommand{setinternalreference("\referenceprefix","\currentconstructionreference",\nextinternalreference,"\interactionparameter\c!focus")}% + \clf_setinternalreference + prefix {\referenceprefix}% + reference {\currentconstructionreference}% + internal \nextinternalreference + view {\interactionparameter\c!focus}% + \relax \normalexpanded{% \endgroup \edef\noexpand\currentconstructionlistentry {\the\scratchcounter}% diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index 1f7f01e4f..b7487dbd1 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -27,6 +27,8 @@ local catcodenumbers = catcodes.numbers local ctxcatcodes = catcodenumbers.ctxcatcodes local variables = interfaces.variables +local implement = interfaces.implement + local v_last = variables.last local v_first = variables.first local v_previous = variables.previous @@ -551,10 +553,6 @@ end sections.depthnumber = depthnumber -function commands.depthnumber(n) - return context(depthnumber(n)) -end - function sections.autodepth(numbers) for i=#numbers,1,-1 do if numbers[i] ~= 0 then @@ -938,27 +936,7 @@ end local levels = { } ---~ function commands.autonextstructurelevel(level) ---~ if level > #levels then ---~ for i=#levels+1,level do ---~ levels[i] = "" ---~ end ---~ end ---~ local finish = concat(levels,"\n",level) or "" ---~ for i=level+1,#levels do ---~ levels[i] = "" ---~ end ---~ levels[level] = [[\finalizeautostructurelevel]] ---~ context(finish) ---~ end - ---~ function commands.autofinishstructurelevels() ---~ local finish = concat(levels,"\n") or "" ---~ levels = { } ---~ context(finish) ---~ end - -function commands.autonextstructurelevel(level) +local function autonextstructurelevel(level) if level > #levels then for i=#levels+1,level do levels[i] = false @@ -974,7 +952,7 @@ function commands.autonextstructurelevel(level) levels[level] = true end -function commands.autofinishstructurelevels() +local function autofinishstructurelevels() for i=1,#levels do if levels[i] then ctx_finalizeauto() @@ -983,31 +961,132 @@ function commands.autofinishstructurelevels() levels = { } end +implement { + name = "autonextstructurelevel", + actions = autonextstructurelevel, + arguments = "integer", +} + +implement { + name = "autofinishstructurelevels", + actions = autofinishstructurelevels, +} + -- interface (some are actually already commands, like sections.fullnumber) -commands.structurenumber = sections.fullnumber -commands.structuretitle = sections.title +implement { + name = "depthnumber", + actions = { depthnumber, context }, + arguments = "integer", +} + +implement { name = "structurenumber", actions = sections.fullnumber } +implement { name = "structuretitle", actions = sections.title } + +implement { name = "structurevariable", actions = sections.structuredata, arguments = { false, "string" } } +implement { name = "structureuservariable", actions = sections.userdata, arguments = { false, "string" } } +implement { name = "structurecatcodedget", actions = sections.structuredata, arguments = { false, "string", false, true } } +implement { name = "structuregivencatcodedget", actions = sections.structuredata, arguments = { false, "string", false, "integer" } } +implement { name = "structureautocatcodedget", actions = sections.structuredata, arguments = { false, "string", false, "string" } } + +implement { name = "namedstructurevariable", actions = sections.structuredata } +implement { name = "namedstructureuservariable", actions = sections.userdata } + +implement { name = "setstructurelevel", actions = sections.setlevel, arguments = { "string", "string" } } +implement { name = "getstructurelevel", actions = sections.getcurrentlevel, arguments = { "string" } } +implement { name = "setstructurenumber", actions = sections.setnumber, arguments = { "integer", "string" } } +implement { name = "getstructurenumber", actions = sections.getnumber, arguments = { "integer" } } +implement { name = "getsomestructurenumber", actions = sections.getnumber, arguments = { "integer", "string" } } +implement { name = "getfullstructurenumber", actions = sections.fullnumber, arguments = { "integer" } } +implement { name = "getsomefullstructurenumber", actions = sections.fullnumber, arguments = { "integer", "string" } } +implement { name = "getspecificstructuretitle", actions = sections.structuredata, arguments = { "string", "'titledata.title'",false,"string" } } + +implement { name = "reportstructure", actions = sections.reportstructure } + +implement { + name = "registersection", + actions = sections.register, + arguments = { + "string", + { + { "coupling" }, + { "section" }, + { "level", "integer" }, + { "parent" }, + } + } +} -commands.structurevariable = function(name) sections.structuredata(nil,name) end -commands.structureuservariable = function(name) sections.userdata (nil,name) end -commands.structurecatcodedget = function(name) sections.structuredata(nil,name,nil,true) end -commands.structuregivencatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end -commands.structureautocatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end +implement { + name = "setsectionentry", + actions = sections.setentry, + arguments = { + { + { "references", { + { "internal", "integer" }, + { "block" }, + { "referenceprefix" }, + { "reference" }, + { "backreference" }, + } + }, + { "directives", { + { "resetset" } + } + }, + { "metadata", { + { "kind" }, + { "name" }, + { "catcodes", "integer" }, + { "coding" }, + { "xmlroot" }, + { "xmlsetup" }, + { "nolist", "boolean" }, + { "increment" }, + } + }, + { "titledata", { + { "label" }, + { "title" }, + { "bookmark" }, + { "marking" }, + { "list" }, + } + }, + { "numberdata", { + { "block" }, + { "hidenumber", "boolean" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "starter" }, + { "stopper" }, + { "set" }, + { "segments" }, + { "ownnumber" }, + { "language" }, + }, + }, + { "userdata" }, + } + } +} -commands.namedstructurevariable = sections.structuredata -commands.namedstructureuservariable = sections.userdata +-- os.exit() -commands.setsectionlevel = sections.setlevel -commands.setsectionnumber = sections.setnumber -commands.getsectionnumber = sections.getnumber -commands.getfullsectionnumber = sections.fullnumber -commands.getstructuredata = sections.structuredata -commands.getcurrentsectionlevel = sections.getcurrentlevel +implement { + name = "setsectionblock", + actions = sections.setblock, + arguments = { "string", { { "bookmark" } } } +} -commands.setsectionblock = sections.setblock -commands.pushsectionblock = sections.pushblock -commands.popsectionblock = sections.popblock +implement { + name = "pushsectionblock", + actions = sections.pushblock, + arguments = { "string", { { "bookmark" } } } +} -commands.registersection = sections.register -commands.setsectionentry = sections.setentry -commands.reportstructure = sections.reportstructure +implement { + name = "popsectionblock", + actions = sections.popblock, +} diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv index 98abfd611..05b31bf4f 100644 --- a/tex/context/base/strc-doc.mkiv +++ b/tex/context/base/strc-doc.mkiv @@ -20,7 +20,12 @@ %D This will move: \unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext - {\ctxcommand{setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\interactionparameter\c!focus")}% + {\clf_setinternalreference + prefix {\currentstructurereferenceprefix}% + reference {\currentstructurereference} + internal \nextinternalreference + view {\interactionparameter\c!focus}% + \relax \xdef\currentstructureattribute {\the\lastdestinationattribute}% \xdef\currentstructuresynchronize{\ctxlatecommand{enhancelist(#1)}}} diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index 9e0309139..06506cb7f 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -32,6 +32,7 @@ local report_lists = logs.reporter("structure","lists") local context = context local commands = commands +local implement = interfaces.implement local structures = structures local lists = structures.lists @@ -193,6 +194,9 @@ function lists.addto(t) -- maybe more more here (saves parsing at the tex end) if u and type(u) == "string" then t.userdata = helpers.touserdata(u) end + if not m.level then + m.level = structures.sections.currentlevel() + end local numberdata = t.numberdata local group = numberdata and numberdata.group local name = m.name @@ -211,6 +215,9 @@ function lists.addto(t) -- maybe more more here (saves parsing at the tex end) setcomponent(t) -- can be inlined end local r = t.references + if r and not r.section then + r.section = structures.sections.currentid() + end local i = r and r.internal or 0 -- brrr local p = pushed[i] if not p then @@ -225,6 +232,13 @@ function lists.addto(t) -- maybe more more here (saves parsing at the tex end) if trace_lists then report_lists("added %a, internal %a",name,p) end + local n = t.numberdata + if n then + local numbers = n.numbers + if type(numbers) == "string" then + n.numbers = structures.counters.compact(numbers,nil,true) + end + end return p end @@ -926,29 +940,175 @@ end -- interface (maybe strclistpush etc) -commands.pushlist = lists.pushnesting -commands.poplist = lists.popnesting -commands.enhancelist = lists.enhance -commands.processlist = lists.process -commands.analyzelist = lists.analyze -commands.listtitle = lists.title -commands.listprefixednumber = lists.prefixednumber -commands.listprefixedpage = lists.prefixedpage - - -function commands.addtolist (...) context(lists.addto (...)) end -function commands.listsize (...) context(lists.size (...)) end -function commands.listlocation (...) context(lists.location (...)) end -function commands.listlabel (...) context(lists.label (...)) end -function commands.listrealpage (...) context(lists.realpage (...)) end -function commands.listgroupindex (...) context(lists.groupindex(...)) end - -function commands.currentsectiontolist() - context(lists.addto(sections.current())) +if not lists.reordered then + function lists.reordered(data) + return data.numberdata + end end -function commands.listuserdata(...) - local str, metadata = lists.userdata(...) +implement { name = "pushlist", actions = lists.pushnesting, arguments = "integer" } +implement { name = "poplist", actions = lists.popnesting } + +implement { + name = "addtolist", + actions = { lists.addto, context }, + arguments = { + { + { "references", { + { "internal", "integer" }, + { "block" }, + { "section", "integer" }, + { "location" }, + { "referenceprefix" }, + { "reference" }, + { "order", "integer" }, + } + }, + { "metadata", { + { "kind" }, + { "name" }, + { "level", "integer" }, + { "catcodes", "integer" }, + { "coding" }, + { "xmlroot" }, + { "setup" }, + } + }, + { "userdata" }, + { "titledata", { + { "label" }, + { "title" }, + { "bookmark" }, + { "marking" }, + { "list" }, + } + }, + { "prefixdata", { + { "prefix" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "set" }, + { "segments" }, + { "connector" }, + } + }, + { "numberdata", { + { "numbers" }, -- = structures.counters.compact("\currentcounter",nil,true), + { "groupsuffix" }, + { "group" }, + { "counter" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "starter" }, + { "stopper" }, + { "segments" }, + } + } + } + } +} + +implement { + name = "enhancelist", + actions = lists.enhance, + arguments = "integer" +} + +implement { + name = "processlist", + actions = lists.process, + arguments = { + { + { "names" }, + { "criterium" }, + { "reference" }, + { "extras" }, + { "order" }, + } + } +} + +implement { + name = "analyzelist", + actions = lists.analyze, + arguments = { + { + { "names" }, + { "criterium" }, + { "reference" }, + } + } +} + +implement { + name = "listtitle", + actions = lists.title, + arguments = { "string", "integer" } +} + +implement { + name = "listprefixednumber", + actions = lists.prefixednumber, + arguments = { + "string", + "integer", + { + { "prefix" }, + { "separatorset" }, + { "conversionset" }, + { "starter" }, + { "stopper" }, + { "set" }, + { "segments" }, + { "connector" }, + }, + { + { "separatorset" }, + { "conversionset" }, + { "starter" }, + { "stopper" }, + { "segments" }, + } + } +} + +implement { + name = "listprefixedpage", + actions = lists.prefixedpage, + arguments = { + "string", + "integer", + { + { "separatorset" }, + { "conversionset" }, + { "set" }, + { "segments" }, + { "connector" }, + }, + { + { "prefix" }, + { "conversionset" }, + { "starter" }, + { "stopper" }, + } + } +} + +implement { name = "listsize", actions = { lists.size, context } } +implement { name = "listlocation", actions = { lists.location, context }, arguments = "integer" } +implement { name = "listlabel", actions = { lists.label, context }, arguments = { "integer", "string" } } +implement { name = "listrealpage", actions = { lists.realpage, context }, arguments = { "string", "integer" } } +implement { name = "listgroupindex", actions = { lists.groupindex, context }, arguments = { "string", "string" } } + +implement { + name = "currentsectiontolist", + actions = { sections.current, lists.addto, context } +} + +local function userdata(name,r,tag) + local str, metadata = lists.userdata(name,r,tag) if str then -- local catcodes = metadata and metadata.catcodes -- if catcodes then @@ -960,15 +1120,21 @@ function commands.listuserdata(...) end end +implement { + name = "listuserdata", + actions = userdata, + arguments = { "string", "integer", "string" } +} + -- we could also set variables .. names will change (when this module is done) -- maybe strc_lists_savedtitle etc -function commands.doiflisthastitleelse (...) commands.doifelse(lists.hastitledata (...)) end -function commands.doiflisthaspageelse (...) commands.doifelse(lists.haspagedata (...)) end -function commands.doiflisthasnumberelse(...) commands.doifelse(lists.hasnumberdata(...)) end -function commands.doiflisthasentry (n) commands.doifelse(lists.iscached (n )) end +implement { name = "doiflisthastitleelse", actions = { lists.hastitledata, commands.doifelse }, arguments = { "string", "integer" } } +implement { name = "doiflisthaspageelse", actions = { lists.haspagedata, commands.doifelse }, arguments = { "string", "integer" } } +implement { name = "doiflisthasnumberelse", actions = { lists.hasnumberdata, commands.doifelse }, arguments = { "string", "integer" } } +implement { name = "doiflisthasentry", actions = { lists.iscached, commands.doifelse }, arguments = { "integer" } } -function commands.savedlistnumber(name,n) +local function savedlistnumber(name,n) local data = cached[tonumber(n)] if data then local numberdata = data.numberdata @@ -978,7 +1144,7 @@ function commands.savedlistnumber(name,n) end end -function commands.savedlisttitle(name,n,tag) +local function savedlisttitle(name,n,tag) local data = cached[tonumber(n)] if data then local titledata = data.titledata @@ -988,24 +1154,7 @@ function commands.savedlisttitle(name,n,tag) end end --- function commands.savedlistprefixednumber(name,n) --- local data = cached[tonumber(n)] --- if data then --- local numberdata = data.numberdata --- if numberdata then --- helpers.prefix(data,data.prefixdata) --- typesetnumber(numberdata,"number",numberdata or false) --- end --- end --- end - -if not lists.reordered then - function lists.reordered(data) - return data.numberdata - end -end - -function commands.savedlistprefixednumber(name,n) +local function savedlistprefixednumber(name,n) local data = cached[tonumber(n)] if data then local numberdata = lists.reordered(data) @@ -1016,7 +1165,29 @@ function commands.savedlistprefixednumber(name,n) end end -commands.discardfromlist = lists.discard +implement { + name = "savedlistnumber", + actions = savedlistnumber, + arguments = { "string", "integer" } +} + +implement { + name = "savedlisttitle", + actions = savedlisttitle, + arguments = { "string", "integer", "string" } +} + +implement { + name = "savedlistprefixednumber", + actions = savedlistprefixednumber, + arguments = { "string", "integer" } +} + +implement { + name = "discardfromlist", + actions = lists.discard, + arguments = { "integer" } +} -- new and experimental and therefore off by default diff --git a/tex/context/base/strc-lst.mkvi b/tex/context/base/strc-lst.mkvi index e5bdbdc99..6bc2ad67e 100644 --- a/tex/context/base/strc-lst.mkvi +++ b/tex/context/base/strc-lst.mkvi @@ -129,30 +129,31 @@ {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let... \edef\p_location{\listparameter\c!location}% \setnextinternalreference - \edef\currentlistnumber{\ctxcommand{addtolist{ - references = { - internal = \nextinternalreference, - block = "\currentsectionblock", % handy for lists, like bibl - section = structures.sections.currentid(), - % location = "\p_location", - }, - metadata = { - kind = "\listparameter\c!type", - name = "\currentlist", - level = structures.sections.currentlevel(), - catcodes = \the\catcodetable, - }, - userdata = \!!bs\detokenize{#userdata}\!!es % will be converted to table at the lua end - }}}% + \scratchcounter\clf_addtolist + references { + internal \nextinternalreference + block {\currentsectionblock} + % section structures.sections.currentid() + % location {\p_location} + } + metadata { + kind {\listparameter\c!type} + name {\currentlist} + % level structures.sections.currentlevel() + catcodes \catcodetable + } + userdata {\detokenize{#userdata}} + \relax + \edef\currentlistnumber{\the\scratchcounter}% \ifx\p_location\v!here % this branch injects nodes ! \expanded{\ctxlatecommand{enhancelist(\currentlistnumber)}}% - \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% will change + \clf_setinternalreference internal \nextinternalreference\relax % this will change \xdef\currentstructurelistattribute{\the\lastdestinationattribute}% \dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo \else % and this one doesn't - \ctxcommand{enhancelist(\currentlistnumber)}% + \clf_enhancelist\currentlistnumber\relax \fi \endgroup} @@ -324,42 +325,42 @@ \def\currentstructurelistnumber{0} % injection \def\currentlistmethod {entry} % typesetting -\def\currentlistindex {0} % typesetting +\def\currentlistindex {0} % typesetting (maybe also a real counter) \def\structurelistlocation - {\ctxcommand{listlocation(\currentlistindex)}} + {\clf_listlocation\numexpr\currentlistindex\relax} \def\structurelistrealpagenumber - {\ctxcommand{listrealpage("\currentlist",\currentlistindex)}} + {\clf_listrealpage{\currentlist}\numexpr\currentlistindex\relax} \unexpanded\def\structurelistpagenumber {\dostarttagged\t!listpage\empty - \ctxcommand{listprefixedpage( - "\currentlist", - \currentlistindex, - { - separatorset = "\listparameter\c!pageprefixseparatorset", - conversionset = "\listparameter\c!pageprefixconversionset", - set = "\listparameter\c!pageprefixset", - segments = "\listparameter\c!pageprefixsegments", - connector = \!!bs\listparameter\c!pageprefixconnector\!!es, - }, - { - prefix = "\listparameter\c!pageprefix", - conversionset = "\listparameter\c!pageconversionset", - starter = \!!bs\listparameter\c!pagestarter\!!es, - stopper = \!!bs\listparameter\c!pagestopper\!!es, + \clf_listprefixedpage + {\currentlist} + \currentlistindex + { + separatorset {\listparameter\c!pageprefixseparatorset} + conversionset {\listparameter\c!pageprefixconversionset} + set {\listparameter\c!pageprefixset} + segments {\listparameter\c!pageprefixsegments} + connector {\listparameter\c!pageprefixconnector} + } + { + prefix {\listparameter\c!pageprefix} + conversionset {\listparameter\c!pageconversionset} + starter {\listparameter\c!pagestarter} + stopper {\listparameter\c!pagestopper} } - )}% + \relax \dostoptagged} \unexpanded\def\structurelistuservariable#name% {\dostarttagged\t!listdata{#name}% - \ctxcommand{listuserdata("\currentlist",\currentlistindex,"#name")}% + \clf_listuserdata{\currentlist}\currentlistindex{#name}% \dostoptagged} \def\rawstructurelistuservariable#name% - {\ctxcommand{listuserdata("\currentlist",\currentlistindex,"#name")}} + {\clf_listuserdata{\currentlist}\currentlistindex{#name}} \unexpanded\def\structurelistfirst {\structurelistuservariable\s!first } % s! \unexpanded\def\structurelistsecond{\structurelistuservariable\s!second} % s! @@ -368,62 +369,66 @@ \def\rawstructurelistsecond{\rawstructurelistuservariable\s!second} % s! % was \unexpanded \unexpanded\def\doifstructurelisthaspageelse - {\ctxcommand{doiflisthaspageelse("\currentlist",\currentlistindex)}} + {\clf_doiflisthaspageelse{\currentlist}\numexpr\currentlistindex\relax} \unexpanded\def\doifstructurelisthasnumberelse - {\ctxcommand{doiflisthasnumberelse("\currentlist",\currentlistindex)}} + {\clf_doiflisthasnumberelse{\currentlist}\numexpr\currentlistindex\relax} \unexpanded\def\structurelistgenerictitle {\dostarttagged\t!listcontent\empty - \ctxcommand{listtitle("\currentlist",\currentlistindex)}% + \clf_listtitle{\currentlist}\currentlistindex\relax \dostoptagged} \unexpanded\def\structurelistgenericnumber % tricky, we need to delay tagging as we have nested lua calls {\dostarttagged\t!listtag\empty - \ctxcommand{listprefixednumber("\currentlist",\currentlistindex, { - prefix = "\listparameter\c!prefix", - separatorset = "\listparameter\c!prefixseparatorset", - conversionset = "\listparameter\c!prefixconversionset", - starter = \!!bs\listparameter\c!prefixstarter\!!es, - stopper = \!!bs\listparameter\c!prefixstopper\!!es, - set = "\listparameter\c!prefixset", - segments = "\listparameter\c!prefixsegments", - connector = \!!bs\listparameter\c!prefixconnector\!!es, - }, - { - separatorset = "\listparameter\c!numberseparatorset", - conversionset = "\listparameter\c!numberconversionset", - starter = \!!bs\listparameter\c!numberstarter\!!es, - stopper = \!!bs\listparameter\c!numberstopper\!!es, - segments = "\listparameter\c!numbersegments", - } )}% + \clf_listprefixednumber + {\currentlist} + \currentlistindex + { + prefix {\listparameter\c!prefix} + separatorset {\listparameter\c!prefixseparatorset} + conversionset {\listparameter\c!prefixconversionset} + starter {\listparameter\c!prefixstarter} + stopper {\listparameter\c!prefixstopper} + set {\listparameter\c!prefixset} + segments {\listparameter\c!prefixsegments} + connector {\listparameter\c!prefixconnector} + } + { + separatorset {\listparameter\c!numberseparatorset} + conversionset {\listparameter\c!numberconversionset} + starter {\listparameter\c!numberstarter} + stopper {\listparameter\c!numberstopper} + segments {\listparameter\c!numbersegments} + } + \relax \dostoptagged} % TODO: pass extra tag name (contents, figures, bibliography ...) \unexpanded\def\strc_lists_place_current#list#criterium#reference#extras#order% beware, not a user command {\dostarttaggedchained\t!list\empty\??list - \ctxcommand{processlist{ - names = "#list", - criterium = "#criterium", - reference = "#reference", - extras = "#extras", - order = "#order" - }}% + \clf_processlist + names {#list} + criterium {#criterium} + reference {#reference} + extras {#extras} + order {#order} + \relax \dostoptagged} \unexpanded\def\strc_lists_analyze#list#criterium#reference% - {\ctxcommand{analyzelist{ - names = "#list", - criterium = "#criterium", - reference = "#reference", - }}} + {\clf_analyzelist + names {#list} + criterium {#criterium} + reference {#reference} + \relax} \def\firststructureelementinlist#list% {\ctxcommand{firstinset("#list")}} \def\structurelistsize - {\ctxcommand{listsize()}} + {\clf_listsize} %D Depending on what kind of list we have (e.g.\ a section related one) %D processors can be defined. @@ -467,13 +472,13 @@ \listextraparameter\c!after} \unexpanded\def\strclistsentryprocess#tag#method#index#extra% This one is called at the lua end! - {\ctxcommand{pushlist(#index)}% + {\clf_pushlist#index\relax \edef\currentlist {#tag}% \edef\currentlistmethod{#method}% \edef\currentlistindex {#index}% \edef\currentlistextra {#extra}% \strc_lists_entry_process - \ctxcommand{poplist()}} + \clf_poplist} % lists that have a number/title are kind of generic and can share code @@ -487,7 +492,7 @@ \strc_lists_apply_renderingsetup} \installstructurelistprocessor\s!command - {\ctxcommand{listuserdata("\currentlist",\currentlistindex,"\s!command")}} + {\clf_listuserdata{\currentlist}\currentlistindex{\s!command}} \installstructurelistprocessor{section} {\let\currentlistentrynumber \structurelistgenericnumber @@ -504,7 +509,7 @@ % example of usage elsewhere: % % \installstructcurelistprocessor{pubs:userdata} -% {\ctxcommand{listuserdata("\currentlist",\currentlistindex,"bibref")}} +% {\clf_listuserdata{\currentlist}\currentlistindex{bibref}} %D List symbols are used in interactive documents where no numbers %D are used but nevertheless structure is present. Beware, the list @@ -595,7 +600,7 @@ {\currentlistentrynumber} \setvalue{\??listsymbollabels\v!yes}% auto (use value stored in tuc file) - {\edef\currentlistlabel{\ctxcommand{listlabel(\currentlistindex,"\currentlistlabel")}}% + {\edef\currentlistlabel{\clf_listlabel\currentlistindex{\currentlistlabel}}% \leftlabeltext\currentlistlabel \listparameter\c!starter \currentlistentrynumber diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua index 951cf3ced..3af9113bf 100644 --- a/tex/context/base/strc-mar.lua +++ b/tex/context/base/strc-mar.lua @@ -10,12 +10,14 @@ if not modules then modules = { } end modules ['strc-mar'] = { -- todo: only commands.* print to tex, native marks return values local insert, concat = table.insert, table.concat -local tostring, next, rawget = tostring, next, rawget +local tostring, next, rawget, type = tostring, next, rawget, type local lpegmatch = lpeg.match local context = context local commands = commands +local implement = interfaces.implement + local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex @@ -216,7 +218,11 @@ local function resolve(t,k) end function marks.define(name,settings) - settings = settings or { } + if not settings then + settings = { } + elseif type(settings) == "string" then + settings = { parent = settings } + end data[name] = settings local parent = settings.parent if parent == nil or parent == "" or parent == name then @@ -711,20 +717,17 @@ end -- interface -commands.markingtitle = marks.title -commands.markingnumber = marks.number - -commands.definemarking = marks.define -commands.relatemarking = marks.relate -commands.setmarking = marks.set -commands.resetmarking = marks.reset -commands.synchronizemarking = marks.synchronize -commands.getmarking = marks.fetch -commands.fetchonemark = marks.fetchonemark -commands.fetchtwomarks = marks.fetchtwomarks -commands.fetchallmarks = marks.fetchallmarks - -function commands.doifelsemarking(str) -- can be shortcut - commands.doifelse(marks.exists(str)) -end +implement { name = "markingtitle", actions = marks.title, arguments = { "string", "string" } } +implement { name = "markingnumber", actions = marks.number, arguments = { "string", "string" } } + +implement { name = "definemarking", actions = marks.define, arguments = { "string", "string" } } +implement { name = "relatemarking", actions = marks.relate, arguments = { "string", "string" } } +implement { name = "setmarking", actions = marks.set, arguments = { "string", "string" } } +implement { name = "resetmarking", actions = marks.reset, arguments = { "string" } } +implement { name = "synchronizemarking", actions = marks.synchronize, arguments = { "string", "integer", "string" } } +implement { name = "getmarking", actions = marks.fetch, arguments = { "string", "string", "string" } } +implement { name = "fetchonemark", actions = marks.fetchonemark, arguments = { "string", "string", "string" } } +implement { name = "fetchtwomarks", actions = marks.fetchtwomarks, arguments = { "string", "string" } } +implement { name = "fetchallmarks", actions = marks.fetchallmarks, arguments = { "string", "string" } } +implement { name = "doifelsemarking", actions = { marks.exists, commands.doifelse }, arguments = "string" } diff --git a/tex/context/base/strc-mar.mkiv b/tex/context/base/strc-mar.mkiv index 3685b66a7..6ffd3ad31 100644 --- a/tex/context/base/strc-mar.mkiv +++ b/tex/context/base/strc-mar.mkiv @@ -56,35 +56,35 @@ \unexpanded\def\synchronizemarking{\dotripleargument\strc_markings_synchronize} \appendtoks - \ctxcommand{definemarking("\currentmarking",{ parent = "\currentmarkingparent" })}% + \clf_definemarking{\currentmarking}{\currentmarkingparent}% \to \everydefinemarking \def\strc_markings_relate[#1][#2]% - {\ctxcommand{relatemarking("#1","#2")}} + {\clf_relatemarking{#1}{#2}} \def\strc_markings_set[#1]#2% {\ifconditional\inhibitsetmarking % nothing \else \doifelse{\namedmarkingparameter{#1}\c!expansion}\v!yes - {\ctxcommand{setmarking("#1",\!!bs#2\!!es)}} - {\ctxcommand{setmarking("#1",\!!bs\detokenize{#2}\!!es)}}% + {\clf_setmarking{#1}{#2}} + {\clf_setmarking{#1}{\detokenize{#2}}}% \fi} \def\strc_markings_reset[#1]% - {\ctxcommand{resetmarking("#1")}} + {\clf_resetmarking{#1}} \def\strc_markings_synchronize[#1][#2][#3]% #1=class #2=boxnumber (some day also name) #3=options, maybe second argument table - {\ifvoid#2\else\ctxcommand{synchronizemarking("#1",\number#2,"#3")}\fi} + {\ifvoid#2\else\clf_synchronizemarking{#1}#2{#3}\fi} % \def\doifelsemarking#1% why no \unexpanded -% {\ctxcommand{doifelsemarking("#1")}} +% {\clf_doifelsemarking{#1}} % \def\doifelsemarking#1% -% {\normalexpanded{\noexpand\ctxcommand{doifelsemarking("\noexpand\detokenize{#1}")}}} +% {\normalexpanded{\noexpand\clf_doifelsemarking{\noexpand\detokenize{#1}}}} -\def\doifelsemarking#1% - {\ctxcommand{doifelsemarking(\!!bs#1\!!es)}} +\def\doifelsemarking#1% no \noexpanded + {\clf_doifelsemarking{#1}} % \appendtoks % \strc_markings_synchronize[\v!page][\normalpagebox][\v!keep]% keep if no marks @@ -116,25 +116,25 @@ \setsystemmode\v!marking \the\everymarking \ifthirdargument - \ctxcommand{getmarking("#1","#2","#3")}% + \clf_getmarking{#1}{#2}{#3}% \else - \ctxcommand{getmarking("#1","\v!page","#2")}% + \clf_getmarking{#1}{\v!page}{#2}% \fi \endgroup}} % the fetchers are fully expandable: [name][method] -\def\fetchonemark[#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchonemark ("#1","\v!page","#2")}\fi} -\def\fetchtwomarks [#1]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchtwomarks("#1","\v!page")}\fi} -\def\fetchallmarks [#1]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchallmarks("#1","\v!page")}\fi} +\def\fetchonemark[#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchonemark {#1}{\v!page}{#2}\fi} +\def\fetchtwomarks [#1]{\ifconditional\inhibitgetmarking\else\clf_fetchtwomarks{#1}{\v!page}\fi} +\def\fetchallmarks [#1]{\ifconditional\inhibitgetmarking\else\clf_fetchallmarks{#1}{\v!page}\fi} \let\fetchmark\fetchonemark % also fully expandable but here we have: [name][range][method] -\def\fetchonemarking[#1]#2[#3]#4[#5]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchonemark ("#1","#3","#5")}\fi} -\def\fetchtwomarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchtwomarks("#1","#3")}\fi} -\def\fetchallmarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\ctxcommand{fetchallmarks("#1","#3")}\fi} +\def\fetchonemarking[#1]#2[#3]#4[#5]{\ifconditional\inhibitgetmarking\else\clf_fetchonemark {#1}{#3}{#5}\fi} +\def\fetchtwomarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchtwomarks{#1}{#3}\fi} +\def\fetchallmarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchallmarks{#1}{#3}\fi} \let\fetchmarking\fetchonemarking diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua index 808d23fde..15c543b08 100644 --- a/tex/context/base/strc-num.lua +++ b/tex/context/base/strc-num.lua @@ -20,6 +20,8 @@ local setmetatableindex = table.setmetatableindex local trace_counters = false trackers.register("structures.counters", function(v) trace_counters = v end) local report_counters = logs.reporter("structure","counters") +local implement = interfaces.implement + local structures = structures local helpers = structures.helpers local sections = structures.sections @@ -199,6 +201,24 @@ local function allocate(name,i) -- can be metatable return ci end +local pattern = lpeg.P(variables.by)^-1 * lpeg.C(lpeg.P(1)^1) +local lpegmatch = lpeg.match + +function counters.way(way) + if not way or way == "" then + return "" + else + return lpegmatch(pattern,way) + end +end + +implement { + name = "way", + actions = { counters.way, context }, + arguments = "string" +} + + function counters.record(name,i) return allocate(name,i or 1) end @@ -553,24 +573,7 @@ end -- interfacing -commands.definecounter = counters.define -commands.setcounter = counters.set -commands.setowncounter = counters.setown -commands.resetcounter = counters.reset -commands.restartcounter = counters.restart -commands.savecounter = counters.save -commands.restorecounter = counters.restore -commands.addcounter = counters.add - -commands.rawcountervalue = function(...) context(counters.raw (...)) end -commands.countervalue = function(...) context(counters.value (...)) end -commands.lastcountervalue = function(...) context(counters.last (...)) end -commands.firstcountervalue = function(...) context(counters.first (...)) end -commands.nextcountervalue = function(...) context(counters.next (...)) end -commands.prevcountervalue = function(...) context(counters.previous(...)) end -commands.subcountervalues = function(...) context(counters.subs (...)) end - -function commands.showcounter(name) +local function showcounter(name) local cd = counterdata[name] if cd then context("[%s:",name) @@ -583,26 +586,11 @@ function commands.showcounter(name) end end -function commands.doifelsecounter(name) commands.doifelse(counterdata[name]) end -function commands.doifcounter (name) commands.doif (counterdata[name]) end -function commands.doifnotcounter (name) commands.doifnot (counterdata[name]) end - -function commands.incrementedcounter(...) context(counters.add(...)) end - -local pattern = lpeg.P(variables.by)^-1 * lpeg.C(lpeg.P(1)^1) -local lpegmatch = lpeg.match - -function commands.way(way) - if way and way ~= "" then - context(lpegmatch(pattern,way)) - end -end - -- the noreset is somewhat messy ... always false messes up e.g. itemize but true the pagenumbers -- -- if this fails i'll clean up this still somewhat experimental mechanism (but i need use cases) -function commands.checkcountersetup(name,level,start,state) +local function checkcountersetup(name,level,start,state) local noreset = true -- level > 0 -- was true counters.restart(name,1,start,noreset) -- was true counters.setstate(name,state) @@ -610,6 +598,70 @@ function commands.checkcountersetup(name,level,start,state) sections.setchecker(name,level,counters.reset) end +-- + +implement { name = "addcounter", actions = counters.add, arguments = { "string", "integer", "integer" } } +implement { name = "setcounter", actions = counters.set, arguments = { "string", 1, "integer" } } +implement { name = "setowncounter", actions = counters.setown, arguments = { "string", 1, "string" } } +implement { name = "restartcounter", actions = counters.restart, arguments = { "string", 1, "integer" } } +implement { name = "resetcounter", actions = counters.reset, arguments = { "string", 1 } } +implement { name = "incrementcounter", actions = counters.add, arguments = { "string", 1, 1 } } +implement { name = "decrementcounter", actions = counters.add, arguments = { "string", 1, -1 } } + +implement { name = "setsubcounter", actions = counters.set, arguments = { "string", "integer", "integer" } } +implement { name = "setownsubcounter", actions = counters.setown, arguments = { "string", "integer", "string" } } +implement { name = "restartsubcounter", actions = counters.restart, arguments = { "string", "integer", "integer" } } +implement { name = "resetsubcounter", actions = counters.reset, arguments = { "string", "integer" } } +implement { name = "incrementsubcounter", actions = counters.add, arguments = { "string", "integer", 1 } } +implement { name = "decrementsubcounter", actions = counters.add, arguments = { "string", "integer", -1 } } + +implement { name = "rawcountervalue", actions = { counters.raw , context }, arguments = { "string", 1 } } +implement { name = "countervalue", actions = { counters.value , context }, arguments = { "string", 1 } } +implement { name = "lastcountervalue", actions = { counters.last , context }, arguments = { "string", 1 } } +implement { name = "firstcountervalue", actions = { counters.first , context }, arguments = { "string", 1 } } +implement { name = "nextcountervalue", actions = { counters.next , context }, arguments = { "string", 1 } } +implement { name = "prevcountervalue", actions = { counters.previous, context }, arguments = { "string", 1 } } +implement { name = "subcountervalues", actions = { counters.subs , context }, arguments = { "string", 1 } } + +implement { name = "rawsubcountervalue", actions = { counters.raw , context }, arguments = { "string", "integer" } } +implement { name = "subcountervalue", actions = { counters.value , context }, arguments = { "string", "integer" } } +implement { name = "lastsubcountervalue", actions = { counters.last , context }, arguments = { "string", "integer" } } +implement { name = "firstsubcountervalue", actions = { counters.first , context }, arguments = { "string", "integer" } } +implement { name = "nextsubcountervalue", actions = { counters.next , context }, arguments = { "string", "integer" } } +implement { name = "previoussubcountervalue", actions = { counters.previous, context }, arguments = { "string", "integer" } } +implement { name = "subsubcountervalues", actions = { counters.subs , context }, arguments = { "string", "integer" } } + +implement { name = "savecounter", actions = counters.save, arguments = "string" } +implement { name = "restorecounter", actions = counters.restore, arguments = "string" } + +implement { name = "incrementedcounter", actions = { counters.add, context }, arguments = { "string", 1, 1 } } +implement { name = "decrementedcounter", actions = { counters.add, context }, arguments = { "string", 1, -1 } } + +implement { name = "showcounter", actions = showcounter, arguments = "string" } -- todo +implement { name = "checkcountersetup", actions = checkcountersetup, arguments = { "string", "integer", "integer", "string" } } + +table.setmetatablecall(counterdata,function(t,k) return t[k] end) + +implement { name = "doifelsecounter", actions = { counterdata, commands.doifelse }, arguments = "string" } +implement { name = "doifcounter", actions = { counterdata, commands.doif }, arguments = "string" } +implement { name = "doifnotcounter", actions = { counterdata, commands.doifnot }, arguments = "string" } + +implement { + name = "definecounter", + actions = counters.define, + arguments = { + { + { "name" } , + { "start", "integer" }, + { "counter" }, + { "method" }, + } + } +} + +------------------------------------------------------------------ +------------------------------------------------------------------ + -- -- move to strc-pag.lua -- -- function counters.analyze(name,counterspecification) diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv index 5adec5afd..bd736f249 100644 --- a/tex/context/base/strc-num.mkiv +++ b/tex/context/base/strc-num.mkiv @@ -43,7 +43,7 @@ \c!state=\v!start] \def\autostructureprefixsegments#1% todo: \c!prefixsegments=\v!auto - {2:\thenamedheadlevel{\ctxcommand{way("#1\c!way")}}} + {2:\thenamedheadlevel{\clf_way{#1\c!way}}} \appendtoks \resetcounterparameter\s!counter @@ -52,12 +52,12 @@ \appendtoks \ifx\currentcounterparent\empty \edef\p_start{\counterparameter\c!start}% - \ctxcommand{definecounter { - name = "\currentcounter", - start = \ifx\p_start\empty0\else\number\p_start\fi, - counter = "\counterparameter\s!counter", - method = "\counterparameter\c!method", - }}% + \clf_definecounter + name {\currentcounter}% + start \ifx\p_start\empty\zerocount\else\p_start\fi + counter {\counterparameter\s!counter}% + method {\counterparameter\c!method}% + \relax \letcounterparameter\s!name\currentcounter \else % \letcounterparameter\s!name\currentcounterparent % we need a chained clone @@ -70,7 +70,7 @@ \ifx\currentcounter\empty \else \edef\p_number{\counterparameter\c!number}% \ifx\p_number\empty \else - \ctxcommand{setcounter("\counterparameter\s!name",1,\number\p_number)}% + \clf_setcounter{\counterparameter\s!name}\p_number\relax \letcounterparameter\c!number\empty \fi \edef\p_start{\counterparameter\c!start}% @@ -81,40 +81,26 @@ % % % % -\def\strc_counters_way#1% slow, we need to store it at the tex end - {\ctxcommand{way("\namedcounterparameter{#1}\c!way")}} - -% \def\thenamedcounterlevel#1% -% {\thenamedheadlevel{\strc_counters_way{#1}}} +\def\strc_counters_way#1{\clf_way{\namedcounterparameter{#1}\c!way}} \def\thenamedcounterlevel#1% - {\xthenamedheadlevel{\strc_counters_way{#1}}} - -% \def\strc_counters_check_setup#1% does it have to happen here? -% {% this can be done at the lua end / a bit messy here ... todo ... -% \ifcsname\??counter#1\c!number\endcsname -% \doifelsevalue {\??counter#1\c!number}{#1} {\letbeundefined{\??counter#1\c!number}}% -% {\doifvaluenothing{\??counter#1\c!number} {\letbeundefined{\??counter#1\c!number}}}% -% \fi -% \ifcsname\??counter#1\c!number\endcsname -% % it's a clone -% \else -% \edef\currentcounterlevel{\thenamedcounterlevel{#1}}% -% \edef\p_start{\counterparameter{#1}\c!start}% -% \ctxcommand{checkcountersetup("#1",\currentcounterlevel,\ifx\p_start\empty0\else\number\p_start\fi,"\counterparameter{#1}\c!state")}% -% \fi} + {\xthenamedheadlevel{\clf_way{\namedcounterparameter{#1}\c!way}}} -\def\strc_counters_check_setup +\unexpanded\def\strc_counters_check_setup {\edef\p_name{\directcounterparameter\s!name}% \ifx\currentcounter\p_name \edef\currentcounterlevel{\thenamedcounterlevel\currentcounter}% \edef\p_start{\counterparameter\c!start}% - \ctxcommand{checkcountersetup("\currentcounter",\currentcounterlevel,\ifx\p_start\empty0\else\number\p_start\fi,"\counterparameter\c!state")}% + \clf_checkcountersetup + {\currentcounter}% + \numexpr\currentcounterlevel\relax + \numexpr\ifx\p_start\empty\zerocount\else\p_start\fi\relax % bug in scanner + {\counterparameter\c!state}% \fi} -\unexpanded\def\doifcounterelse #1{\ctxcommand{doifelsecounter("\namedcounterparameter{#1}\s!name")}} -\unexpanded\def\doifcounter #1{\ctxcommand{doifcounter ("\namedcounterparameter{#1}\s!name")}} -\unexpanded\def\doifnotcounter #1{\ctxcommand{doifnotcounter ("\namedcounterparameter{#1}\s!name")}} +\unexpanded\def\doifcounterelse #1{\clf_doifelsecounter{\namedcounterparameter{#1}\s!name}} +\unexpanded\def\doifcounter #1{\clf_doifcounter {\namedcounterparameter{#1}\s!name}} +\unexpanded\def\doifnotcounter #1{\clf_doifnotcounter {\namedcounterparameter{#1}\s!name}} \unexpanded\def\setcounter {\dotripleempty \strc_counters_set_interfaced} \unexpanded\def\setcounterown {\dotripleempty \strc_counters_setown_interfaced} @@ -255,90 +241,90 @@ \expandafter\gobbleoneoptional \fi} -\def\strc_counters_set_two [#1][#2][#3]{\strc_counters_set_sub {#1}{#2}{#3}} -\def\strc_counters_setown_two [#1][#2][#3]{\strc_counters_setown_sub {#1}{#2}{#3}} -\def\strc_counters_restart_two [#1][#2][#3]{\strc_counters_restart_sub {#1}{#2}{#3}} -\def\strc_counters_reset_two [#1][#2]{\strc_counters_reset_sub {#1}{#2}} -\def\strc_counters_increment_two [#1][#2]{\strc_counters_increment_sub{#1}{#2}} -\def\strc_counters_decrement_two [#1][#2]{\strc_counters_decrement_sub{#1}{#2}} - -\def\strc_counters_raw_two [#1][#2]{\strc_counters_raw_sub {#1}{#2}} -\def\strc_counters_last_two [#1][#2]{\strc_counters_last_sub {#1}{#2}} -\def\strc_counters_first_two [#1][#2]{\strc_counters_first_sub {#1}{#2}} -\def\strc_counters_next_two [#1][#2]{\strc_counters_next_sub {#1}{#2}} -\def\strc_counters_prev_two [#1][#2]{\strc_counters_prev_sub {#1}{#2}} -\def\strc_counters_subs_two [#1][#2]{\strc_counters_subs_sub {#1}{#2}} - -\def\strc_counters_set_one [#1][#2][#3]{\strc_counters_set_sub {#1}\plusone{#2}} -\def\strc_counters_setown_one [#1][#2][#3]{\strc_counters_setown_sub {#1}\plusone{#2}} -\def\strc_counters_restart_one [#1][#2][#3]{\strc_counters_restart_sub {#1}\plusone{#2}} -\def\strc_counters_reset_one [#1][#2]{\strc_counters_reset_sub {#1}\plusone} -\def\strc_counters_increment_one [#1][#2]{\strc_counters_increment_sub{#1}\plusone} -\def\strc_counters_decrement_one [#1][#2]{\strc_counters_decrement_sub{#1}\plusone} - -\def\strc_counters_raw_one [#1][#2]{\strc_counters_raw_sub {#1}\plusone} -\def\strc_counters_last_one [#1][#2]{\strc_counters_last_sub {#1}\plusone} -\def\strc_counters_first_one [#1][#2]{\strc_counters_first_sub {#1}\plusone} -\def\strc_counters_next_one [#1][#2]{\strc_counters_next_sub {#1}\plusone} -\def\strc_counters_prev_one [#1][#2]{\strc_counters_prev_sub {#1}\plusone} -\def\strc_counters_subs_one [#1][#2]{\strc_counters_subs_sub {#1}\plusone} - -\def\strc_counters_save_one [#1]{\strc_counters_save {#1}} -\def\strc_counters_restore_one [#1]{\strc_counters_restore {#1}} - -\unexpanded\def\strc_counters_set #1#2{\strc_counters_set_sub {#1}\plusone{#2}} -\unexpanded\def\strc_counters_setown #1#2{\strc_counters_setown_sub {#1}\plusone{#2}} -\unexpanded\def\strc_counters_restart #1#2{\strc_counters_restart_sub {#1}\plusone{#2}} -\unexpanded\def\strc_counters_reset #1{\strc_counters_reset_sub {#1}\plusone} -\unexpanded\def\strc_counters_increment #1{\strc_counters_increment_sub{#1}\plusone} -\unexpanded\def\strc_counters_decrement #1{\strc_counters_decrement_sub{#1}\plusone} - - \def\strc_counters_raw #1{\strc_counters_raw_sub {#1}\plusone} - \def\strc_counters_last #1{\strc_counters_last_sub {#1}\plusone} - \def\strc_counters_first #1{\strc_counters_first_sub {#1}\plusone} - \def\strc_counters_next #1{\strc_counters_next_sub {#1}\plusone} - \def\strc_counters_prev #1{\strc_counters_prev_sub {#1}\plusone} - \def\strc_counters_subs #1{\strc_counters_subs_sub {#1}\plusone} - -\unexpanded\def\strc_counters_set_sub #1#2#3{\ctxcommand{setcounter ("\namedcounterparameter{#1}\s!name",\number#2,\number#3)}} -\unexpanded\def\strc_counters_setown_sub #1#2#3{\ctxcommand{setowncounter ("\namedcounterparameter{#1}\s!name",\number#2,"#3")}} -\unexpanded\def\strc_counters_restart_sub #1#2#3{\ctxcommand{restartcounter("\namedcounterparameter{#1}\s!name",\number#2,\number#3)}} -\unexpanded\def\strc_counters_reset_sub #1#2{\ctxcommand{resetcounter ("\namedcounterparameter{#1}\s!name",\number#2)}} -\unexpanded\def\strc_counters_increment_sub #1#2{\ctxcommand{addcounter ("\namedcounterparameter{#1}\s!name",\number#2,1)}} -\unexpanded\def\strc_counters_decrement_sub #1#2{\ctxcommand{addcounter ("\namedcounterparameter{#1}\s!name",\number#2,-1)}} - - \def\strc_counters_raw_sub #1#2{\ctxcommand{countervalue ("\namedcounterparameter{#1}\s!name",\number#2)}} % maybe raw - \def\strc_counters_last_sub #1#2{\ctxcommand{lastcountervalue ("\namedcounterparameter{#1}\s!name",\number#2)}} - \def\strc_counters_first_sub #1#2{\ctxcommand{firstcountervalue ("\namedcounterparameter{#1}\s!name",\number#2)}} - \def\strc_counters_next_sub #1#2{\ctxcommand{nextcountervalue ("\namedcounterparameter{#1}\s!name",\number#2)}} - \def\strc_counters_prev_sub #1#2{\ctxcommand{previouscountervalue("\namedcounterparameter{#1}\s!name",\number#2)}} - \def\strc_counters_subs_sub #1#2{\ctxcommand{subcountervalues ("\namedcounterparameter{#1}\s!name",\number#2)}} - -\unexpanded\def\strc_counters_save #1{\ctxcommand{savecounter ("\namedcounterparameter{#1}\s!name")}} -\unexpanded\def\strc_counters_restore #1{\ctxcommand{restorecounter("\namedcounterparameter{#1}\s!name")}} - -\unexpanded\def\strc_counters_incremented #1{\ctxcommand{incrementedcounter("\namedcounterparameter{#1}\s!name",1, 1)}} -\unexpanded\def\strc_counters_decremented #1{\ctxcommand{incrementedcounter("\namedcounterparameter{#1}\s!name",1,-1)}} - -\unexpanded\def\showcounter [#1]{\ctxcommand{tracecounter("\namedcounterparameter{#1}\s!name")}} - -\unexpanded\def\incrementedcounter [#1]{\strc_counters_incremented{#1}} % expandable, no \dosingleargument -\unexpanded\def\decrementedcounter [#1]{\strc_counters_decremented{#1}} % expandable, no \dosingleargument +\def\strc_counters_set_two [#1][#2][#3]{\clf_setsubcounter {\namedcounterparameter{#1}\s!name}#2 #3\relax} +\def\strc_counters_setown_two [#1][#2][#3]{\clf_setownsubcounter {\namedcounterparameter{#1}\s!name}#2{#3}} +\def\strc_counters_restart_two [#1][#2][#3]{\clf_restartsubcounter {\namedcounterparameter{#1}\s!name}#2 #3\relax} +\def\strc_counters_reset_two [#1][#2]{\clf_resetsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\def\strc_counters_increment_two [#1][#2]{\clf_incrementsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\def\strc_counters_decrement_two [#1][#2]{\clf_decrementsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} + +\def\strc_counters_raw_two [#1][#2]{\clf_subcountervalue {\namedcounterparameter{#1}\s!name}#2 } +\def\strc_counters_last_two [#1][#2]{\clf_lastsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } +\def\strc_counters_first_two [#1][#2]{\clf_firstsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } +\def\strc_counters_next_two [#1][#2]{\clf_nextsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } +\def\strc_counters_prev_two [#1][#2]{\clf_previoussubcountervalue{\namedcounterparameter{#1}\s!name}#2 } +\def\strc_counters_subs_two [#1][#2]{\clf_subsubcountervalues {\namedcounterparameter{#1}\s!name}#2 } + +\def\strc_counters_set_one [#1][#2][#3]{\clf_setcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\def\strc_counters_setown_one [#1][#2][#3]{\clf_setowncounter {\namedcounterparameter{#1}\s!name}{#2}} +\def\strc_counters_restart_one [#1][#2][#3]{\clf_restartcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\def\strc_counters_reset_one [#1][#2]{\clf_resetcounter {\namedcounterparameter{#1}\s!name}\relax} +\def\strc_counters_increment_one [#1][#2]{\clf_incrementcounter {\namedcounterparameter{#1}\s!name}\relax} +\def\strc_counters_decrement_one [#1][#2]{\clf_decrementcounter {\namedcounterparameter{#1}\s!name}\relax} + +\def\strc_counters_raw_one [#1][#2]{\clf_countervalue {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_last_one [#1][#2]{\clf_lastcountervalue {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_first_one [#1][#2]{\clf_firstcountervalue {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_next_one [#1][#2]{\clf_nextcountervalue {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_prev_one [#1][#2]{\clf_previouscountervalue {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_subs_one [#1][#2]{\clf_subcountervalues {\namedcounterparameter{#1}\s!name}} + +\def\strc_counters_save_one [#1]{\clf_savecounter {\namedcounterparameter{#1}\s!name}} +\def\strc_counters_restore_one [#1]{\clf_restorecounter {\namedcounterparameter{#1}\s!name}} + +\unexpanded\def\strc_counters_set #1#2{\clf_setcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\unexpanded\def\strc_counters_setown #1#2{\clf_setowncounter {\namedcounterparameter{#1}\s!name}{#2}} +\unexpanded\def\strc_counters_restart #1#2{\clf_restartcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\unexpanded\def\strc_counters_reset #1{\clf_resetcounter {\namedcounterparameter{#1}\s!name}\relax} +\unexpanded\def\strc_counters_increment #1{\clf_incrementcounter {\namedcounterparameter{#1}\s!name}\relax} +\unexpanded\def\strc_counters_decrement #1{\clf_decrementcounter {\namedcounterparameter{#1}\s!name}\relax} + + \def\strc_counters_raw #1{\clf_countervalue {\namedcounterparameter{#1}\s!name}} + \def\strc_counters_last #1{\clf_lastcountervalue {\namedcounterparameter{#1}\s!name}} + \def\strc_counters_first #1{\clf_firstcountervalue {\namedcounterparameter{#1}\s!name}} + \def\strc_counters_next #1{\clf_nextcountervalue {\namedcounterparameter{#1}\s!name}} + \def\strc_counters_prev #1{\clf_previouscountervalue {\namedcounterparameter{#1}\s!name}} + \def\strc_counters_subs #1{\clf_subcountervalues {\namedcounterparameter{#1}\s!name}} + +\unexpanded\def\strc_counters_set_sub #1#2#3{\clf_setsubcounter {\namedcounterparameter{#1}\s!name}#2 #3\relax} +\unexpanded\def\strc_counters_setown_sub #1#2#3{\clf_setownsubcounter {\namedcounterparameter{#1}\s!name}#2{#3}} +\unexpanded\def\strc_counters_restart_sub #1#2#3{\clf_restartsubcounter {\namedcounterparameter{#1}\s!name}#2 #3\relax} +\unexpanded\def\strc_counters_reset_sub #1#2{\clf_resetsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\unexpanded\def\strc_counters_increment_sub #1#2{\clf_incrementsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} +\unexpanded\def\strc_counters_decrement_sub #1#2{\clf_decrementsubcounter {\namedcounterparameter{#1}\s!name}#2\relax} + + \def\strc_counters_raw_sub #1#2{\clf_subcountervalue {\namedcounterparameter{#1}\s!name}#2 } % maybe raw + \def\strc_counters_last_sub #1#2{\clf_lastsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } + \def\strc_counters_first_sub #1#2{\clf_firstsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } + \def\strc_counters_next_sub #1#2{\clf_nextsubcountervalue {\namedcounterparameter{#1}\s!name}#2 } + \def\strc_counters_prev_sub #1#2{\clf_previoussubcountervalue{\namedcounterparameter{#1}\s!name}#2 } + \def\strc_counters_subs_sub #1#2{\clf_subsubcountervalues {\namedcounterparameter{#1}\s!name}#2 } + +\unexpanded\def\strc_counters_save #1{\clf_savecounter {\namedcounterparameter{#1}\s!name}} +\unexpanded\def\strc_counters_restore #1{\clf_restorecounter {\namedcounterparameter{#1}\s!name}} + +\unexpanded\def\strc_counters_incremented #1{\clf_incrementedcounter {\namedcounterparameter{#1}\s!name}} +\unexpanded\def\strc_counters_decremented #1{\clf_decrementedcounter {\namedcounterparameter{#1}\s!name}} + +\unexpanded\def\showcounter [#1]{\clf_showcounter {\namedcounterparameter{#1}\s!name}} + +\unexpanded\def\incrementedcounter [#1]{\clf_incrementedcounter {\namedcounterparameter{#1}\s!name}} % no \dosingleargument +\unexpanded\def\decrementedcounter [#1]{\clf_decrementedcounter {\namedcounterparameter{#1}\s!name}} % no \dosingleargument % public variants ... beware, for old cases, from now on the value variants are the % ones that are expandable -\def\rawcountervalue [#1]{\strc_counters_raw_sub {#1}\plusone} -\def\lastcountervalue [#1]{\strc_counters_last_sub {#1}\plusone} -\def\firstcountervalue[#1]{\strc_counters_first_sub{#1}\plusone} -\def\nextcountervalue [#1]{\strc_counters_next_sub {#1}\plusone} -\def\prevcountervalue [#1]{\strc_counters_prev_sub {#1}\plusone} +\def\rawcountervalue [#1]{\clf_countervalue {\namedcounterparameter{#1}\s!name}} +\def\lastcountervalue [#1]{\clf_lastcountervalue {\namedcounterparameter{#1}\s!name}} +\def\firstcountervalue [#1]{\clf_firstcountervalue {\namedcounterparameter{#1}\s!name}} +\def\nextcountervalue [#1]{\clf_nextcountervalue {\namedcounterparameter{#1}\s!name}} +\def\prevcountervalue [#1]{\clf_previouscountervalue{\namedcounterparameter{#1}\s!name}} -\let\rawsubcountervalue \strc_counters_raw_two -\let\lastsubcountervalue \strc_counters_last_two -\let\firstsubcountervalue\strc_counters_first_two -\let\nextsubcountervalue \strc_counters_next_two -\let\prevsubcountervalue \strc_counters_prev_two +\let\rawsubcountervalue \strc_counters_raw_two +\let\lastsubcountervalue \strc_counters_last_two +\let\firstsubcountervalue \strc_counters_first_two +\let\nextsubcountervalue \strc_counters_next_two +\let\prevsubcountervalue \strc_counters_prev_two % The bypage check needs a multipass reference and therefore we only check for it when we increment % and know that some content will be placed. We could also check for spreads. @@ -352,7 +338,7 @@ \strc_counters_reset{#1}% \fi \fi - \ctxcommand{addcounter("\namedcounterparameter{#1}\s!name",\number#2,1)}} + \clf_incrementsubcounter{\namedcounterparameter{#1}\s!name}#2\relax} \unexpanded\def\convertedcounter {\dodoubleempty\strc_counters_converted} @@ -361,58 +347,58 @@ {\begingroup \edef\currentcounter{#1}% \ifsecondargument\setupcurrentcounter[#2]\fi - \ctxcommand{prefixedconverted( - "\counterparameter\s!name", + \clf_prefixedconverted + {\counterparameter\s!name} { - prefix = "\counterparameter\c!prefix", - separatorset = "\counterparameter\c!prefixseparatorset", - conversion = "\counterparameter\c!prefixconversion", - conversionset = "\counterparameter\c!prefixconversionset", - starter = \!!bs\counterparameter\c!prefixstarter\!!es, - stopper = \!!bs\counterparameter\c!prefixstopper\!!es, - set = "\counterparameter\c!prefixset", - segments = "\counterparameter\c!prefixsegments", - connector = \!!bs\counterparameter\c!prefixconnector\!!es, - }, + prefix {\counterparameter\c!prefix} + separatorset {\counterparameter\c!prefixseparatorset} + conversion {\counterparameter\c!prefixconversion} + conversionset {\counterparameter\c!prefixconversionset} + starter {\counterparameter\c!prefixstarter} + stopper {\counterparameter\c!prefixstopper} + set {\counterparameter\c!prefixset} + segments {\counterparameter\c!prefixsegments} + connector {\counterparameter\c!prefixconnector} + } { - order = "\counterparameter\c!numberorder", - separatorset = "\counterparameter\c!numberseparatorset", - conversion = \!!bs\counterparameter\c!numberconversion\!!es, - conversionset = "\counterparameter\c!numberconversionset", - starter = \!!bs\counterparameter\c!numberstarter\!!es, - stopper = \!!bs\counterparameter\c!numberstopper\!!es, - segments = "\counterparameter\c!numbersegments", - type = "\counterparameter\c!type", - criterium = "\counterparameter\c!criterium", % might change if we also want this with sectioning + order {\counterparameter\c!numberorder} + separatorset {\counterparameter\c!numberseparatorset} + conversion {\counterparameter\c!numberconversion} + conversionset {\counterparameter\c!numberconversionset} + starter {\counterparameter\c!numberstarter} + stopper {\counterparameter\c!numberstopper} + segments {\counterparameter\c!numbersegments} + type {\counterparameter\c!type} + criterium {\counterparameter\c!criterium} } - )}% + \relax \endgroup} \def\directconvertedcounter#1#2% name, type - {\ctxcommand{prefixedconverted( - "\namedcounterparameter{#1}\s!name", + {\clf_prefixedconverted + {\namedcounterparameter{#1}\s!name} { - prefix = "\namedcounterparameter{#1}\c!prefix", - separatorset = "\namedcounterparameter{#1}\c!prefixseparatorset", - conversion = "\namedcounterparameter{#1}\c!prefixconversion", - conversionset = "\namedcounterparameter{#1}\c!prefixconversionset", - % starter = \!!bs\namedcounterparameter{#1}\c!prefixstarter\!!es, - % stopper = \!!bs\namedcounterparameter{#1}\c!prefixstopper\!!es, - set = "\namedcounterparameter{#1}\c!prefixset", - segments = "\namedcounterparameter{#1}\c!prefixsegments", - connector = \!!bs\namedcounterparameter{#1}\c!prefixconnector\!!es, - }, + prefix {\namedcounterparameter{#1}\c!prefix} + separatorset {\namedcounterparameter{#1}\c!prefixseparatorset} + conversion {\namedcounterparameter{#1}\c!prefixconversion} + conversionset {\namedcounterparameter{#1}\c!prefixconversionset} + % starter {\namedcounterparameter{#1}\c!prefixstarter} + % stopper {\namedcounterparameter{#1}\c!prefixstopper} + set {\namedcounterparameter{#1}\c!prefixset} + segments {\namedcounterparameter{#1}\c!prefixsegments} + connector {\namedcounterparameter{#1}\c!prefixconnector} + } { - order = "\namedcounterparameter{#1}\c!numberorder", - separatorset = "\namedcounterparameter{#1}\c!numberseparatorset", - conversion = \!!bs\namedcounterparameter{#1}\c!numberconversion\!!es, - conversionset = "\namedcounterparameter{#1}\c!numberconversionset", - starter = \!!bs\namedcounterparameter{#1}\c!numberstarter\!!es, - stopper = \!!bs\namedcounterparameter{#1}\c!numberstopper\!!es, - segments = "\namedcounterparameter{#1}\c!numbersegments", - type = "#2", + order {\namedcounterparameter{#1}\c!numberorder} + separatorset {\namedcounterparameter{#1}\c!numberseparatorset} + conversion {\namedcounterparameter{#1}\c!numberconversion} + conversionset {\namedcounterparameter{#1}\c!numberconversionset} + starter {\namedcounterparameter{#1}\c!numberstarter} + stopper {\namedcounterparameter{#1}\c!numberstopper} + segments {\namedcounterparameter{#1}\c!numbersegments} + type {#2} } - )}} + \relax} \unexpanded\def\convertedsubcounter {\dotripleempty\strc_counters_converted_sub} @@ -598,68 +584,69 @@ \fi % \setnextinternalreference - \xdef\m_strc_counters_last_registered_index{\ctxcommand{addtolist{ - metadata = { - kind = "#1", - name = "\currentname", - level = structures.sections.currentlevel(), - catcodes = \the\ifx\currentstructurecomponentcatcodes\empty\catcodetable\else\csname\currentstructurecomponentcatcodes\endcsname\fi, - coding = "\currentstructurecomponentcoding", + \scratchcounter\clf_addtolist %{ + metadata { + kind {#1} + name {\currentname} + % level structures.sections.currentlevel() + catcodes \ifx\currentstructurecomponentcatcodes\empty\catcodetable\else\csname\currentstructurecomponentcatcodes\endcsname\fi + coding {\currentstructurecomponentcoding} \ifx\currentstructurecomponentcoding\s!xml - xmlroot = "\xmldocument", + xmlroot {\xmldocument} \fi \ifx\currentstructurecomponentxmlsetup\empty \else - xmlsetup = "\currentstructurexmlsetup", + xmlsetup {\currentstructurexmlsetup} \fi - }, - references = { - internal = \nextinternalreference, - block = "\currentsectionblock", - reference = "\currentstructurecomponentreference", - referenceprefix = "\currentstructurecomponentreferenceprefix", - section = structures.sections.currentid(), - }, - titledata = { - label = \!!bs\detokenize\expandafter{\currentstructurecomponentlabel }\!!es, - title = \!!bs\detokenize\expandafter{\currentstructurecomponenttitle }\!!es, + } + references { + internal \nextinternalreference + block {\currentsectionblock} + reference {\currentstructurecomponentreference} + referenceprefix {\currentstructurecomponentreferenceprefix} + % section structures.sections.currentid() + } + titledata { + label {\detokenize\expandafter{\currentstructurecomponentlabel}} + title {\detokenize\expandafter{\currentstructurecomponenttitle}} \ifx\currentstructurecomponentbookmark\currentstructurecomponenttitle \else - bookmark = \!!bs\detokenize\expandafter{\currentstructurecomponentbookmark}\!!es, + bookmark {\detokenize\expandafter{\currentstructurecomponentbookmark}} \fi \ifx\currentstructurecomponentmarking\currentstructurecomponenttitle \else - marking = \!!bs\detokenize\expandafter{\currentstructurecomponentmarking }\!!es, + marking {\detokenize\expandafter{\currentstructurecomponentmarking}} \fi \ifx\currentstructurecomponentlist\currentstructurecomponenttitle \else - list = \!!bs\detokenize\expandafter{\currentstructurecomponentlist}\!!es, + list {\detokenize\expandafter{\currentstructurecomponentlist}} \fi - }, - \ifx\p_hasnumber\v!yes - prefixdata = { - prefix = "#2\c!prefix", - separatorset = "#2\c!prefixseparatorset", - conversion = \!!bs#2\c!prefixconversion\!!es, - conversionset = "#2\c!prefixconversionset", - set = "#2\c!prefixset", - % segments = "#2\c!prefixsegments", - segments = "\p_prefixsegments", - connector = \!!bs#2\c!prefixconnector\!!es, - }, - numberdata = { % more helpers here, like compact elsewhere - numbers = structures.counters.compact("\currentcounter",nil,true), - group = "#2\c!group", - groupsuffix = \!!bs#2\c!groupsuffix\!!es, - counter = "\currentcounter", - separatorset = "#2\c!numberseparatorset", - conversion = \!!bs#2\c!numberconversion\!!es, - conversionset = "#2\c!numberconversionset", - starter = \!!bs#2\c!numberstarter\!!es, - stopper = \!!bs#2\c!numberstopper\!!es, - segments = "#2\c!numbersegments", - }, - \fi - userdata = \!!bs\detokenize{#4}\!!es % will be converted to table at the lua end - } - }}% - \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% + } + \ifx\p_hasnumber\v!yes + prefixdata { + prefix {#2\c!prefix} + separatorset {#2\c!prefixseparatorset} + conversion {#2\c!prefixconversion} + conversionset {#2\c!prefixconversionset} + set {#2\c!prefixset} + % segments {#2\c!prefixsegments} + segments {\p_prefixsegments} + connector {#2\c!prefixconnector} + } + numberdata { % more helpers here, like compact elsewhere + numbers {\currentcounter} + group {#2\c!group} + groupsuffix {#2\c!groupsuffix} + counter {\currentcounter} + separatorset {#2\c!numberseparatorset} + conversion {#2\c!numberconversion} + conversionset {#2\c!numberconversionset} + starter {#2\c!numberstarter} + stopper {#2\c!numberstopper} + segments {#2\c!numbersegments} + } + \fi + userdata {\detokenize{#4}} + %} + \relax + \xdef\m_strc_counters_last_registered_index{\the\scratchcounter}% + \clf_setinternalreference internal \nextinternalreference\relax \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}% \xdef\m_strc_counters_last_registered_synchronize{\ctxlatecommand{enhancelist(\m_strc_counters_last_registered_index)}}} diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua index 35b288888..ede731d2b 100644 --- a/tex/context/base/strc-pag.lua +++ b/tex/context/base/strc-pag.lua @@ -25,6 +25,7 @@ local counterdata = counters.data local variables = interfaces.variables local context = context local commands = commands +local implement = interfaces.implement local processors = typesetters.processors local applyprocessor = processors.apply @@ -325,5 +326,58 @@ end -- -commands.savepagedata = pages.save -commands.prefixedconverted = sections.prefixedconverted -- weird place +implement { + name = "savepagedata", + actions = pages.save, + arguments = { + { + { "prefix" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "set" }, + { "segments" }, + { "connector" }, + }, + { + { "conversionset" }, + { "conversion" }, + { "starter" }, + { "stopper" }, + }, + { + { "viewerprefix" }, + { "state" }, + } + } +} + +implement { -- weird place + name = "prefixedconverted", + actions = sections.prefixedconverted, + arguments = { + "string", + { + { "prefix" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "starter" }, + { "stopper" }, + { "set" }, + { "segments" }, + { "connector" }, + }, + { + { "order" }, + { "separatorset" }, + { "conversionset" }, + { "conversion" }, + { "starter" }, + { "stopper" }, + { "segments" }, + { "type" }, + { "criterium" }, + } + } +} diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv index 6eddc0fba..808a2854a 100644 --- a/tex/context/base/strc-pag.mkiv +++ b/tex/context/base/strc-pag.mkiv @@ -111,24 +111,25 @@ % invisible = \def\strc_pagenumbers_page_state_save % \normalexpanded? - {\ctxcommand{savepagedata({ - prefix = "\namedcounterparameter\s!userpage\c!prefix", - separatorset = "\namedcounterparameter\s!userpage\c!prefixseparatorset", - conversion = "\namedcounterparameter\s!userpage\c!prefixconversion", - conversionset = "\namedcounterparameter\s!userpage\c!prefixconversionset", - set = "\namedcounterparameter\s!userpage\c!prefixset", - segments = "\namedcounterparameter\s!userpage\c!prefixsegments", - connector = \!!bs\namedcounterparameter\s!userpage\c!prefixconnector\!!es, - },{ - conversion = "\namedcounterparameter\s!userpage\c!numberconversion", - conversionset = "\namedcounterparameter\s!userpage\c!numberconversionset", - starter = \!!bs\namedcounterparameter\s!userpage\c!numberstarter\!!es, - stopper = \!!bs\namedcounterparameter\s!userpage\c!numberstopper\!!es, - },{ - viewerprefix = \!!bs\namedcounterparameter\s!userpage\c!viewerprefix\!!es, - state = \!!bs\namedcounterparameter\s!userpage\c!state\!!es, - } - )}} + {\clf_savepagedata + { + prefix {\namedcounterparameter\s!userpage\c!prefix} + separatorset {\namedcounterparameter\s!userpage\c!prefixseparatorset} + conversion {\namedcounterparameter\s!userpage\c!prefixconversion} + conversionset {\namedcounterparameter\s!userpage\c!prefixconversionset} + set {\namedcounterparameter\s!userpage\c!prefixset} + segments {\namedcounterparameter\s!userpage\c!prefixsegments} + connector {\namedcounterparameter\s!userpage\c!prefixconnector} + }{ + conversion {\namedcounterparameter\s!userpage\c!numberconversion} + conversionset {\namedcounterparameter\s!userpage\c!numberconversionset} + starter {\namedcounterparameter\s!userpage\c!numberstarter} + stopper {\namedcounterparameter\s!userpage\c!numberstopper} + }{ + viewerprefix {\namedcounterparameter\s!userpage\c!viewerprefix} + state {\namedcounterparameter\s!userpage\c!state} + }% + \relax} \prependtoks \strc_pagenumbers_page_state_save diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 58ef9625f..aa7acd542 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -53,6 +53,7 @@ local v_auto = variables.auto local context = context local commands = commands +local implement = interfaces.implement local texgetcount = tex.getcount local texsetcount = tex.setcount @@ -1782,24 +1783,27 @@ end) local destinationattributes = { } -local function setinternalreference(prefix,tag,internal,view) -- needs checking +local function setinternalreference(specification) + local internal = specification.internal local destination = unsetvalue if innermethod == v_auto then local t, tn = { }, 0 -- maybe add to current - if tag then + local reference = specification.reference + if reference then + local prefix = specification.prefix if prefix and prefix ~= "" then prefix = prefix .. ":" -- watch out, : here local function action(ref) tn = tn + 1 t[tn] = prefix .. ref end - process_settings(tag,action) + process_settings(reference,action) else local function action(ref) tn = tn + 1 t[tn] = ref end - process_settings(tag,action) + process_settings(reference,action) end end -- ugly .. later we decide to ignore it when we have a real one @@ -1808,7 +1812,7 @@ local function setinternalreference(prefix,tag,internal,view) -- needs checking tn = tn + 1 t[tn] = internal -- when number it's internal end - destination = references.mark(t,nil,nil,view) -- returns an attribute + destination = references.mark(t,nil,nil,specification.view) -- returns an attribute end if internal then -- new destinationattributes[internal] = destination @@ -1823,8 +1827,25 @@ end references.setinternalreference = setinternalreference references.getinternalreference = getinternalreference -commands.setinternalreference = setinternalreference -commands.getinternalreference = getinternalreference + +implement { + name = "setinternalreference", + actions = setinternalreference, + arguments = { + { + { "prefix" }, + { "reference" }, + { "internal", "integer" }, + { "view" } + } + } +} + +-- implement { +-- name = "getinternalreference", +-- actions = { getinternalreference, context }, +-- arguments = "integer", +-- } function references.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here local attr = references.set(kind,prefix,tag,data) and setinternalreference(prefix,tag,nil,view) or unsetvalue diff --git a/tex/context/base/strc-ref.mkvi b/tex/context/base/strc-ref.mkvi index 4d4b07e9c..3c4cf80a5 100644 --- a/tex/context/base/strc-ref.mkvi +++ b/tex/context/base/strc-ref.mkvi @@ -777,7 +777,7 @@ \def\thisissomeinternal#kind#name% only for old time sake {\begingroup - \ctxcommand{setinternalreference("","#kind:#name")}% + \clf_setinternalreference reference {#kind:#name}\relax \hbox attr \destinationattribute\lastdestinationattribute{}% \endgroup} diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua index a8d388a71..4268001fa 100644 --- a/tex/context/base/strc-reg.lua +++ b/tex/context/base/strc-reg.lua @@ -588,7 +588,7 @@ end function commands.storeregister(rawdata) local nofentries = storeregister(rawdata) - setinternalreference(nil,nil,rawdata.references.internal) + setinternalreference { internal = rawdata.references.internal } context(nofentries) end diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index f08a65516..30fc698be 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -293,7 +293,7 @@ userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) } }}% - % \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% in previous + % \clf_setinternalreference internal \nextinternalreference\relax % in previous \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else diff --git a/tex/context/base/strc-sbe.mkiv b/tex/context/base/strc-sbe.mkiv index e6f0282ee..61f6f16b2 100644 --- a/tex/context/base/strc-sbe.mkiv +++ b/tex/context/base/strc-sbe.mkiv @@ -81,7 +81,7 @@ \def\strc_sectionblock_set[#1][#2]% used to set the default {\edef\currentsectionblock{#1}% from now on we assume a value \setupcurrentsectionblock[#2]% - \ctxcommand{setsectionblock("#1", { bookmark = "\sectionblockparameter\c!bookmark" })}} + \clf_setsectionblock{#1}{ bookmark {\sectionblockparameter\c!bookmark} }} \let\currentsectionblock\empty % was \s!unknown @@ -93,7 +93,7 @@ \begingroup \edef\currentsectionblock{#1}% from now on we assume a value \setupcurrentsectionblock[#2]% - \ctxcommand{pushsectionblock("#1", { bookmark = "\sectionblockparameter\c!bookmark" })}% + \clf_pushsectionblock{#1}{ bookmark {\sectionblockparameter\c!bookmark} }% \csname #1true\endcsname % obsolete \setsystemmode\currentsectionblock \the\everybeforesectionblock\relax @@ -102,7 +102,7 @@ \unexpanded\def\stopsectionblock {\showmessage\m!structures2\currentsectionblock \the\everyaftersectionblock\relax - \ctxcommand{popsectionblock()}% + \clf_popsectionblock \endgroup} %D \starttyping diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index 5c539794f..a4084187f 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -175,72 +175,133 @@ \setnextinternalreference \storeinternalreference\currentstructurename\nextinternalreference % \strc_sectioning_set_reference_prefix - \ctxcommand{% todo: combine with next call, adapt marks accordingly - setsectionentry{ - references = { - internal = \nextinternalreference, - block = "\currentsectionblock", - reference = "\currentstructurereference", - referenceprefix = "\currentstructurereferenceprefix", - backreference = "\currentstructurebackreference", - }, - directives = { - resetset = "\structureparameter\c!sectionresetset", - }, - metadata = { - kind = "section", - name = "\currentstructurename", - catcodes = \the\ifx\currentstructurecatcodes\empty\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi, - coding = "\currentstructurecoding", - \ifx\currentstructurecoding\s!xml - xmlroot = "\xmldocument", - \fi - \ifx\currentstructurexmlsetup\empty \else - xmlsetup = "\currentstructurexmlsetup", - \fi - \ifx\currentstructuresaveinlist\v!no - nolist = true, - \fi - \ifx\currentstructureincrementnumber\v!yes - increment = "\currentstructureincrementnumber", - \fi - }, - titledata = { % we can add mark and reference - label = \!!bs\detokenize\expandafter{\currentstructurelabel }\!!es, - title = \!!bs\detokenize\expandafter{\currentstructuretitle }\!!es, - \ifx\currentstructurebookmark\currentstructuretitle \else - bookmark = \!!bs\detokenize\expandafter{\currentstructurebookmark }\!!es, - \fi - \ifx\currentstructuremarking\currentstructuretitle \else - marking = \!!bs\detokenize\expandafter{\currentstructuremarking }\!!es, - \fi - \ifx\currentstructuresaveinlist\v!no \else - \ifx\currentstructurelist\currentstructuretitle \else - list = \!!bs\detokenize\expandafter{\currentstructurelist}\!!es, - \fi - \fi - }, - numberdata = { - % needed ? - block = "\currentsectionblock", - \ifx\currentstructureshownumber\v!no - hidenumber = true, % titles - \fi - % so far - separatorset = "\structureparameter\c!sectionseparatorset", - conversion = "\structureparameter\c!sectionconversion", % for good old times sake - conversionset = "\structureparameter\c!sectionconversionset", - starter = \!!bs\structureparameter\c!sectionstarter\!!es, - stopper = \!!bs\structureparameter\c!sectionstopper\!!es, - set = "\structureparameter\c!sectionset", - segments = "\structureparameter\c!sectionsegments", - ownnumber = "\currentstructureownnumber", - language = "\currentlanguage", % for the moment, needed for bookmarks conversion - }, - userdata = \!!bs\detokenize{#3}\!!es % will be converted to table at the lua end +% \ctxcommand{% todo: combine with next call, adapt marks accordingly +% setsectionentry{ +% references = { +% internal = \nextinternalreference, +% block = "\currentsectionblock", +% reference = "\currentstructurereference", +% referenceprefix = "\currentstructurereferenceprefix", +% backreference = "\currentstructurebackreference", +% }, +% directives = { +% resetset = "\structureparameter\c!sectionresetset", +% }, +% metadata = { +% kind = "section", +% name = "\currentstructurename", +% catcodes = \the\ifx\currentstructurecatcodes\empty\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi, +% coding = "\currentstructurecoding", +% \ifx\currentstructurecoding\s!xml +% xmlroot = "\xmldocument", +% \fi +% \ifx\currentstructurexmlsetup\empty \else +% xmlsetup = "\currentstructurexmlsetup", +% \fi +% \ifx\currentstructuresaveinlist\v!no +% nolist = true, +% \fi +% \ifx\currentstructureincrementnumber\v!yes +% increment = "\currentstructureincrementnumber", +% \fi +% }, +% titledata = { % we can add mark and reference +% label = \!!bs\detokenize\expandafter{\currentstructurelabel }\!!es, +% title = \!!bs\detokenize\expandafter{\currentstructuretitle }\!!es, +% \ifx\currentstructurebookmark\currentstructuretitle \else +% bookmark = \!!bs\detokenize\expandafter{\currentstructurebookmark }\!!es, +% \fi +% \ifx\currentstructuremarking\currentstructuretitle \else +% marking = \!!bs\detokenize\expandafter{\currentstructuremarking }\!!es, +% \fi +% \ifx\currentstructuresaveinlist\v!no \else +% \ifx\currentstructurelist\currentstructuretitle \else +% list = \!!bs\detokenize\expandafter{\currentstructurelist}\!!es, +% \fi +% \fi +% }, +% numberdata = { +% % needed ? +% block = "\currentsectionblock", +% \ifx\currentstructureshownumber\v!no +% hidenumber = true, % titles +% \fi +% % so far +% separatorset = "\structureparameter\c!sectionseparatorset", +% conversion = "\structureparameter\c!sectionconversion", % for good old times sake +% conversionset = "\structureparameter\c!sectionconversionset", +% starter = \!!bs\structureparameter\c!sectionstarter\!!es, +% stopper = \!!bs\structureparameter\c!sectionstopper\!!es, +% set = "\structureparameter\c!sectionset", +% segments = "\structureparameter\c!sectionsegments", +% ownnumber = "\currentstructureownnumber", +% language = "\currentlanguage", % for the moment, needed for bookmarks conversion +% }, +% userdata = \!!bs\detokenize{#3}\!!es % will be converted to table at the lua end +% } +% }% + \clf_setsectionentry + references { + internal \nextinternalreference\space + block {\currentsectionblock} + referenceprefix {\currentstructurereferenceprefix} + reference {\currentstructurereference} + backreference {\currentstructurebackreference} } - }% - \xdef\currentstructurelistnumber{\ctxcommand{currentsectiontolist()}}% + directives { + resetset {\structureparameter\c!sectionresetset} + } + metadata { + kind {section} + name {\currentstructurename} + catcodes \ifx\currentstructurecatcodes\empty\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi\space + coding {\currentstructurecoding} + \ifx\currentstructurecoding\s!xml + xmlroot {\xmldocument} + \fi + \ifx\currentstructurexmlsetup\empty \else + xmlsetup {\currentstructurexmlsetup} + \fi + \ifx\currentstructuresaveinlist\v!no + nolist \space true\space + \fi + \ifx\currentstructureincrementnumber\v!yes + increment {\currentstructureincrementnumber} + \fi + } + titledata { + label {\detokenize\expandafter{\currentstructurelabel}} + title {\detokenize\expandafter{\currentstructuretitle}} + \ifx\currentstructurebookmark\currentstructuretitle \else + bookmark {\detokenize\expandafter{\currentstructurebookmark}} + \fi + \ifx\currentstructuremarking\currentstructuretitle \else + marking {\detokenize\expandafter{\currentstructuremarking}} + \fi + \ifx\currentstructuresaveinlist\v!no \else + \ifx\currentstructurelist\currentstructuretitle \else + list {\detokenize\expandafter{\currentstructurelist}} + \fi + \fi + } + numberdata { + block {\currentsectionblock} + \ifx\currentstructureshownumber\v!no + hidenumber \space true\space + \fi + separatorset {\structureparameter\c!sectionseparatorset} + conversionset {\structureparameter\c!sectionconversionset} + conversion {\structureparameter\c!sectionconversion} + starter {\structureparameter\c!sectionstarter} + stopper {\structureparameter\c!sectionstopper} + set {\structureparameter\c!sectionset} + segments {\structureparameter\c!sectionsegments} + ownnumber {\currentstructureownnumber} + language {\currentlanguage}% for the moment, needed for bookmarks conversion + } + userdata {\detokenize{#3}}% will be converted to table at the lua end + \relax + \xdef\currentstructurelistnumber{\clf_currentsectiontolist}% % \currentstructuresynchronize has to be called someplace, since it introduces a node \setstructuresynchronization\currentstructurelistnumber \endgroup} @@ -267,16 +328,15 @@ % todo: #1 => "#1" ... adapt lua code for name and number -\def\structurenumber {\ctxcommand{structurenumber()}} -\def\structuretitle {\ctxcommand{structuretitle()}} -\def\structurevariable #1{\ctxcommand{structurevariable("#1")}} -\def\structureuservariable #1{\ctxcommand{structureuservariable("#1")}} -\def\structurecatcodedget #1{\ctxcommand{structurecatcodedget("#1")}} % bad name -\def\structuregivencatcodedget #1#2{\ctxcommand{structuregivencatcodedget("#1",\number#2)}} % bad name -\def\structureautocatcodedget #1#2{\ctxcommand{structureautocatcodedget ("#1","#2")}} - -\def\namedstructurevariable #1#2{\ctxcommand{namedstructurevariable ("#1","#2")}} -\def\namedstructureuservariable#1#2{\ctxcommand{namedstructureuservariable("#1","#2")}} +\def\structurenumber {\clf_structurenumber} +\def\structuretitle {\clf_structuretitle} +\def\structurevariable #1{\clf_structurevariable {#1}} +\def\structureuservariable #1{\clf_structureuservariable {#1}} +\def\structurecatcodedget #1{\clf_structurecatcodedget {#1}} % bad name +\def\structuregivencatcodedget #1#2{\clf_structuregivencatcodedget {#1}#2 } % bad name +\def\structureautocatcodedget #1#2{\clf_structureautocatcodedget {#1}{#2}} +\def\namedstructurevariable #1#2{\clf_namedstructurevariable {#1}{#2}} +\def\namedstructureuservariable#1#2{\clf_namedstructureuservariable{#1}{#2}} % compatibility issue: % @@ -306,14 +366,14 @@ \newconditional\c_strc_rendering_continuous % not used (mkii ?) -\def\setstructurelevel #1#2{\ctxcommand{setsectionlevel("#1","#2")}} % name, level|parent -\def\getstructurelevel #1{\ctxcommand{getcurrentsectionlevel("#1")}}% name -\def\setstructurenumber #1#2{\ctxcommand{setsectionnumber(#1,"#2")}} % level, number (+/-) -\def\getstructurenumber #1{\ctxcommand{getsectionnumber(#1)}} % level -\def\getsomestructurenumber #1#2{\ctxcommand{getsectionnumber(#1,"#2")}} % level, what -\def\getfullstructurenumber #1{\ctxcommand{getfullsectionnumber(#1)}} % level -\def\getsomefullstructurenumber#1#2{\ctxcommand{getfullsectionnumber(#1,"#2")}} -\def\getspecificstructuretitle #1{\ctxcommand{getstructuredata("#1","titledata.title",nil,"\headparameter\s!catcodes")}}% +\def\setstructurelevel #1#2{\clf_setstructurelevel {#1}{#2}} % name, level|parent +\def\getstructurelevel #1{\clf_getstructurelevel {#1}} % name +\def\setstructurenumber #1#2{\clf_setstructurenumber #1{#2}} % level, number (+/-) +\def\getstructurenumber #1{\clf_getstructurenumber #1 } % level +\def\getsomestructurenumber #1#2{\clf_getsomestructurenumber #1{#2}} % level, what +\def\getfullstructurenumber #1{\clf_getfullstructurenumber #1 } % level +\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}} % level, what +\def\getspecificstructuretitle #1{\clf_getspecificstructuretitle {#1}{\headparameter\s!catcodes}} % will be: % @@ -447,13 +507,12 @@ \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}% \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}% \edef\currentsectionlevel {\sectionlevel \currentsectionheadsection}% - \ctxcommand{registersection("\currenthead",{ - coupling = "\currentsectionheadcoupling", - section = "\currentsectionheadsection", - level = \currentsectionlevel, - % for statistical purposes: - parent = "\currentheadparent" - })}% + \clf_registersection {\currenthead} { + coupling {\currentsectionheadcoupling} + section {\currentsectionheadsection} + level \currentsectionlevel + parent {\currentheadparent} + }% \endgroup \to \everyredefinehead @@ -601,8 +660,8 @@ % head -> head -\def\sectionheadmarkingtitle #1#2{\ctxcommand{markingtitle("#1","#2")}} -\def\sectionheadmarkingnumber#1#2{\ctxcommand{markingnumber("#1","#2")}} +\def\sectionheadmarkingtitle #1#2{\clf_markingtitle {#1}{#2}} +\def\sectionheadmarkingnumber#1#2{\clf_markingnumber{#1}{#2}} \def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling} \def\sectionheadsection #1{\namedheadparameter{#1}\c!section} @@ -786,7 +845,7 @@ \unexpanded\def\placeheadtext {\dosingleempty\strc_sectioning_place_head_text } % use with care \unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care -\unexpanded\def\strc_sectioning_report{\ctxcommand{reportstructure()}} +\unexpanded\def\strc_sectioning_report{\clf_reportstructure} \ifdefined\strc_rendering_initialize_style_and_color \else @@ -1067,8 +1126,8 @@ #1% \fi} -\def\currentsectioncountervalue {\ctxcommand{depthnumber(\thenamedheadlevel\currenthead)}} -\def\previoussectioncountervalue{\ctxcommand{depthnumber(\thenamedheadlevel\currenthead-1)}} +\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax} +\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax} \def\strc_sectioning_handle_page_nop {\edef\p_continue{\headparameter\c!continue}% @@ -1170,7 +1229,7 @@ \unexpanded\def\strc_sectioning_initialize_autolevel {\ifconditional\c_strc_sectioning_auto_levels - \ctxcommand{autonextstructurelevel(\number\currentheadlevel)}% + \clf_autonextstructurelevel\currentheadlevel\relax \global\setfalse\c_strc_sectioning_auto_levels \fi} @@ -1178,7 +1237,7 @@ {\global\settrue\c_strc_sectioning_auto_levels} \unexpanded\def\finalizeautostructurelevels - {\ctxcommand{autofinishstructurelevels()}} + {\clf_autofinishstructurelevels} \unexpanded\def\finalizeautostructurelevel {\dostoptagged diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua index 2ca428455..1864dc84a 100644 --- a/tex/context/base/strc-syn.lua +++ b/tex/context/base/strc-syn.lua @@ -13,6 +13,8 @@ local allocate = utilities.storage.allocate -- interface to tex end local context = context +local implement = interfaces.implement + local sorters = sorters local structures = structures @@ -204,8 +206,46 @@ function synonyms.process(class,options) end end -commands.registersynonym = synonyms.register -commands.registerusedsynonym = synonyms.registerused -commands.synonymmeaning = synonyms.meaning -commands.synonymname = synonyms.synonym -commands.processsynonyms = synonyms.process +-- todo: local higher up + +implement { name = "registerusedsynonym", actions = synonyms.registerused, arguments = { "string", "string" } } +implement { name = "synonymmeaning", actions = synonyms.meaning, arguments = { "string", "string" } } +implement { name = "synonymname", actions = synonyms.synonym, arguments = { "string", "string" } } + +implement { + name = "registersynonym", + actions = synonyms.register, + arguments = { + "string", + "string", + { + { "metadata", { + { "catcodes", "integer" }, + { "coding" }, + { "xmlroot" } + } + }, + { + "definition", { + { "tag" }, + { "synonym" }, + { "meaning" }, + { "used", "boolean" } + } + } + } + } +} + +implement { + name = "processsynonyms", + actions = synonyms.process, + arguments = { + "string", + { + { "criterium" }, + { "language" }, + { "method" } + } + } +} diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv index b69139afb..bd5cd4ca8 100644 --- a/tex/context/base/strc-syn.mkiv +++ b/tex/context/base/strc-syn.mkiv @@ -197,19 +197,25 @@ \edef\currentsynonymexpansion{\simplelistparameter\c!expansion}% \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}% \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}% - \ctxcommand{registersynonym("\currentsynonym", "synonym", { - metadata = { - catcodes = \the\catcodetable, - coding = "\currentsynonymcoding", - xmlroot = \ifx\currentsynonymcoding\s!xml "\xmldocument" \else nil \fi, - }, - definition = { - tag = "\currentsynonymtag", - synonym = \!!bs\currentsynonymtext\!!es, - meaning = \!!bs\currentsynonymmeaning\!!es, - used = false, - } - })}% + \clf_registersynonym + {\currentsynonym}% + {synonym}% + {% + metadata {% + catcodes \catcodetable + coding {\currentsynonymcoding}% + \ifx\currentsynonymcoding\s!xml + xmlroot {\xmldocument}% + \fi + }% + definition {% + tag {\currentsynonymtag}% + synonym {\currentsynonymtext}% + meaning {\currentsynonymmeaning}% + used false + }% + }% + \relax \doif{#1}\v!yes{\setuxvalue\currentsynonymtag{\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}}% \fi \endgroup} @@ -218,13 +224,13 @@ {\dodoubleargument\strc_synonyms_register} \def\strc_synonyms_register[#1][#2]% - {\ctxcommand{registerusedsynonym("#1","#2")}} + {\clf_registerusedsynonym{#1}{#2}} \unexpanded\def\strc_synonyms_insert_meaning#1#2% name tag {\begingroup \def\currentsimplelist{#1}% \usesimpleliststyleandcolor\c!textstyle\c!textcolor - \simplelistparameter\c!textcommand{\ctxcommand{synonymmeaning("#1","#2")}}% + \simplelistparameter\c!textcommand{\clf_synonymmeaning{#1}{#2}}% \endgroup} \unexpanded\def\strc_synonyms_insert#1#2% name tag @@ -235,7 +241,7 @@ \dostarttaggedchained\t!synonym\currentsynonym\??simplelist \dotagsynonym \usesimpleliststyleandcolor\c!synonymstyle\c!synonymcolor - \simplelistparameter\c!synonymcommand{\ctxcommand{synonymname("#1","#2")}}% + \simplelistparameter\c!synonymcommand{\clf_synonymname{#1}{#2}}% \dostoptagged \normalexpanded{\endgroup\simplelistparameter\c!next}} @@ -249,11 +255,14 @@ \setupcurrentsimplelist[#2]% \let\synonymentry\strc_synonym_normal \startpacked - \ctxcommand{processsynonyms('#1',{ - criterium = "\simplelistparameter\c!criterium", - language = "\simplelistparameter\s!language", - method = "\simplelistparameter\c!method", - })}% + \clf_processsynonyms + {#1}% + {% + criterium {\simplelistparameter\c!criterium}% + language {\simplelistparameter\s!language}% + method {\simplelistparameter\c!method}% + }% + \relax \stoppacked \endgroup} @@ -338,18 +347,24 @@ \else \edef\currentsortingexpansion{\simplelistparameter\c!expansion}% \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}% - \ctxcommand{registersynonym("\currentsorting", "sorting", { - metadata = { - catcodes = \the\catcodetable, - coding = "\currentsortingcoding", - xmlroot = \ifx\currentsortingcoding\s!xml "\xmldocument" \else nil \fi, - }, - definition = { - tag = "\currentsortingtag", - synonym = \!!bs\currentsortingtext\!!es, - % used = false, - } - })}% + \clf_registersynonym + {\currentsorting}% + {sorting}% + {% + metadata {% + catcodes \catcodetable + coding {\currentsortingcoding}% + \ifx\currentsortingcoding\s!xml + xmlroot {\xmldocument}% + \fi + }% + definition {% + tag {\currentsortingtag}% + synonym {\currentsortingtext}% + % used false + }% + }% + \relax \doif{#1}\v!yes{\setuxvalue\currentsortingtag{\strc_sorting_insert{\currentsorting}{\currentsortingtag}}}% \fi \endgroup} @@ -363,7 +378,7 @@ \dostarttaggedchained\t!sorting\currentsorting\??simplelist \dotagsorting \usesimpleliststyleandcolor\c!style\c!color - \ctxcommand{synonymname("#1","#2")}% + \clf_synonymname{#1}{#2}% \dostoptagged \normalexpanded{\endgroup\simplelistparameter\c!next}} @@ -371,7 +386,7 @@ {\dodoubleargument\strc_sorting_register} \def\strc_sorting_register[#1][#2]% - {\ctxcommand{registerusedsynonym("#1","#2")}} + {\clf_registerusedsynonym{#1}{#2}} % before after % @@ -392,11 +407,14 @@ \let\synonymentry\strc_sorting_command \fi \startpacked - \ctxcommand{processsynonyms('#1',{ - criterium = "\simplelistparameter\c!criterium", - language = "\simplelistparameter\s!language", - method = "\simplelistparameter\c!method", - })}% + \clf_processsynonyms + {#1}% + {% + criterium {\simplelistparameter\c!criterium}% + language {\simplelistparameter\s!language}% + method {\simplelistparameter\c!method}% + }% + \relax \stoppacked \endgroup} diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua index 7b235957b..a20375448 100644 --- a/tex/context/base/strc-tag.lua +++ b/tex/context/base/strc-tag.lua @@ -24,7 +24,9 @@ local trace_tags = false trackers.register("structures.tags", function(v) trace local report_tags = logs.reporter("structure","tags") -local attributes, structures = attributes, structures +local attributes = attributes +local structures = structures +local implement = interfaces.implement local a_tagged = attributes.private('tagged') @@ -379,10 +381,10 @@ end local strip = C((1-S(">"))^1) -commands.getelementtag = function() +function tags.elementtag() local fulltag = chain[stacksize] if fulltag then - context(lpegmatch(strip,fulltag)) + return lpegmatch(strip,fulltag) end end @@ -410,8 +412,6 @@ function tags.setuserproperties(tag,list) end end -commands.setelementuserproperties = tags.setuserproperties - function tags.handler(head) -- we need a dummy return head, false end @@ -433,7 +433,72 @@ directives.register("backend.addtags", function(v) end end) -commands.starttag = tags.start -commands.stoptag = tags.stop -commands.settagproperty = tags.setproperty -commands.settagaspect = tags.setaspect +-- interface + +local starttag = tags.start + +implement { + name = "starttag", + actions = starttag, + arguments = { "string" } +} + +implement { + name = "stoptag", + actions = tags.stop, +} + +implement { + name = "starttag_u", + scope = "private", + actions = function(tag,userdata) starttag(tag,{ userdata = userdata }) end, + arguments = { "string", "string" } +} + +implement { + name = "starttag_d", + scope = "private", + actions = function(tag,detail) starttag(tag,{ detail = detail }) end, + arguments = { "string", "string" } +} + +implement { + name = "starttag_c", + scope = "private", + actions = function(tag,detail,parents) starttag(tag,{ detail = detail, parents = parents }) end, + arguments = { "string", "string", "string" } +} + +implement { name = "settagaspect", actions = tags.setaspect, arguments = { "string", "string" } } + +implement { name = "settagproperty", actions = tags.setproperty, arguments = { "string", "string", "string" } } +implement { name = "settagproperty_b", actions = tags.setproperty, arguments = { "string", "'backend'", "string" }, scope = "private" } +implement { name = "settagproperty_n", actions = tags.setproperty, arguments = { "string", "'nature'", "string" }, scope = "private" } + +implement { name = "getelementtag", actions = { tags.elementtag, context } } + +implement { + name = "setelementuserproperties_o", + scope = "private", + actions = tags.setuserproperties, + arguments = "string" +} + +implement { + name = "setelementuserproperties_t", + scope = "private", + actions = tags.setuserproperties, + arguments = { "string", "string" } +} + +implement { + name = "doifinelementelse", + actions = { structures.atlocation, commands.testcase }, + arguments = "string", +} + +implement { + name = "settaggedmetadata", + actions = structures.tags.registermetadata, + arguments = "string" +} diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv index e1198af4d..95a776e35 100644 --- a/tex/context/base/strc-tag.mkiv +++ b/tex/context/base/strc-tag.mkiv @@ -167,11 +167,11 @@ \unexpanded\def\setelementbackendtag{\dodoubleargument\strc_tags_set_backend} \unexpanded\def\setelementnature {\dodoubleargument\strc_tags_set_nature} -\def\strc_tags_set_backend[#1][#2]{\ctxcommand{settagproperty("#1","backend","#2")}} % todo: ignore when no export -\def\strc_tags_set_nature [#1][#2]{\ctxcommand{settagproperty("#1","nature", "#2")}} % todo: ignore when no export +\def\strc_tags_set_backend[#1][#2]{\clf_settagproperty_b{#1}{#2}} % todo: ignore when no export +\def\strc_tags_set_nature [#1][#2]{\clf_settagproperty_n{#1}{#2}} % todo: ignore when no export \unexpanded\def\strc_tags_set_aspect_nop#1#2{} -\unexpanded\def\strc_tags_set_aspect_yes#1#2{\ctxcommand{settagaspect("#1","#2")}} % todo: ignore when no export +\unexpanded\def\strc_tags_set_aspect_yes#1#2{\clf_settagaspect{#1}{#2}} % todo: ignore when no export / also \let \installcorenamespace{tagging} @@ -206,10 +206,10 @@ % which might be more efficient then ... okay, we now cannot overload but who cares \unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]% - {\ctxcommand{starttag("#1",{userdata=\!!bs#2\!!es})}} + {\clf_starttag_u{#1}{#2}} \unexpanded\def\strc_tags_element_stop_yes - {\ctxcommand{stoptag()}} + {\clf_stoptag} \unexpanded\def\strc_tags_element_start_nop_indeed[#1][#2]% {} @@ -258,10 +258,10 @@ \expandafter\strc_tags_stop_yes \fi} -\def\strc_tags_start_yes_no_detail #1{\ctxcommand{starttag("#1")}} -\def\strc_tags_start_yes_detail #1#2{\ctxcommand{starttag("#1",{detail="#2"})}} -\def\strc_tags_start_yes_chained #1#2#3{\ctxcommand{starttag("#1",{detail="#2",parents="\getcurrentparentchain#3{#2}"})}} -\def\strc_tags_stop_yes {\ctxcommand{stoptag()}} +\def\strc_tags_start_yes_no_detail #1{\clf_starttag{#1}} +\def\strc_tags_start_yes_detail #1#2{\clf_starttag_d{#1}{#2}} +\def\strc_tags_start_yes_chained #1#2#3{\clf_starttag_c{#1}{#2}{\getcurrentparentchain#3{#2}}} +\def\strc_tags_stop_yes {\clf_stoptag} \let\strc_tags_start_nop_no_detail\gobbleoneargument \let\strc_tags_start_nop_detail \gobbletwoarguments @@ -292,7 +292,7 @@ % for luigi (beware: fully expandable): -\def\strc_tags_get_element_tag_yes{\ctxcommand{getelementtag()}} +\def\strc_tags_get_element_tag_yes{\clf_getelementtag} \let\strc_tags_get_element_tag_nop\donothing \unexpanded\def\strc_tags_setup_element_user_properties_yes @@ -311,8 +311,8 @@ \fi\fi} \def\strc_tags_setup_element_user_properties_indeed_nop[#1][#2]{} -\def\strc_tags_setup_element_user_properties_indeed_one[#1][#2]{\ctxcommand{setelementuserproperties(\!!bs#1\!!es)}} -\def\strc_tags_setup_element_user_properties_indeed_two[#1][#2]{\ctxcommand{setelementuserproperties("#1",\!!bs#2\!!es)}} +\def\strc_tags_setup_element_user_properties_indeed_one[#1][#2]{\clf_setelementuserproperties_o{#1}} +\def\strc_tags_setup_element_user_properties_indeed_two[#1][#2]{\clf_setelementuserproperties_u{#1}{#2}} \unexpanded\def\strc_tags_enable_properties {\let\getelementtag \strc_tags_get_element_tag_yes @@ -448,7 +448,7 @@ % \doifinelementelse{division:*-structure:chapter} {yes} {no} \unexpanded\def\doifinelementelse#1% - {\ctxcommand{testcase(structures.atlocation("#1"))}} + {\clf_doifinelementelse{#1}} \unexpanded\def\taggedlabeltexts#1#2#3% experimental: label, numberdetail, numbercontent {\begingroup @@ -494,7 +494,7 @@ %D \stoptyping \unexpanded\def\settaggedmetadata[#1]% - {\ctxlua{structures.tags.registermetadata(\!!bs#1\!!es)}} + {\clf_registermetadata{#1}} %D An overload: diff --git a/tex/context/base/supp-ran.lua b/tex/context/base/supp-ran.lua index 7997db8f6..1d34393fa 100644 --- a/tex/context/base/supp-ran.lua +++ b/tex/context/base/supp-ran.lua @@ -10,12 +10,16 @@ if not modules then modules = { } end modules ['supp-ran'] = { local report_system = logs.reporter("system","randomizer") -local math = math -local context, commands = context, commands +local math = math +local context = context +local implement = interfaces.implement -local random, randomseed, round, seed, last = math.random, math.randomseed, math.round, false, 1 - -local maxcount = 2^30-1 -- 1073741823 +local random = math.random +local randomseed = math.randomseed +local round = math.round +local seed = false +local last = 1 +local maxcount = 2^30-1 -- 1073741823 local function setrandomseedi(n,comment) if not n then @@ -34,28 +38,23 @@ end math.setrandomseedi = setrandomseedi -function commands.getrandomcounta(min,max) +local function getrandomnumber(min,max) last = random(min,max) - context(last) -end - -function commands.getrandomcountb(min,max) - last = random(min,max)/65536 - context(last) + return last end -function commands.setrandomseed(n) +local function setrandomseed(n) last = n setrandomseedi(n) end -function commands.getrandomseed(n) - context(last) +local function getrandomseed() + return last end -- maybe stack -function commands.freezerandomseed(n) +local function freezerandomseed(n) if seed == false or seed == nil then seed = last setrandomseedi(seed,"freeze",seed) @@ -65,9 +64,18 @@ function commands.freezerandomseed(n) end end -function commands.defrostrandomseed() +local function defrostrandomseed() if seed ~= false then setrandomseedi(seed,"defrost",seed) -- was last (bug) seed = false end end + +implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } } +implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } } +implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } } +implement { name = "setrandomseed", actions = { setrandomseed }, arguments = { "integer" } } +implement { name = "getrandomseed", actions = { getrandomseed, context } } +implement { name = "freezerandomseed", actions = { freezerandomseed } } +implement { name = "defrostrandomseed", actions = { defrostrandomseed } } + diff --git a/tex/context/base/supp-ran.mkiv b/tex/context/base/supp-ran.mkiv index f5466a0e1..e49173717 100644 --- a/tex/context/base/supp-ran.mkiv +++ b/tex/context/base/supp-ran.mkiv @@ -18,13 +18,15 @@ \registerctxluafile{supp-ran}{1.001} -\unexpanded\def\getrandomcount #1#2#3{#1=\ctxcommand{getrandomcounta(\number#2,\number#3)}\relax} -\unexpanded\def\getrandomdimen #1#2#3{#1=\ctxcommand{getrandomcounta(\number\dimexpr#2,\number\dimexpr#3)}\scaledpoint\relax} -\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\ctxcommand{getrandomcounta(\number#2,\number#3)}}} -\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\ctxcommand{getrandomcountb(\number\dimexpr#2\points,\number\dimexpr#3\points)}}} -\unexpanded\def\setrandomseed #1{\ctxcommand{setrandomseed(\number#1)}} -\unexpanded\def\getrandomseed #1{\edef#1{\ctxcommand{getrandomseed()}}} -\unexpanded\def\freezerandomseed {\ctxcommand{freezerandomseed()}} -\unexpanded\def\defrostrandomseed {\ctxcommand{defrostrandomseed()}} +\unprotect -\endinput +\unexpanded\def\getrandomcount #1#2#3{#1=\clf_getrandomnumber#2 #3\relax} +\unexpanded\def\getrandomdimen #1#2#3{#1=\clf_getrandomdimen#2 #3 \scaledpoint\relax} +\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\clf_getrandomnumber#2 #3}} +\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat#2 #3}} +\unexpanded\def\setrandomseed #1{\clf_setrandomseed#1\relax} +\unexpanded\def\getrandomseed #1{\edef#1{\clf_getrandomseed}} +\unexpanded\def\freezerandomseed {\clf_freezerandomseed} +\unexpanded\def\defrostrandomseed {\clf_defrostrandomseed} + +\protect \endinput diff --git a/tex/context/base/x-asciimath.lua b/tex/context/base/x-asciimath.lua index 20cbd14e4..7defd3387 100644 --- a/tex/context/base/x-asciimath.lua +++ b/tex/context/base/x-asciimath.lua @@ -1018,7 +1018,7 @@ local a_parser = Ct { "tokenizer", + p_reserved + p_entity -- + p_utf - p_close - p_right - + p_utf - p_right + + (p_utf - p_right) )^1, } @@ -1590,7 +1590,7 @@ local p = ( local function invalidtex(str) n = 0 - local result = lpegmatch(p,str) + lpegmatch(p,str) if n == 0 then return false elseif n < 0 then @@ -1640,7 +1640,7 @@ local function register(s,cleanedup,collected,shortname) local texcoded = convert(s) local message = invalidtex(texcoded) if message then - report_asciimath("%s: %s",message,s) + report_asciimath("%s: %s : %s",message,s,texcoded) end collected[c] = { count = 1, @@ -1735,7 +1735,7 @@ local function convert(str) else local message = invalidtex(texcoded) if message then - report_asciimath("%s: %s",message,str) + report_asciimath("%s: %s : %s",message,str,texcoded) ctx_type(formatters["<%s>"](message)) else ctx_mathematics(texcoded) @@ -1761,6 +1761,8 @@ if not context then -- convert("10000,00001") -- convert("4/18*100text(%)~~22,2") +-- convert("4/18*100text(%)≈22,2") +convert("62541/(197,6)≈316,05") -- convert([[sum x]]) -- convert([[sum^(1)_(2) x]]) diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 0c307c7bc..9395a157c 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 : 03/25/15 22:13:54 +-- merge date : 03/26/15 19:19:12 do -- begin closure to overcome local limits and interference @@ -662,46 +662,40 @@ function lpeg.append(list,pp,delayed,checked) end local p_false=P(false) local p_true=P(true) -local function make(t,hash) - local p=p_false - local keys=sortedkeys(t) - local function making(t,w) +local function make(t) + local function making(t) local p=p_false local keys=sortedkeys(t) + local okay=t[""] for i=1,#keys do local k=keys[i] - local v=t[k] - if w then + if k~="" then + local v=t[k] if v==true then p=p+P(k)*p_true + elseif v==false then + elseif okay then + p=p+P(k)*(making(v)+p_true) else - p=p+P(k)*(making(v,w)+p_true) - end - else - if v==true then - p=p+P(k) - else - p=p+P(k)*making(v,w) + p=p+P(k)*making(v) end end end return p end + local p=p_false + local keys=sortedkeys(t) for i=1,#keys do local k=keys[i] - local v=t[k] - local h=hash[v] - if h then + if k~="" then + local v=t[k] if v==true then p=p+P(k)*p_true + elseif v==false then + elseif v[""] then + p=p+P(k)*(making(v)+p_true) else - p=p+P(k)*(making(v,true)+p_true) - end - else - if v==true then - p=p+P(k) - else - p=p+P(k)*making(v,false) + p=p+P(k)*making(v) end end end @@ -709,58 +703,76 @@ local function make(t,hash) end function lpeg.utfchartabletopattern(list) local tree={} - local hash local n=#list if n==0 then - hash=list for s in next,list do local t=tree local p,pk for c in gmatch(s,".") do if t==true then - t={ [c]=true } + t={ [c]=true,[""]=true } + p[pk]=t + p=t + t=false + elseif t==false then + t={ [c]=false } p[pk]=t p=t - t=true + t=false else local tc=t[c] if not tc then - tc=true - t[c]=tc + tc=false + t[c]=false end p=t t=tc end pk=c end + if t==false then + p[pk]=true + elseif t==true then + else + t[""]=true + end end else - hash={} for i=1,n do - local t=tree local s=list[i] + local t=tree local p,pk for c in gmatch(s,".") do if t==true then - t={ [c]=true } + t={ [c]=true,[""]=true } + p[pk]=t + p=t + t=false + elseif t==false then + t={ [c]=false } p[pk]=t p=t - t=true + t=false else local tc=t[c] if not tc then - tc=true - t[c]=true + tc=false + t[c]=false end p=t t=tc end pk=c end - hash[s]=true + if t==false then + p[pk]=true + elseif t==true then + else + t[""]=true + end end end - return make(tree,hash) + return make(tree) end patterns.containseol=lpeg.finder(eol) local function nextstep(n,step,result) -- cgit v1.2.3