1if not modules then modules = { } end modules ['back-exp-imp-ref'] = {
2 version = 1.001,
3 comment = "companion to back-exp.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
23local tonumber = tonumber
24local lpegmatch = lpeg.match
25local insert = table.insert
26
27local references = structures.references
28
29local structurestags = structures.tags
30local specifications = structurestags.specifications
31local locatedtag = structurestags.locatedtag
32
33local backend = structurestags.backend
34
35local setattribute = backend.setattribute
36local extras = backend.extras
37local fixes = backend.fixes
38local referencehash = backend.referencehash
39local destinationhash = backend.destinationhash
40
41local implement = interfaces.implement
42
43local evaluators = { }
44local specials = { }
45local explicits = { }
46
47evaluators.inner = function(di,var)
48 local inner = var.inner
49 if inner then
50 setattribute(di,"location",inner,true)
51 end
52end
53
54evaluators.outer = function(di,var)
55 local file, url = references.checkedfileorurl(var.outer,var.outer)
56 if url then
57 setattribute(di,"url",url,true)
58 elseif file then
59 setattribute(di,"file",file,true)
60 end
61end
62
63evaluators["outer with inner"] = function(di,var)
64 local file = references.checkedfile(var.f)
65 if file then
66 setattribute(di,"file",file,true)
67 end
68 local inner = var.inner
69 if inner then
70 setattribute(di,"inner",inner,true)
71 end
72end
73
74evaluators.special = function(di,var)
75 local handler = specials[var.special]
76 if handler then
77 handler(di,var)
78 end
79end
80
81do
82
83 evaluators["special outer with operation"] = evaluators.special
84 evaluators["special operation"] = evaluators.special
85 evaluators["special operation with arguments"] = evaluators.special
86
87 function specials.url(di,var)
88 local url = references.checkedurl(var.operation)
89 if url and url ~= "" then
90 setattribute(di,"url",url,true)
91 end
92 end
93
94 function specials.file(di,var)
95 local file = references.checkedfile(var.operation)
96 if file and file ~= "" then
97 setattribute(di,"file",file,true)
98 end
99 end
100
101 function specials.fileorurl(di,var)
102 local file, url = references.checkedfileorurl(var.operation,var.operation)
103 if url and url ~= "" then
104 setattribute(di,"url",url,true)
105 elseif file and file ~= "" then
106 setattribute(di,"file",file,true)
107 end
108 end
109
110 function specials.internal(di,var)
111 local internal = references.checkedurl(var.operation)
112 if internal then
113 setattribute(di,"location",internal)
114 end
115 end
116
117 local function adddestination(di,references)
118 if references then
119 local reference = references.reference
120 if reference and reference ~= "" then
121 local prefix = references.prefix
122 if prefix and prefix ~= "" then
123 setattribute(di,"prefix",prefix,true)
124 end
125 setattribute(di,"destination",reference,true)
126 for i=1,#references do
127 local r = references[i]
128 local e = evaluators[r.kind]
129 if e then
130 e(di,r)
131 end
132 end
133 end
134 end
135 end
136
137 function extras.addimplicit(di,references)
138 if references then
139 local internal = references.internal
140 if internal then
141 setattribute(di,"implicit",internal)
142 end
143 end
144 end
145
146 function extras.addinternal(di,references)
147 if references then
148 local internal = references.internal
149 if internal then
150 setattribute(di,"internal",internal)
151 end
152 end
153 end
154
155 local p_firstpart = lpeg.Cs((1-lpeg.P(","))^0)
156
157 local function addreference(di,references)
158 if references then
159 local reference = references.reference
160 if reference and reference ~= "" then
161 local prefix = references.prefix
162 if prefix and prefix ~= "" then
163 setattribute(di,"prefix",prefix)
164 end
165 setattribute(di,"reference",reference,true)
166 setattribute(di,"explicit",lpegmatch(p_firstpart,reference),true)
167 end
168 local internal = references.internal
169 if internal and internal ~= "" then
170 setattribute(di,"implicit",internal)
171 end
172 end
173 end
174
175 local function link(di,element,n,fulltag)
176
177 local reference = referencehash[fulltag]
178 if reference then
179 adddestination(di,structures.references.get(reference))
180 return true
181 else
182 local data = di.data
183 if data then
184 for i=1,#data do
185 local di = data[i]
186 if di then
187 local fulltag = di.fulltag
188 if fulltag and link(di,element,n,fulltag) then
189 return true
190 end
191 end
192 end
193 end
194 end
195 end
196
197 local function reference(di,element,n,fulltag)
198 local destination = destinationhash[fulltag]
199 if destination then
200 local d = structures.references.internals[destination]
201 if d then
202 addreference(di,d.references)
203 return true
204 else
205 return false
206 end
207 else
208 local data = di.data
209 if data then
210 for i=1,#data do
211 local di = data[i]
212 if di then
213 local fulltag = di.fulltag
214 if fulltag and reference(di,element,n,fulltag) then
215 return true
216 end
217 end
218 end
219 end
220 end
221 end
222
223 extras.adddestination = adddestination
224 extras.addreference = addreference
225
226 extras.link = link
227 extras.reference = reference
228
229end
230
231do
232
233 function fixes.linenumber(di,data,i)
234 local ni = data[i+1]
235 if ni then
236 if ni.data then
237 while true do
238 local d = ni.data[1]
239 if d then
240 local e = d.element
241 if e then
242 if e == "line" or e == "verbatimline" then
243 insert(d.data,1,di)
244 data[i] = false
245 return
246 else
247 ni = d
248 end
249 else
250 return
251 end
252 else
253 return
254 end
255 end
256 end
257 end
258 end
259
260end
261
262 |