math-dir.lua /size: 5517 b    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
math-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
-- As I'm wrapping up the updated math support (for CTX/TUG 2013) I wondered about numbers in
10
-- r2l math mode. Googling lead me to TUGboat, Volume 25 (2004), No. 2 where I see numbers
11
-- running from left to right. Makes me wonder how far we should go. And as I was looking
12
-- into bidi anyway, it's a nice distraction.
13
--
14
-- I first tried to hook something into noads but that gets pretty messy due to indirectness
15
-- char noads. If needed, I'll do it that way. With regards to spacing: as we can assume that
16
-- only numbers are involved we can safely swap them and the same is true for mirroring. But
17
-- anyway, I'm not too happy with this solution so eventually I'll do something with noads (as
18
-- an alternative method). Yet another heuristic approach.
19 20
local
nodes
,
node
=
nodes
,
node
21 22
local
trace_directions
=
false
trackers
.
register
(
"
typesetters.directions.math
"
,
function
(
v
)
trace_directions
=
v
end
)
23 24
local
report_directions
=
logs
.
reporter
(
"
typesetting
"
,
"
math directions
"
)
25 26
local
nuts
=
nodes
.
nuts
27
local
tonut
=
nuts
.
tonut
28
local
tonode
=
nuts
.
tonode
29 30
local
getnext
=
nuts
.
getnext
31
local
getchar
=
nuts
.
getchar
32
local
getid
=
nuts
.
getid
33
local
getlist
=
nuts
.
getlist
34
local
getattr
=
nuts
.
getattr
35 36
local
setchar
=
nuts
.
setchar
37
local
setlist
=
nuts
.
setlist
38 39
local
insertnodebefore
=
nuts
.
insertbefore
40
local
insertnodeafter
=
nuts
.
insertafter
41 42
local
nodecodes
=
nodes
.
nodecodes
43
local
enableaction
=
nodes
.
tasks
.
enableaction
44 45
local
glyph_code
=
nodecodes
.
glyph
46
local
hlist_code
=
nodecodes
.
hlist
47
local
vlist_code
=
nodecodes
.
vlist
48 49
local
nodepool
=
nuts
.
pool
50 51
local
new_direction
=
nodepool
.
direction
52 53
local
lefttoright_code
=
nodes
.
dirvalues
.
lefttoright
54 55
local
chardirections
=
characters
.
directions
56
local
charmirrors
=
characters
.
mirrors
57
local
charclasses
=
characters
.
textclasses
58 59
local
directions
=
typesetters
.
directions
or
{
}
60 61
local
a_mathbidi
=
attributes
.
private
(
'
mathbidi
'
)
62 63
local
function
processmath
(
head
)
64
local
current
=
head
65
local
start
=
nil
66
local
stop
=
nil
67
local
function
capsulate
(
)
68
head
=
insertnodebefore
(
head
,
start
,
new_direction
(
lefttoright_code
)
)
69
insertnodeafter
(
head
,
stop
,
new_direction
(
lefttoright_code
,
true
)
)
70
if
trace_directions
then
71
report_directions
(
"
reversed: %s
"
,
nodes
.
listtoutf
(
start
,
false
,
false
,
stop
)
)
72
end
73
start
=
false
74
stop
=
nil
75
end
76
while
current
do
77
local
id
=
getid
(
current
)
78
if
id
=
=
glyph_code
then
79
local
char
=
getchar
(
current
)
80
local
cdir
=
chardirections
[
char
]
81
if
cdir
=
=
"
en
"
or
cdir
=
=
"
an
"
then
-- we could check for mathclass punctuation
82
if
not
start
then
83
start
=
current
84
end
85
stop
=
current
86
else
87
if
not
start
then
88
-- nothing
89
elseif
start
=
=
stop
then
90
start
=
nil
91
else
92
capsulate
(
)
93
end
94
if
cdir
=
=
"
on
"
then
95
local
mirror
=
charmirrors
[
char
]
96
if
mirror
then
97
local
class
=
charclasses
[
char
]
98
if
class
=
=
"
open
"
or
class
=
=
"
close
"
then
99
setchar
(
current
,
mirror
)
100
if
trace_directions
then
101
report_directions
(
"
mirrored: %C to %C
"
,
char
,
mirror
)
102
end
103
end
104
end
105
end
106
end
107
elseif
not
start
then
108
-- nothing
109
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
110
local
list
=
processmath
(
getlist
(
current
)
)
111
setlist
(
current
,
list
)
112
end
113
elseif
start
=
=
stop
then
114
start
=
nil
115
else
116
capsulate
(
head
,
start
,
stop
)
117
-- math can pack things into hlists .. we need to make sure we don't process
118
-- too often: needs checking
119
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
120
local
list
=
processmath
(
getlist
(
current
)
)
121
setlist
(
current
,
list
)
122
end
123
end
124
current
=
getnext
(
current
)
125
end
126
if
not
start
then
127
-- nothing
128
elseif
start
=
=
stop
then
129
-- nothing
130
else
131
capsulate
(
)
132
end
133
return
head
134
end
135 136
local
enabled
=
false
137 138
function
directions
.
processmath
(
head
)
-- style, penalties
139
if
enabled
then
140
local
a
=
getattr
(
head
,
a_mathbidi
)
141
if
a
and
a
>
0
then
142
return
processmath
(
head
)
143
end
144
end
145
end
146 147
function
directions
.
setmath
(
n
)
148
if
not
enabled
and
n
and
n
>
0
then
149
if
trace_directions
then
150
report_directions
(
"
enabling directions handler
"
)
151
end
152
enableaction
(
"
math
"
,
"
typesetters.directions.processmath
"
)
153
enabled
=
true
154
end
155
end
156 157
interfaces
.
implement
{
158
name
=
"
setmathdirection
"
,
159
actions
=
directions
.
setmath
,
160
arguments
=
"
integer
"
161
}
162