attr-neg.lmt /size: 2761 b    last modification: 2025-02-21 11:03
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 allocate          = utilities.storage.allocate
23local setmetatableindex = table.setmetatableindex
24
25--- negative / positive
26
27attributes.negatives    = attributes.negatives or { }
28local negatives         = attributes.negatives
29
30local a_negative        <const> = attributes.private("negative")
31
32local v_none            <const> = interfaces.variables.none
33
34negatives.data          = allocate()
35negatives.attribute     = a_negative
36
37negatives.registered = allocate {
38    [interfaces.variables.positive] = 1,
39    [interfaces.variables.negative] = 2,
40}
41
42local data       = negatives.data
43local registered = negatives.registered
44
45local function extender(negatives,key)
46    if key == "none" then -- v_none then
47        local d = data[1]
48        negatives.none = d
49        return d
50    end
51end
52
53local function reviver(data,n)
54    if n == 1 then
55        local d = nodeinjections.positive() -- called once
56        data[1] = d
57        return d
58    elseif n == 2 then
59        local d = nodeinjections.negative() -- called once
60        data[2] = d
61        return d
62    end
63end
64
65setmetatableindex(negatives,      extender)
66setmetatableindex(negatives.data, reviver)
67
68negatives.handler = nodes.installattributehandler {
69    name        = "negative",
70    namespace   = negatives,
71    initializer = states.initialize,
72    finalizer   = states.finalize,
73    processor   = states.process,
74}
75
76local function register(stamp)
77    return registered[stamp] or registered.positive
78end
79
80local function enable()
81    enableaction("shipouts","attributes.negatives.handler")
82end
83
84negatives.register = register
85negatives.enable   = enable
86
87-- interface
88
89local enabled = false
90
91function negatives.set(stamp)
92    if not enabled then
93        enable()
94        enabled = true
95    end
96    texsetattribute(a_negative,register(stamp))
97end
98
99interfaces.implement {
100    name      = "setnegative",
101    actions   = negatives.set,
102    arguments = "argument",
103}
104