1if not modules then modules = { } end modules ['bibl-tra'] = {
2 version = 1.001,
3 comment = "this module is the basis for the lxml-* ones",
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
13if not publications then
14
15 local hacks = utilities.storage.allocate()
16
17 job.register('publications.collected',hacks,function(t) publications.collected = t end)
18
19end
20
21
22
23
24local gmatch, format = string.gmatch, string.format
25local sort = table.sort
26local savedata = io.savedata
27
28bibtex = bibtex or { }
29local bibtex = bibtex
30
31bibtex.hacks = bibtex.hacks or { }
32local hacks = bibtex.hacks
33
34local trace_bibtex = false trackers.register("publications.bibtex", function(v) trace_bibtex = v end)
35
36local report_tex = logs.reporter("publications","tex")
37
38local context = context
39local structures = structures
40
41local references = structures.references
42local sections = structures.sections
43
44local variables = interfaces.variables
45
46local v_short = variables.short
47local v_cite = variables.cite
48local v_default = variables.default
49local v_reference = variables.default
50
51local list = { }
52local done = { }
53local alldone = { }
54local used = { }
55local registered = { }
56local ordered = { }
57local shorts = { }
58local mode = 0
59
60local template = [[
61\citation{*}
62\bibstyle{cont-%s}
63\bibdata{%s}
64]]
65
66local runners = {
67 bibtex = sandbox.registerrunner {
68 name = "bibtex",
69 method = "execute",
70 program = "bibtex",
71 template = "%filename%",
72 checkers = {
73 filename = "readable",
74 }
75 },
76 mlbibtex = sandbox.registerrunner {
77 name = "mlbibtex",
78 method = "execute",
79 program = "mlbibcontext",
80 template = "%filename%",
81 checkers = {
82 filename = "readable",
83 }
84 }
85}
86
87local runner = environment.arguments.mlbibtex and runners.mlbibtex or runners.bibtex
88
89directives.register("publications.usemlbibtex", function(v)
90 runner = v and runners.mlbibtex or runners.bibtex
91end)
92
93function hacks.process(settings)
94 local style = settings.style or ""
95 local database = settings.database or ""
96 local jobname = tex.jobname
97 if database ~= "" then
98 local targetfile = file.addsuffix(jobname,"aux")
99 interfaces.showmessage("publications",3,targetfile)
100 savedata(targetfile,format(template,style,database))
101 if trace_bibtex then
102 report_tex("processing bibtex file %a using %a",jobname,bibtexbin)
103 end
104 runner { filename = jobname }
105
106 end
107end
108
109function hacks.register(tag,short)
110 if not short or short == "" then
111 short = tag
112 end
113 if trace_bibtex then
114 report_tex("registering bibtex entry %a with shortcut %a",tag,short)
115 end
116 local top = #registered + 1
117 registered[top] = tag
118 ordered [tag] = top
119 shorts [tag] = short
120end
121
122function hacks.nofregistered()
123 return #registered
124end
125
126function hacks.reset(m)
127 mode, list, done = m, { }, { }
128end
129
130function hacks.add(str,listindex)
131 if not str or mode == 0 then
132
133 elseif mode == 1 then
134
135 local sc = sections.currentid()
136 if done[str] ~= sc then
137 done[str], alldone[str] = sc, true
138 list[#list+1] = { str, listindex }
139 end
140 elseif mode == 2 then
141
142 local sc = sections.currentid()
143 if not alldone[str] and done[str] ~= sc then
144 done[str], alldone[str] = sc, true
145 list[#list+1] = { str, listindex }
146 end
147 end
148end
149
150function hacks.flush(sortvariant)
151 local compare
152 if sortvariant == "" or sortvariant == v_cite or sortvariant == v_default then
153
154 elseif sortvariant == v_short then
155 compare = function(a,b)
156 local aa, bb = a and a[1], b and b[1]
157 if aa and bb then
158 local oa, ob = shorts[aa], shorts[bb]
159 return oa and ob and oa < ob
160 end
161 return false
162 end
163 elseif sortvariant == v_reference then
164 compare = function(a,b)
165 local aa, bb = a and a[1], b and b[1]
166 if aa and bb then
167 return aa and bb and aa < bb
168 end
169 return false
170 end
171 else
172 compare = function(a,b)
173 local aa, bb = a and a[1], b and b[1]
174 if aa and bb then
175 local oa, ob = ordered[aa], ordered[bb]
176 return oa and ob and oa < ob
177 end
178 return false
179 end
180 end
181 if compare then
182 sort(list,compare)
183 end
184 for i=1,#list do
185 context.doprocessbibtexentry(list[i][1])
186 end
187end
188
189function hacks.filterall()
190 for i=1,#registered do
191 list[i] = { registered[i], i }
192 end
193end
194
195function hacks.registerplaced(str)
196 used[str] = true
197end
198
199function hacks.doifalreadyplaced(str)
200 commands.doifelse(used[str])
201end
202
203
204
205
206
207local function compare(a,b)
208 local aa, bb = a and a[3], b and b[3]
209 return aa and bb and aa < bb
210end
211
212function hacks.resolve(prefix,block,reference)
213
214 local subsets
215 local collected = references.collected
216 if prefix and prefix ~= "" then
217 subsets = { collected[prefix] or collected[""] }
218 else
219 local components = references.productdata.components
220 local subset = collected[""]
221 if subset then
222 subsets = { subset }
223 else
224 subsets = { }
225 end
226 for i=1,#components do
227 local subset = collected[components[i]]
228 if subset then
229 subsets[#subsets+1] = subset
230 end
231 end
232 end
233 if #subsets > 0 then
234 local result, nofresult, done = { }, 0, { }
235 block = tonumber(block)
236 for i=1,#subsets do
237 local subset = subsets[i]
238 for rest in gmatch(reference,"[^, ]+") do
239 local blk, tag, found = block, nil, nil
240 if block then
241 tag = blk .. ":" .. rest
242 found = subset[tag]
243 if not found then
244 for i=block-1,1,-1 do
245 tag = i .. ":" .. rest
246 found = subset[tag]
247 if found then
248 blk = i
249 break
250 end
251 end
252 end
253 end
254 if not found then
255 blk = "*"
256 tag = blk .. ":" .. rest
257 found = subset[tag]
258 end
259 if found then
260 local current = tonumber(found.entries and found.entries.text)
261 if current and not done[current] then
262 nofresult = nofresult + 1
263 result[nofresult] = { blk, rest, current }
264 done[current] = true
265 end
266 end
267 end
268 end
269
270 sort(result,compare)
271 local first, last, firsti, lasti, firstr, lastr
272 local collected, nofcollected = { }, 0
273 for i=1,nofresult do
274 local r = result[i]
275 local current = r[3]
276 if not first then
277 first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r
278 elseif current == last + 1 then
279 last, lasti, lastr = current, i, r
280 else
281 if last > first + 1 then
282 nofcollected = nofcollected + 1
283 collected[nofcollected] = { firstr[1], firstr[2], lastr[1], lastr[2] }
284 else
285 nofcollected = nofcollected + 1
286 collected[nofcollected] = { firstr[1], firstr[2] }
287 if last > first then
288 nofcollected = nofcollected + 1
289 collected[nofcollected] = { lastr[1], lastr[2] }
290 end
291 end
292 first, last, firsti, lasti, firstr, lastr = current, current, i, i, r, r
293 end
294 end
295 if first and last then
296 if last > first + 1 then
297 nofcollected = nofcollected + 1
298 collected[nofcollected] = { firstr[1], firstr[2], lastr[1], lastr[2] }
299 else
300 nofcollected = nofcollected + 1
301 collected[nofcollected] = { firstr[1], firstr[2] }
302 if last > first then
303 nofcollected = nofcollected + 1
304 collected[nofcollected] = { lastr[1], lastr[2] }
305 end
306 end
307 end
308 if nofcollected > 0 then
309 for i=1,nofcollected do
310 local c = collected[i]
311 if c[3] then
312 context.dowithbibtexnumrefrange(#collected,i,prefix,c[1],c[2],c[3],c[4])
313 else
314
315 context.dowithbibtexnumref(#collected,i,prefix,c[1],c[2])
316 end
317 end
318 else
319 context.nobibtexnumref("error 1")
320 end
321 else
322 context.nobibtexnumref("error 2")
323 end
324end
325 |