1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
if not modules then modules = { } end modules ['attr-lay'] = {
version = 1.001,
comment = "companion to attr-lay.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-- layers (ugly code, due to no grouping and such); currently we use exclusive layers
-- but when we need it stacked layers might show up too; the next function based
-- approach can be replaced by static (metatable driven) resolvers
local type = type
local format = string.format
local report_viewerlayers = logs.new("viewerlayers")
-- todo: document this but first reimplement this as it reflects the early
-- days of luatex / mkiv and we have better ways now
-- nb: attributes: color etc is much slower than normal (marks + literals) but ...
-- nb. too many "0 g"s
local attributes, nodes = attributes, nodes
attributes.viewerlayers = attributes.viewerlayers or { }
local viewerlayers = attributes.viewerlayers
viewerlayers = viewerlayers or { }
viewerlayers.data = viewerlayers.data or { }
viewerlayers.registered = viewerlayers.registered or { }
viewerlayers.values = viewerlayers.values or { }
viewerlayers.listwise = viewerlayers.listwise or { }
viewerlayers.attribute = attributes.private("viewerlayer")
viewerlayers.supported = true
viewerlayers.hasorder = true
local states = attributes.states
local tasks = nodes.tasks
local nodeinjections = backends.nodeinjections
storage.register("attributes/viewerlayers/registered", viewerlayers.registered, "attributes.viewerlayers.registered")
storage.register("attributes/viewerlayers/values", viewerlayers.values, "attributes.viewerlayers.values")
local data = viewerlayers.data
local values = viewerlayers.values
local listwise = viewerlayers.listwise
local registered = viewerlayers.registered
local template = "%s"
-- stacked
local function extender(viewerlayers,key)
if viewerlayers.supported and key == "none" then
local d = nodeinjections.stoplayer()
viewerlayers.none = d
return d
end
end
local function reviver(data,n)
if viewerlayers.supported then
local v = values[n]
if v then
local d = nodeinjections.startlayer(v)
data[n] = d
return d
else
logs.report("viewerlayers","error, unknown reference '%s'",tostring(n))
end
end
end
setmetatable(viewerlayers, { __index = extender })
setmetatable(viewerlayers.data, { __index = reviver })
local function initializer(...)
return states.initialize(...)
end
viewerlayers.register = function(name,lw) -- if not inimode redefine data[n] in first call
local stamp = format(template,name)
local n = registered[stamp]
if not n then
n = #values + 1
values[n] = name
registered[stamp] = n
listwise[n] = lw or false
end
return registered[stamp] -- == n
end
attributes.viewerlayers.handler = nodes.installattributehandler {
name = "viewerlayer",
namespace = viewerlayers,
initializer = initializer,
finalizer = states.finalize,
processor = states.stacked,
}
function viewerlayers.enable(value)
if value == false or not viewerlayers.supported then
tasks.disableaction("shipouts","attributes.viewerlayers.handler")
else
tasks.enableaction("shipouts","attributes.viewerlayers.handler")
end
end
function viewerlayers.forcesupport(value)
viewerlayers.supported = value
report_viewerlayers("viewerlayers are %ssupported",value and "" or "not ")
viewerlayers.enable(value)
end
function viewerlayers.setfeatures(hasorder)
viewerlayers.hasorder = hasorder
end
|