1if not modules then modules = { } end modules [ ' typo-dig ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to typo-dig.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
10
11
12local next , type , tonumber = next , type , tonumber
13local format , insert = string . format , table . insert
14local round , div = math . round , math . div
15
16local trace_digits = false trackers . register ( " typesetters.digits " , function ( v ) trace_digits = v end )
17
18local report_digits = logs . reporter ( " typesetting " , " digits " )
19
20local nodes , node = nodes , node
21
22local nuts = nodes . nuts
23
24local getnext = nuts . getnext
25local getprev = nuts . getprev
26local getid = nuts . getid
27local getwidth = nuts . getwidth
28local isglyph = nuts . isglyph
29local takeattr = nuts . takeattr
30
31local setlink = nuts . setlink
32local setnext = nuts . setnext
33local setprev = nuts . setprev
34
35local hpack_node = nuts . hpack
36local traverse_id = nuts . traverse_id
37local insert_node_before = nuts . insert_before
38local insert_node_after = nuts . insert_after
39
40local texsetattribute = tex . setattribute
41local unsetvalue = attributes . unsetvalue
42
43local nodecodes = nodes . nodecodes
44local glyph_code = nodecodes . glyph
45
46local nodepool = nuts . pool
47local enableaction = nodes . tasks . enableaction
48
49local new_glue = nodepool . glue
50
51local fonthashes = fonts . hashes
52local chardata = fonthashes . characters
53
54local v_reset = interfaces . variables . reset
55
56local charbase = characters . data
57local getdigitwidth = fonts . helpers . getdigitwidth
58
59typesetters = typesetters or { }
60local typesetters = typesetters
61
62typesetters . digits = typesetters . digits or { }
63local digits = typesetters . digits
64
65digits . actions = { }
66local actions = digits . actions
67
68local a_digits = attributes . private ( " digits " )
69
70
71
72
73function nodes . aligned ( head , start , stop , width , how )
74 if how = = " flushright " or how = = " middle " then
75 head , start = insert_node_before ( head , start , new_glue ( 0 , 65536 , 65536 ) )
76 end
77 if how = = " flushleft " or how = = " middle " then
78 head , stop = insert_node_after ( head , stop , new_glue ( 0 , 65536 , 65536 ) )
79 end
80 local prv = getprev ( start )
81 local nxt = getnext ( stop )
82 setprev ( start )
83 setnext ( stop )
84 local packed = hpack_node ( start , width , " exactly " )
85 if prv then
86 setlink ( prv , packed )
87 end
88 if nxt then
89 setlink ( packed , nxt )
90 end
91 if getprev ( packed ) then
92 return head , packed
93 else
94 return packed , packed
95 end
96end
97
98actions [ 1 ] = function ( head , start , attr )
99 local char , font = isglyph ( start )
100 local unic = chardata [ font ] [ char ] . unicode or char
101 if charbase [ unic ] . category = = " nd " then
102 local oldwidth = getwidth ( start )
103 local newwidth = getdigitwidth ( font )
104 if newwidth ~ = oldwidth then
105 if trace_digits then
106 report_digits ( " digit trigger %a, instance %a, char %C, unicode %U, delta %s " ,
107 attr % 100 , div ( attr , 100 ) , char , unic , newwidth - oldwidth )
108 end
109 head , start = nodes . aligned ( head , start , start , newwidth , " middle " )
110 return head , start
111 end
112 end
113 return head , start
114end
115
116function digits . handler ( head )
117 local current = head
118 while current do
119 if getid ( current ) = = glyph_code then
120 local attr = takeattr ( current , a_digits )
121 if attr and attr > 0 then
122 local action = actions [ attr % 100 ]
123 if action then
124 head , current = action ( head , current , attr )
125 elseif trace_digits then
126 report_digits ( " unknown digit trigger %a " , attr )
127 end
128 end
129 end
130 if current then
131 current = getnext ( current )
132 end
133 end
134 return head
135end
136
137local m , enabled = 0 , false
138
139function digits . set ( n )
140 if n = = v_reset then
141 n = unsetvalue
142 else
143 n = tonumber ( n )
144 if n then
145 if not enabled then
146 enableaction ( " processors " , " typesetters.digits.handler " )
147 if trace_digits then
148 report_digits ( " enabling digit handler " )
149 end
150 enabled = true
151 end
152 if m = = 100 then
153 m = 1
154 else
155 m = m + 1
156 end
157 n = m * 100 + n
158 else
159 n = unsetvalue
160 end
161 end
162 texsetattribute ( a_digits , n )
163end
164
165
166
167interfaces . implement {
168 name = " setdigitsmanipulation " ,
169 actions = digits . set ,
170 arguments = " string "
171}
172 |