1if not modules then modules = { } end modules [ ' typo-dir ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to typo-dir.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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29local next , type = next , type
30local format , insert , sub , find , match = string . format , table . insert , string . sub , string . find , string . match
31
32local nodes , node = nodes , node
33
34local trace_textdirections = false trackers . register ( " typesetters.directions.text " , function ( v ) trace_textdirections = v end )
35local trace_mathdirections = false trackers . register ( " typesetters.directions.math " , function ( v ) trace_mathdirections = v end )
36local trace_directions = false trackers . register ( " typesetters.directions " , function ( v ) trace_textdirections = v trace_mathdirections = v end )
37
38local one_too = false directives . register ( " typesetters.directions.onetoo " , function ( v ) one_too = v end )
39
40local report_textdirections = logs . reporter ( " typesetting " , " text directions " )
41
42
43local band = bit32 . band
44
45local texsetattribute = tex . setattribute
46local unsetvalue = attributes . unsetvalue
47
48local nuts = nodes . nuts
49local getnext = nuts . getnext
50local getattr = nuts . getattr
51
52local enableaction = nodes . tasks . enableaction
53local tracers = nodes . tracers
54local setcolor = tracers . colors . set
55local resetcolor = tracers . colors . reset
56
57local implement = interfaces . implement
58
59local directions = typesetters . directions or { }
60typesetters . directions = directions
61
62local a_directions = attributes . private ( ' directions ' )
63
64local variables = interfaces . variables
65local v_global = variables [ " global " ]
66local v_local = variables [ " local " ]
67local v_on = variables . on
68local v_yes = variables . yes
69
70local m_enabled = 0x00000040
71local m_global = 0x00000080
72local m_fences = 0x00000100
73
74local handlers = { }
75local methods = { }
76local lastmethod = 0
77
78local function installhandler ( name , handler )
79 local method = methods [ name ]
80 if not method then
81 lastmethod = lastmethod + 1
82 method = lastmethod
83 methods [ name ] = method
84 end
85 handlers [ method ] = handler
86 return method
87end
88
89directions . handlers = handlers
90directions . installhandler = installhandler
91
92local function tomode ( specification )
93 local scope = specification . scope
94 local mode
95 if scope = = v_global or scope = = v_on then
96 mode = m_enabled + m_global
97 elseif scope = = v_local then
98 mode = m_enabled
99 else
100 return 0
101 end
102 local method = methods [ specification . method ]
103 if method then
104 mode = mode + method
105 else
106 return 0
107 end
108 if specification . fences = = v_yes then
109 mode = mode + m_fences
110 end
111 return mode
112end
113
114local function getglobal ( a )
115 return a and a > 0 and band ( a , m_global ) ~ = 0
116end
117
118local function getfences ( a )
119 return a and a > 0 and band ( a , m_fences ) ~ = 0
120end
121
122local function getmethod ( a )
123 return a and a > 0 and a % m_enabled or 0
124end
125
126directions . tomode = tomode
127directions . getglobal = getglobal
128directions . getfences = getfences
129directions . getmethod = getmethod
130directions . installhandler = installhandler
131
132
133
134function directions . setcolor ( current , direction , reversed , mirror )
135 if mirror then
136 setcolor ( current , " bidi:mirrored " )
137 elseif direction = = " l " then
138 setcolor ( current , reversed and " bidi:left:reversed " or " bidi:left:original " )
139 elseif direction = = " r " then
140 setcolor ( current , reversed and " bidi:right:reversed " or " bidi:right:original " )
141 else
142 resetcolor ( current )
143 end
144end
145
146implement {
147 name = " getbidimode " ,
148 actions = { tomode , context } ,
149 arguments = {
150 {
151 { " scope " } ,
152 { " method " } ,
153 { " fences " } ,
154 }
155 }
156}
157
158local enabled = false
159
160local starttiming = statistics . starttiming
161local stoptiming = statistics . stoptiming
162
163
164
165
166
167
168
169function directions . handler ( head , where , _ , _ , direction )
170 local only_one = not getnext ( head )
171 if only_one and not one_too then
172 return head
173 end
174 local attr = getattr ( head , a_directions )
175 if not attr or attr = = 0 then
176 return head
177 end
178 local method = getmethod ( attr )
179 local handler = handlers [ method ]
180 if not handler then
181 return head
182 end
183 starttiming ( directions )
184 head = handler ( head , direction , only_one , where )
185 stoptiming ( directions )
186 return head
187end
188
189statistics . register ( " text directions " , function ( )
190 if enabled then
191 return statistics . elapsedseconds ( directions )
192 end
193end )
194
195function directions . set ( n )
196 if not enabled then
197 if trace_textdirections then
198 report_textdirections ( " enabling directions handler " )
199 end
200 enableaction ( " processors " , " typesetters.directions.handler " )
201 enabled = true
202 end
203 if not n or n = = 0 then
204 n = unsetvalue
205
206 end
207 texsetattribute ( a_directions , n )
208end
209
210implement {
211 name = " setdirection " ,
212 arguments = " integer " ,
213 actions = directions . set
214}
215 |