diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/anch-pos.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/anch-pos.lua | 361 |
1 files changed, 252 insertions, 109 deletions
diff --git a/Master/texmf-dist/tex/context/base/anch-pos.lua b/Master/texmf-dist/tex/context/base/anch-pos.lua index c2b62bae7d4..77e36e85ece 100644 --- a/Master/texmf-dist/tex/context/base/anch-pos.lua +++ b/Master/texmf-dist/tex/context/base/anch-pos.lua @@ -21,8 +21,6 @@ more efficient.</p> -- maybe replace texsp by our own converter (stay at the lua end) -- eventually mp will have large numbers so we can use sp there too -local commands, context = commands, context - local tostring, next, rawget, setmetatable = tostring, next, rawget, setmetatable local sort = table.sort local format, gmatch, match = string.format, string.gmatch, string.match @@ -30,12 +28,24 @@ local rawget = rawget local lpegmatch = lpeg.match local insert, remove = table.insert, table.remove local allocate, mark = utilities.storage.allocate, utilities.storage.mark -local texsp = tex.sp ------ texsp = string.todimen -- because we cache this is much faster but no rounding +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 + +local tex = tex local texgetcount = tex.getcount local texsetcount = tex.setcount local texget = tex.get +local texsp = tex.sp +----- texsp = string.todimen -- because we cache this is much faster but no rounding local pdf = pdf -- h and v are variables @@ -118,11 +128,28 @@ local nofusedregions = 0 local nofmissingregions = 0 local nofregular = 0 +jobpositions.used = false + -- todo: register subsets and count them indepently local function initializer() tobesaved = jobpositions.tobesaved collected = jobpositions.collected + -- add sparse regions + local pages = structures.pages.collected + if pages then + local last = nil + for p=1,#pages do + local region = "page:" .. p + local data = collected[region] + if data then + last = data + last.p = nil -- no need for a page + elseif last then + collected[region] = last + end + end + end -- enhance regions with paragraphs for tag, data in next, collected do local region = data.r @@ -162,6 +189,7 @@ local function initializer() end -- so, we can be sparse and don't need 'or 0' code end + jobpositions.used = next(collected) end job.register('job.positions.collected', tobesaved, initializer) @@ -259,9 +287,15 @@ local function enhance(data) return data end -local function set(name,index,val) +-- analyze some files (with lots if margindata) and then when one key optionally +-- use that one instead of a table (so, a 3rd / 4th argument: key, e.g. "x") + +local function set(name,index,val) -- ,key local data = enhance(val or index) if val then +-- if data[key] and not next(next(data)) then +-- data = data[key] +-- end container = tobesaved[name] if not container then tobesaved[name] = { @@ -289,7 +323,26 @@ 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) @@ -318,18 +371,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 @@ -355,7 +416,7 @@ function jobpositions.e_region(correct) region = regions[#regions] end -function jobpositions.markregionbox(n,tag,correct) +local function setregionbox(n,tag) if not tag or tag == "" then nofregions = nofregions + 1 tag = f_region(nofregions) @@ -372,6 +433,11 @@ function jobpositions.markregionbox(n,tag,correct) h = h ~= 0 and h or nil, d = d ~= 0 and d or nil, } + return tag, box +end + +local function markregionbox(n,tag,correct) + local tag, box = setregionbox(n,tag) local push = new_latelua(f_b_region(tag)) local pop = new_latelua(f_e_region(tostring(correct))) -- todo: check if tostring is needed with formatter -- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end @@ -389,18 +455,22 @@ function jobpositions.markregionbox(n,tag,correct) setfield(box,"list",push) end +jobpositions.markregionbox = markregionbox +jobpositions.setregionbox = setregionbox + 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") @@ -443,7 +513,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, @@ -455,38 +526,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, @@ -532,7 +623,17 @@ end function jobpositions.region(id) local jpi = collected[id] - return jpi and jpi.r or false + if jpi then + local r = jpi.r + if r then + return r + end + local p = jpi.p + if p then + return "page:" .. p + end + end + return false end function jobpositions.column(id) @@ -738,11 +839,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 @@ -753,8 +866,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 @@ -765,8 +878,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 @@ -777,8 +890,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 @@ -789,8 +902,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 @@ -801,8 +914,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 @@ -813,8 +926,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, @@ -825,8 +938,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, @@ -837,8 +950,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, @@ -849,8 +962,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, @@ -861,8 +974,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, @@ -892,10 +1005,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 @@ -906,25 +1021,28 @@ 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 + if c and c ~= true then context(c) return end end - context(c) -- number + context('0') -- okay ? 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 + if r and r ~= true then context(r) - return + end + local p = jpi.p + if p then + context("page:" .. p) end end end @@ -949,29 +1067,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 @@ -979,8 +1100,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 @@ -996,59 +1119,79 @@ 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.doifelseposition = 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.doifelsepositiononpage = 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.doifelseoverlapping = function() -- one two + doifelse(overlapping(scanstring(),scanstring())) end -function commands.doifpositionsonsamepageelse(list,page) - doifelse(onsamepage(list)) +scanners.doifelsepositionsonsamepage = function() -- list + doifelse(onsamepage(scanstring())) end -function commands.doifpositionsonthispageelse(list) - doifelse(onsamepage(list,tostring(texgetcount("realpageno")))) +scanners.doifelsepositionsonthispage = 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.setregionbox = function() -- box + setregionbox(scaninteger()) +end + +scanners.markregionboxtagged = function() -- box tag + markregionbox(scaninteger(),scanstring()) +end + +scanners.setregionboxtagged = function() -- box tag + setregionbox(scaninteger(),scanstring()) +end + +scanners.markregionboxcorrected = function() -- box tag + markregionbox(scaninteger(),scanstring(),true) +end -- statistics (at least for the moment, when testing) |