attr-neg.lua /size: 2768 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['attr-neg'] = {
2    version   = 1.001,
3    comment   = "companion to attr-neg.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- this module is being reconstructed and code will move to other places
10-- we can also do the nsnone via a metatable and then also se index 0
11
12local format = string.format
13
14local attributes, nodes, utilities, logs, backends = attributes, nodes, utilities, logs, backends
15local commands, context, interfaces = commands, context, interfaces
16local tex = tex
17
18local states            = attributes.states
19local enableaction      = nodes.tasks.enableaction
20local nodeinjections    = backends.nodeinjections
21local texsetattribute   = tex.setattribute
22local variables         = interfaces.variables
23local allocate          = utilities.storage.allocate
24local setmetatableindex = table.setmetatableindex
25
26--- negative / positive
27
28attributes.negatives    = attributes.negatives or { }
29local negatives         = attributes.negatives
30
31local a_negative        = attributes.private("negative")
32
33local v_none            = interfaces.variables.none
34
35negatives.data          = allocate()
36negatives.attribute     = a_negative
37
38negatives.registered = allocate {
39    [variables.positive] = 1,
40    [variables.negative] = 2,
41}
42
43local data       = negatives.data
44local registered = negatives.registered
45
46local function extender(negatives,key)
47    if key == "none" then -- v_none then
48        local d = data[1]
49        negatives.none = d
50        return d
51    end
52end
53
54local function reviver(data,n)
55    if n == 1 then
56        local d = nodeinjections.positive() -- called once
57        data[1] = d
58        return d
59    elseif n == 2 then
60        local d = nodeinjections.negative() -- called once
61        data[2] = d
62        return d
63    end
64end
65
66setmetatableindex(negatives,      extender)
67setmetatableindex(negatives.data, reviver)
68
69negatives.handler = nodes.installattributehandler {
70    name        = "negative",
71    namespace   = negatives,
72    initializer = states.initialize,
73    finalizer   = states.finalize,
74    processor   = states.process,
75}
76
77local function register(stamp)
78    return registered[stamp] or registered.positive
79end
80
81local function enable()
82    enableaction("shipouts","attributes.negatives.handler")
83end
84
85negatives.register = register
86negatives.enable   = enable
87
88-- interface
89
90local enabled = false
91
92function negatives.set(stamp)
93    if not enabled then
94        enable()
95        enabled = true
96    end
97    texsetattribute(a_negative,register(stamp))
98end
99
100interfaces.implement {
101    name      = "setnegative",
102    actions   = negatives.set,
103    arguments = "string",
104}
105