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
|
if not modules then modules = { } end modules ['typo-dig'] = {
version = 1.001,
comment = "companion to typo-dig.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local next, type = next, type
local format, insert = string.format, table.insert
local round = math.round
local trace_digits = false trackers.register("nodes.digits", function(v) trace_digits = v end)
local has_attribute = node.has_attribute
local unset_attribute = node.unset_attribute
local set_attribute = node.set_attribute
local hpack_node = node.hpack
local traverse_id = node.traverse_id
local insert_before = node.insert_before
local insert_after = node.insert_after
local glyph = node.id("glyph")
local kern = node.id("kern")
local new_glue = nodes.glue
local fontdata = fonts.identifiers
local chardata = fonts.characters
local quaddata = fonts.quads
local charbase = characters.data
digits = digits or { }
digits.actions = { }
digits.attribute = attributes.private("digits")
local actions = digits.actions
-- at some point we can manipulate the glyph node so then i need
-- to rewrite this
function nodes.aligned(start,stop,width,how)
local prv, nxt, head = start.prev, stop.next, nil
start.prev, stop.next = nil, nil
if how == "flushright" or how == "middle" then
head, start = insert_before(start,start,new_glue(0,65536,65536))
end
if how == "flushleft" or how == "middle" then
head, stop = insert_after(start,stop,new_glue(0,65536,65536))
end
local packed = hpack_node(start,width,"exactly") -- no directional mess here, just lr
if prv then
prv.next, packed.prev = packed, prv
end
if nxt then
nxt.prev, packed.next = packed, nxt
end
return packed, prv, nxt
end
actions[1] = function(start,attribute)
local char = start.char
if charbase[char].category == "nd" then
local font = start.font
local oldwidth, newwidth = start.width, fonts.get_digit_width(font)
if newwidth ~= oldwidth then
local start = nodes.aligned(start,start,newwidth,"middle") -- return three node pointers
return start, true
end
end
return start, false
end
function digits.process(namespace,attribute,head)
local done, current, ok = false, head, false
while current do
if current.id == glyph then
local attr = has_attribute(current,attribute)
if attr and attr > 0 then
unset_attribute(current,attribute)
local action = actions[attr]
if action then
if current == head then
head, ok = action(current,attribute)
current = head
else
current, ok = action(current,attribute)
end
done = done and ok
end
end
end
current = current and current.next
end
return head, done
end
chars.handle_digits = nodes.install_attribute_handler {
name = "digits",
namespace = digits,
processor = digits.process,
}
function digits.enable()
tasks.enableaction("processors","chars.handle_digits")
end
|