summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/page-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/page-ini.lua')
-rw-r--r--tex/context/base/mkiv/page-ini.lua171
1 files changed, 134 insertions, 37 deletions
diff --git a/tex/context/base/mkiv/page-ini.lua b/tex/context/base/mkiv/page-ini.lua
index 924e01b2a..bcabc0d6b 100644
--- a/tex/context/base/mkiv/page-ini.lua
+++ b/tex/context/base/mkiv/page-ini.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['page-ini'] = {
license = "see context related readme files"
}
+-- Some day I need to make this more efficient.
+
local tonumber, rawget, rawset, type, next = tonumber, rawget, rawset, type, next
local match = string.match
local sort, tohash, insert, remove, sortedkeys = table.sort, table.tohash, table.insert, table.remove, table.sortedkeys
@@ -13,7 +15,12 @@ local settings_to_array, settings_to_hash = utilities.parsers.settings_to_array,
local texgetcount = tex.getcount
+local tonut = nodes.tonut
+local nextlist = nodes.nuts.traversers.list
+local texlists = tex.lists
+
local context = context
+local ctx_doif = commands.doif
local ctx_doifelse = commands.doifelse
local implement = interfaces.implement
@@ -23,16 +30,22 @@ local last = 0
local pages = structures.pages
local autolist = { }
local report = logs.reporter("pages","mark")
+local active = false
local trace = false trackers.register("pages.mark",function(v) trace = v end)
-function pages.mark(name,list)
+function pages.mark(name,list,settings)
+ active = true
+ --
local realpage = texgetcount("realpageno")
+ if type(settings) == "string" then
+ settings = settings_to_hash(settings)
+ end
if not list or list == "" then
if trace then
report("marking current page %i as %a",realpage,name)
end
- data[realpage][name] = true
+ data[realpage][name] = settings or true
return
end
if type(list) == "string" then
@@ -51,7 +64,7 @@ function pages.mark(name,list)
report("marking page %i upto %i as %a",f,t,name)
end
for page=f,t do
- data[page][name] = true
+ data[page][name] = settings or true
end
end
page = false
@@ -74,7 +87,7 @@ function pages.mark(name,list)
if trace then
report("marking page %i as %a",page,name)
end
- data[page][name] = true
+ data[page][name] = settings or true
end
end
end
@@ -83,30 +96,51 @@ function pages.mark(name,list)
if trace then
report("marking current page %i as %a",realpage,name)
end
- data[realpage][name] = true
+ data[realpage][name] = settings or true
end
end
local tobemarked = { }
function pages.markedlist(realpage)
- if realpage then
+ if active and realpage then
local m = rawget(tobemarked,realpage) or rawget(data,realpage)
return m and next(m) and sortedkeys(m)
end
end
local function marked(name)
- local realpage = texgetcount("realpageno")
- for i=last,realpage-1 do
- local di = data[i]
- if di then
- tobemarked[i] = di
- rawset(data,i,nil)
+ if active then
+ local realpage = texgetcount("realpageno")
+ if last ~= 0 then
+ for i=last,realpage-1 do
+ -- print(last)
+ local di = data[i]
+ if di then
+ tobemarked[i] = di
+ rawset(data,i,nil)
+ end
+ end
+ last = 0 -- needs checking
+ end
+ local pagedata = rawget(data,realpage)
+ return pagedata and pagedata[name] and true or false
+ else
+ return false
+ end
+end
+
+local function markedparameter(name,key)
+ if active then
+ local pagedata = rawget(data,texgetcount("realpageno"))
+ if pagedata then
+ pagedata = pagedata[name]
+ if pagedata then
+ pagedata = pagedata[key]
+ end
end
+ return pagedata
end
- local pagedata = rawget(data,realpage)
- return pagedata and pagedata[name] and true or false
end
local function toranges(marked)
@@ -124,12 +158,14 @@ local function toranges(marked)
last = page
end
list[#list+1] = { first, last }
+ --
+ active = true
end
return list
end
local function allmarked(list)
- if list then
+ if active and list then
local collected = pages.collected
if collected then
if type(list) == "string" then
@@ -175,26 +211,77 @@ pages.allmarked = allmarked
-- An alternative is to use an attribute and identify the state by parsing the node
-- list but that's a bit overkill for a hardly used feature like this.
-luatex.registerpageactions(function()
+-- Page actions are bound to a real page. When we set one, we need to bind to the
+-- current page unless we just flushed. So we also need to check the current page.
+
+-- \page ... \start : sync realpage
+-- \page \start : sync realpage
+-- \page \stop : reset synced because no content yet
+-- \page ... \stop : keep sync
+
+local function autopageaction()
+ if active then
+ local nofauto = #autolist
+ if nofauto > 0 then
+ local realpage = texgetcount("realpageno")
+ for i=1,nofauto do
+ local entry = autolist[i]
+ local names = entry[1]
+ local settings = entry[2]
+ for j=1,#names do
+ local name = names[j]
+ local list = data[realpage]
+ if not list[name] then
+ if trace then
+ report("automatically marking page %i as %a",realpage,name)
+ end
+ list[name] = settings or true
+ end
+ end
+ end
+ end
+ end
+end
+
+local function startmarked(name,settings)
+ active = true
+ --
+ insert(autolist, { settings_to_array(name), settings_to_hash(settings) })
+ autopageaction(true)
+end
+
+local function stopmarked()
local nofauto = #autolist
if nofauto > 0 then
- local realpage = texgetcount("realpageno")
- for i=1,nofauto do
- local names = autolist[i]
- for j=1,#names do
- local name = names[j]
- data[realpage][name] = true
- if trace then
- report("automatically marking page %i as %a",realpage,name)
+ if not texlists.pagehead then
+ local realpage = texgetcount("realpageno")
+ for i=1,nofauto do
+ local entry = autolist[i]
+ local names = entry[1]
+ for j=1,#names do
+ local name = names[j]
+ local list = data[realpage]
+ if list[name] then
+ if trace then
+ report("automatically unmarking page %i as %a",realpage,name)
+ end
+ list[name] = nil
+ end
end
end
end
+ remove(autolist)
end
-end)
+end
+
+implement {
+ name = "checkmarkedpages",
+ actions = autopageaction,
+}
implement {
name = "markpage",
- arguments = "2 strings",
+ arguments = "3 strings",
actions = pages.mark
}
@@ -205,6 +292,23 @@ implement {
}
implement {
+ name = "doifmarkedpage",
+ arguments = "string",
+ actions = { marked, ctx_doif }
+}
+
+implement {
+ name = "markedpageparameter",
+ arguments = "strings",
+ actions = function(name,key)
+ local value = markedparameter(name,key)
+ if value then
+ context(value)
+ end
+ end
+}
+
+implement {
name = "markedpages",
arguments = "string",
actions = function(name)
@@ -217,20 +321,13 @@ implement {
implement {
name = "startmarkpages",
- arguments = "string",
- actions = function(name)
- insert(autolist,settings_to_array(name))
- end
+ arguments = "2 strings",
+ actions = startmarked,
}
implement {
- name = "stopmarkpages",
- arguments = "string",
- actions = function(name)
- if #autolist > 0 then
- remove(autolist)
- end
- end
+ name = "stopmarkpages",
+ actions = stopmarked,
}
local tonut = nodes.tonut