1if 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
9local format , concat , rep = string . format , table . concat , string . rep
10local lpegmatch = lpeg . match
11local next = next
12
13local xml = xml
14local lxml = lxml
15local context = context
16
17local lxmlsorters = lxml . sorters or { }
18lxml . sorters = lxmlsorters
19
20if 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
30end
31
32local lists = { }
33
34function lxmlsorters . reset ( name )
35 lists [ name ] = {
36 sorted = false ,
37 entries = { } ,
38 reverse = { } ,
39 results = { } ,
40 }
41end
42
43function lxmlsorters . add ( name , n , key )
44 local list = lists [ name ]
45 if list . sorted then
46
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
61end
62
63function 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
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
97end
98
99lxmlsorters . compare = sorters . comparers . basic
100
101function lxmlsorters . sort ( name )
102 local list = lists [ name ]
103 local entries = list and list . entries
104 if entries then
105
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
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
124 sorters . sort ( results , lxmlsorters . compare )
125
126 list . nofsorted = # results
127 local split = { }
128 for k = 1 , # results do
129 local v = results [ k ]
130 local entry , tag = firstofsplit ( v )
131 local s = split [ entry ]
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
140 list . sorted = true
141 end
142end
143
144function 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
163end
164 |