lxml-sor.lua /size: 4547 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
lxml-sor
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to lxml-sor.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
local
format
,
concat
,
rep
=
string
.
format
,
table
.
concat
,
string
.
rep
10
local
lpegmatch
=
lpeg
.
match
11
local
next
=
next
12 13
local
xml
=
xml
14
local
lxml
=
lxml
15
local
context
=
context
16 17
local
lxmlsorters
=
lxml
.
sorters
or
{
}
18
lxml
.
sorters
=
lxmlsorters
19 20
if
not
lxml
.
splitid
then
21
local
splitter
=
lpeg
.
C
(
(
1
-
lpeg
.
P
(
"
:
"
)
)
^
1
)
*
lpeg
.
P
(
"
::
"
)
*
lpeg
.
C
(
lpeg
.
P
(
1
)
^
1
)
22
function
lxml
.
splitid
(
id
)
23
local
d
,
i
=
lpegmatch
(
splitter
,
id
)
24
if
d
then
25
return
d
,
i
26
else
27
return
"
"
,
id
28
end
29
end
30
end
31 32
local
lists
=
{
}
33 34
function
lxmlsorters
.
reset
(
name
)
35
lists
[
name
]
=
{
36
sorted
=
false
,
37
entries
=
{
}
,
38
reverse
=
{
}
,
39
results
=
{
}
,
40
}
41
end
42 43
function
lxmlsorters
.
add
(
name
,
n
,
key
)
44
local
list
=
lists
[
name
]
45
if
list
.
sorted
then
46
-- reverse is messed up, we could regenerate it and go on
47
else
48
local
entries
=
list
and
list
.
entries
49
if
entries
then
50
local
reverse
=
list
.
reverse
51
local
e
=
reverse
[
n
]
52
if
e
then
53
local
keys
=
entries
[
e
]
[
2
]
54
keys
[
#
keys
+
1
]
=
key
55
else
56
entries
[
#
entries
+
1
]
=
{
n
,
{
key
}
}
57
reverse
[
n
]
=
#
entries
58
end
59
end
60
end
61
end
62 63
function
lxmlsorters
.
show
(
name
)
64
local
list
=
lists
[
name
]
65
local
entries
=
list
and
list
.
entries
66
local
NC
,
NR
,
bold
=
context
.
NC
,
context
.
NR
,
context
.
bold
-- somehow bold is not working
67
if
entries
then
68
local
maxn
=
1
69
for
i
=
1
,
#
entries
do
70
if
#
entries
[
i
]
[
2
]
>
maxn
then
maxn
=
#
entries
[
i
]
[
2
]
end
71
end
72
context
.
starttabulate
{
"
|Tr|Tr|
"
.
.
rep
(
"
Tlp|
"
,
maxn
)
}
73
NC
(
)
bold
(
"
n
"
)
74
NC
(
)
bold
(
"
id
"
)
75
if
maxn
>
1
then
76
for
i
=
1
,
maxn
do
77
NC
(
)
bold
(
"
entry
"
.
.
i
)
78
end
79
else
80
NC
(
)
bold
(
"
entry
"
)
81
end
82
NC
(
)
NR
(
)
83
context
.
HL
(
)
84
for
i
=
1
,
#
entries
do
85
local
entry
=
entries
[
i
]
86
local
document
,
node
=
lxml
.
splitid
(
entry
[
1
]
)
87
NC
(
)
context
(
i
)
88
NC
(
)
context
(
node
)
89
local
e
=
entry
[
2
]
90
for
i
=
1
,
#
e
do
91
NC
(
)
context
.
detokenize
(
e
[
i
]
)
92
end
93
NC
(
)
NR
(
)
94
end
95
context
.
stoptabulate
(
)
96
end
97
end
98 99
lxmlsorters
.
compare
=
sorters
.
comparers
.
basic
-- (a,b)
100 101
function
lxmlsorters
.
sort
(
name
)
102
local
list
=
lists
[
name
]
103
local
entries
=
list
and
list
.
entries
104
if
entries
then
105
-- filtering
106
local
results
=
{
}
107
list
.
results
=
results
108
for
i
=
1
,
#
entries
do
109
local
entry
=
entries
[
i
]
110
results
[
i
]
=
{
111
entry
=
entry
[
1
]
,
112
key
=
concat
(
entry
[
2
]
,
"
"
)
,
113
}
114
end
115
-- preparation
116
local
strip
=
sorters
.
strip
117
local
splitter
=
sorters
.
splitters
.
utf
118
local
firstofsplit
=
sorters
.
firstofsplit
119
for
i
=
1
,
#
results
do
120
local
r
=
results
[
i
]
121
r
.
split
=
splitter
(
strip
(
r
.
key
)
)
122
end
123
-- sorting
124
sorters
.
sort
(
results
,
lxmlsorters
.
compare
)
125
-- finalizing
126
list
.
nofsorted
=
#
results
127
local
split
=
{
}
128
for
k
=
1
,
#
results
do
-- rather generic so maybe we need a function
129
local
v
=
results
[
k
]
130
local
entry
,
tag
=
firstofsplit
(
v
)
131
local
s
=
split
[
entry
]
-- keeps track of change
132
if
not
s
then
133
s
=
{
tag
=
tag
,
data
=
{
}
}
134
split
[
entry
]
=
s
135
end
136
s
.
data
[
#
s
.
data
+
1
]
=
v
137
end
138
list
.
results
=
split
139
-- done
140
list
.
sorted
=
true
141
end
142
end
143 144
function
lxmlsorters
.
flush
(
name
,
setup
)
145
local
list
=
lists
[
name
]
146
local
results
=
list
and
list
.
results
147
local
xmlw
=
context
.
xmlw
148
if
results
and
next
(
results
)
then
149
for
key
,
result
in
next
,
results
do
150
local
tag
,
data
=
result
.
tag
,
result
.
data
151
for
d
=
1
,
#
data
do
152
xmlw
(
setup
,
data
[
d
]
.
entry
)
153
end
154
end
155
else
156
local
entries
=
list
and
list
.
entries
157
if
entries
then
158
for
i
=
1
,
#
entries
do
159
xmlw
(
setup
,
entries
[
i
]
[
1
]
)
160
end
161
end
162
end
163
end
164