slaw 0.17.2 → 1.0.0.alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +9 -2
- data/bin/slaw +2 -19
- data/lib/slaw/generator.rb +21 -6
- data/lib/slaw/grammars/core_nodes.rb +17 -0
- data/lib/slaw/grammars/inlines.treetop +45 -0
- data/lib/slaw/grammars/inlines_nodes.rb +58 -0
- data/lib/slaw/grammars/pl/act.treetop +246 -0
- data/lib/slaw/grammars/pl/act_nodes.rb +469 -0
- data/lib/slaw/grammars/schedules.treetop +33 -0
- data/lib/slaw/grammars/schedules_nodes.rb +107 -0
- data/lib/slaw/grammars/tables.treetop +59 -0
- data/lib/slaw/grammars/tables_nodes.rb +74 -0
- data/lib/slaw/grammars/terminals.treetop +84 -0
- data/lib/slaw/grammars/za/act.treetop +222 -0
- data/lib/slaw/grammars/za/act_nodes.rb +307 -0
- data/lib/slaw/{za → grammars/za}/act_text.xsl +0 -0
- data/lib/slaw/parse/builder.rb +6 -202
- data/lib/slaw/version.rb +1 -1
- data/spec/generator_spec.rb +2 -0
- data/spec/parse/builder_spec.rb +0 -48
- data/spec/pl/act_block_spec.rb +449 -0
- data/spec/za/act_block_spec.rb +5 -3
- data/spec/za/act_inline_spec.rb +2 -0
- data/spec/za/act_schedules_spec.rb +2 -0
- data/spec/za/act_table_spec.rb +2 -0
- metadata +19 -7
- data/lib/slaw/za/act.treetop +0 -393
- data/lib/slaw/za/act_nodes.rb +0 -532
@@ -0,0 +1,469 @@
|
|
1
|
+
require 'slaw/grammars/core_nodes'
|
2
|
+
|
3
|
+
module Slaw
|
4
|
+
module Grammars
|
5
|
+
module PL
|
6
|
+
module Act
|
7
|
+
class Act < Treetop::Runtime::SyntaxNode
|
8
|
+
FRBR_URI = '/pl/act/1980/01'
|
9
|
+
WORK_URI = FRBR_URI
|
10
|
+
EXPRESSION_URI = "#{FRBR_URI}/pol@"
|
11
|
+
MANIFESTATION_URI = EXPRESSION_URI
|
12
|
+
|
13
|
+
def to_xml(b, idprefix=nil, i=0)
|
14
|
+
b.act(contains: "originalVersion") { |b|
|
15
|
+
write_meta(b)
|
16
|
+
write_preface(b)
|
17
|
+
write_preamble(b)
|
18
|
+
write_body(b)
|
19
|
+
}
|
20
|
+
write_schedules(b)
|
21
|
+
end
|
22
|
+
|
23
|
+
def write_meta(b)
|
24
|
+
b.meta { |b|
|
25
|
+
write_identification(b)
|
26
|
+
|
27
|
+
b.references(source: "#this") {
|
28
|
+
b.TLCOrganization(id: 'slaw', href: 'https://github.com/longhotsummer/slaw', showAs: "Slaw")
|
29
|
+
b.TLCOrganization(id: 'council', href: '/ontology/organization/za/council', showAs: "Council")
|
30
|
+
}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_identification(b)
|
35
|
+
b.identification(source: "#slaw") { |b|
|
36
|
+
# use stub values so that we can generate a validating document
|
37
|
+
b.FRBRWork { |b|
|
38
|
+
b.FRBRthis(value: "#{WORK_URI}/main")
|
39
|
+
b.FRBRuri(value: WORK_URI)
|
40
|
+
b.FRBRalias(value: 'Short Title')
|
41
|
+
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
42
|
+
b.FRBRauthor(href: '#council')
|
43
|
+
b.FRBRcountry(value: 'za')
|
44
|
+
}
|
45
|
+
b.FRBRExpression { |b|
|
46
|
+
b.FRBRthis(value: "#{EXPRESSION_URI}/main")
|
47
|
+
b.FRBRuri(value: EXPRESSION_URI)
|
48
|
+
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
49
|
+
b.FRBRauthor(href: '#council')
|
50
|
+
b.FRBRlanguage(language: 'eng')
|
51
|
+
}
|
52
|
+
b.FRBRManifestation { |b|
|
53
|
+
b.FRBRthis(value: "#{MANIFESTATION_URI}/main")
|
54
|
+
b.FRBRuri(value: MANIFESTATION_URI)
|
55
|
+
b.FRBRdate(date: Time.now.strftime('%Y-%m-%d'), name: 'Generation')
|
56
|
+
b.FRBRauthor(href: '#slaw')
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_preface(b)
|
62
|
+
preface.to_xml(b) if preface.respond_to? :to_xml
|
63
|
+
end
|
64
|
+
|
65
|
+
def write_preamble(b)
|
66
|
+
preamble.to_xml(b) if preamble.respond_to? :to_xml
|
67
|
+
end
|
68
|
+
|
69
|
+
def write_body(b)
|
70
|
+
body.to_xml(b)
|
71
|
+
end
|
72
|
+
|
73
|
+
def write_schedules(b)
|
74
|
+
if schedules.text_value != ""
|
75
|
+
schedules.to_xml(b)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Preface < Treetop::Runtime::SyntaxNode
|
81
|
+
def to_xml(b, *args)
|
82
|
+
if text_value != ""
|
83
|
+
b.preface { |b|
|
84
|
+
statements.elements.each { |element|
|
85
|
+
for e in element.elements
|
86
|
+
e.to_xml(b, "") if e.is_a? Slaw::Grammars::Inlines::NakedStatement
|
87
|
+
end
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Preamble < Treetop::Runtime::SyntaxNode
|
95
|
+
def to_xml(b, *args)
|
96
|
+
if text_value != ""
|
97
|
+
b.preamble { |b|
|
98
|
+
statements.elements.each { |e|
|
99
|
+
e.to_xml(b, "")
|
100
|
+
}
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Part < Treetop::Runtime::SyntaxNode
|
107
|
+
def num
|
108
|
+
heading.num
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_xml(b, *args)
|
112
|
+
id = "part-#{num}"
|
113
|
+
|
114
|
+
# include a chapter number in the id if our parent has one
|
115
|
+
if parent and parent.parent.is_a?(Chapter) and parent.parent.num
|
116
|
+
id = "chapter-#{parent.parent.num}.#{id}"
|
117
|
+
end
|
118
|
+
|
119
|
+
b.part(id: id) { |b|
|
120
|
+
heading.to_xml(b)
|
121
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, id + '.', i) }
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class GenericHeading < Treetop::Runtime::SyntaxNode
|
127
|
+
def num
|
128
|
+
prefix.alphanums.text_value
|
129
|
+
end
|
130
|
+
|
131
|
+
def title
|
132
|
+
if heading.text_value and heading.respond_to? :content
|
133
|
+
heading.content.text_value.strip
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_xml(b)
|
138
|
+
b.num(num)
|
139
|
+
b.heading(title) if title
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Division < Treetop::Runtime::SyntaxNode
|
144
|
+
def num
|
145
|
+
heading.num
|
146
|
+
end
|
147
|
+
|
148
|
+
def to_xml(b, *args)
|
149
|
+
id = "division-#{num}"
|
150
|
+
|
151
|
+
b.division(id: id) { |b|
|
152
|
+
heading.to_xml(b)
|
153
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, id + '.', i) }
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class Subdivision < Treetop::Runtime::SyntaxNode
|
159
|
+
def num
|
160
|
+
heading.num
|
161
|
+
end
|
162
|
+
|
163
|
+
def to_xml(b, *args)
|
164
|
+
id = "subdivision-#{num}"
|
165
|
+
|
166
|
+
b.subdivision(id: id) { |b|
|
167
|
+
heading.to_xml(b)
|
168
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, id + '.', i) }
|
169
|
+
}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class Chapter < Treetop::Runtime::SyntaxNode
|
174
|
+
def num
|
175
|
+
heading.num
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_xml(b, *args)
|
179
|
+
id = "chapter-#{num}"
|
180
|
+
|
181
|
+
# TODO: do this for the oddzial and zial
|
182
|
+
# include a part number in the id if our parent has one
|
183
|
+
if parent and parent.parent.is_a?(Part) and parent.parent.num
|
184
|
+
id = "part-#{parent.parent.num}.#{id}"
|
185
|
+
end
|
186
|
+
|
187
|
+
b.chapter(id: id) { |b|
|
188
|
+
heading.to_xml(b)
|
189
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, id + '.', i) }
|
190
|
+
}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class Article < Treetop::Runtime::SyntaxNode
|
195
|
+
def num
|
196
|
+
article_prefix.number_letter.text_value
|
197
|
+
end
|
198
|
+
|
199
|
+
def to_xml(b, *args)
|
200
|
+
id = "article-#{num}"
|
201
|
+
idprefix = "#{id}."
|
202
|
+
|
203
|
+
b.article(id: id) { |b|
|
204
|
+
b.num("#{num}.")
|
205
|
+
|
206
|
+
if !intro.empty?
|
207
|
+
if not children.empty?
|
208
|
+
b.intro { |b| intro.to_xml(b, idprefix) }
|
209
|
+
else
|
210
|
+
b.content { |b| intro.to_xml(b, idprefix) }
|
211
|
+
end
|
212
|
+
elsif children.empty?
|
213
|
+
b.content { |b| b.p }
|
214
|
+
end
|
215
|
+
|
216
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
217
|
+
}
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class Section < Treetop::Runtime::SyntaxNode
|
222
|
+
def num
|
223
|
+
section_prefix.alphanums.text_value
|
224
|
+
end
|
225
|
+
|
226
|
+
def to_xml(b, *args)
|
227
|
+
id = "section-#{num}"
|
228
|
+
idprefix = "#{id}."
|
229
|
+
|
230
|
+
b.section(id: id) { |b|
|
231
|
+
b.num("#{num}.")
|
232
|
+
|
233
|
+
if !intro.empty?
|
234
|
+
if not children.empty?
|
235
|
+
b.intro { |b| intro.to_xml(b, idprefix) }
|
236
|
+
else
|
237
|
+
b.content { |b| intro.to_xml(b, idprefix) }
|
238
|
+
end
|
239
|
+
elsif children.empty?
|
240
|
+
b.content { |b| b.p }
|
241
|
+
end
|
242
|
+
|
243
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
244
|
+
}
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
class Paragraph < Treetop::Runtime::SyntaxNode
|
249
|
+
def num
|
250
|
+
paragraph_prefix.number_letter.text_value
|
251
|
+
end
|
252
|
+
|
253
|
+
def to_xml(b, idprefix='', *args)
|
254
|
+
id = "#{idprefix}paragraph-#{num}"
|
255
|
+
idprefix = id + "."
|
256
|
+
|
257
|
+
b.paragraph(id: id) { |b|
|
258
|
+
b.num(paragraph_prefix.text_value)
|
259
|
+
|
260
|
+
if !intro.empty?
|
261
|
+
if not children.empty?
|
262
|
+
b.intro { |b| intro.to_xml(b, idprefix) }
|
263
|
+
else
|
264
|
+
b.content { |b| intro.to_xml(b, idprefix) }
|
265
|
+
end
|
266
|
+
elsif children.empty?
|
267
|
+
b.content { |b| b.p }
|
268
|
+
end
|
269
|
+
|
270
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
271
|
+
}
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
class Point < Treetop::Runtime::SyntaxNode
|
276
|
+
def num
|
277
|
+
point_prefix.number_letter.text_value
|
278
|
+
end
|
279
|
+
|
280
|
+
def to_xml(b, idprefix='', i)
|
281
|
+
id = "#{idprefix}point-#{num}"
|
282
|
+
idprefix = id + "."
|
283
|
+
|
284
|
+
b.point(id: id) { |b|
|
285
|
+
b.num(point_prefix.text_value)
|
286
|
+
|
287
|
+
if !intro.empty?
|
288
|
+
if not children.empty?
|
289
|
+
b.intro { |b| intro.to_xml(b, idprefix) }
|
290
|
+
else
|
291
|
+
b.content { |b| intro.to_xml(b, idprefix) }
|
292
|
+
end
|
293
|
+
elsif children.empty?
|
294
|
+
b.content { |b| b.p }
|
295
|
+
end
|
296
|
+
|
297
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
298
|
+
}
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class Litera < Treetop::Runtime::SyntaxNode
|
303
|
+
def num
|
304
|
+
litera_prefix.letters.text_value
|
305
|
+
end
|
306
|
+
|
307
|
+
def to_xml(b, idprefix='', i)
|
308
|
+
id = "#{idprefix}list-#{num}"
|
309
|
+
idprefix = id + "."
|
310
|
+
|
311
|
+
b.list(id: id) { |b|
|
312
|
+
b.num(litera_prefix.text_value)
|
313
|
+
|
314
|
+
if !intro.empty?
|
315
|
+
if not children.empty?
|
316
|
+
b.intro { |b| intro.to_xml(b, idprefix) }
|
317
|
+
else
|
318
|
+
b.content { |b| intro.to_xml(b, idprefix) }
|
319
|
+
end
|
320
|
+
elsif children.empty?
|
321
|
+
b.content { |b| b.p }
|
322
|
+
end
|
323
|
+
|
324
|
+
children.elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
325
|
+
}
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
class BlockParagraph < Treetop::Runtime::SyntaxNode
|
330
|
+
def to_xml(b, idprefix='', i=0)
|
331
|
+
id = "#{idprefix}paragraph-0"
|
332
|
+
idprefix = id + "."
|
333
|
+
|
334
|
+
b.paragraph(id: id) { |b|
|
335
|
+
b.content { |b|
|
336
|
+
elements.each_with_index { |e, i| e.to_xml(b, idprefix, i) }
|
337
|
+
}
|
338
|
+
}
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
class Blocklist < Treetop::Runtime::SyntaxNode
|
343
|
+
# Render a block list to xml. If a block is given,
|
344
|
+
# yield to it a builder to insert a listIntroduction node
|
345
|
+
def to_xml(b, idprefix, i=0, &block)
|
346
|
+
id = idprefix + "list#{i}"
|
347
|
+
idprefix = id + '.'
|
348
|
+
|
349
|
+
b.blockList(id: id) { |b|
|
350
|
+
b.listIntroduction { |b| yield b } if block_given?
|
351
|
+
|
352
|
+
elements.each { |e| e.to_xml(b, idprefix) }
|
353
|
+
}
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
class BlocklistItem < Treetop::Runtime::SyntaxNode
|
358
|
+
def num
|
359
|
+
blocklist_item_prefix.text_value
|
360
|
+
end
|
361
|
+
|
362
|
+
def to_xml(b, idprefix)
|
363
|
+
b.item(id: idprefix + num.gsub(/[()]/, '')) { |b|
|
364
|
+
b.num(num)
|
365
|
+
b.p { |b|
|
366
|
+
item_content.clauses.to_xml(b, idprefix) if respond_to? :item_content and item_content.respond_to? :clauses
|
367
|
+
}
|
368
|
+
}
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
class ScheduleContainer < Treetop::Runtime::SyntaxNode
|
373
|
+
def to_xml(b)
|
374
|
+
b.components { |b|
|
375
|
+
schedules.children.elements.each_with_index { |e, i|
|
376
|
+
e.to_xml(b, "", i+1)
|
377
|
+
}
|
378
|
+
}
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
class Schedule < Treetop::Runtime::SyntaxNode
|
383
|
+
def num
|
384
|
+
n = schedule_title.num.text_value
|
385
|
+
return (n && !n.empty?) ? n : nil
|
386
|
+
end
|
387
|
+
|
388
|
+
def alias
|
389
|
+
if not schedule_title.title.text_value.blank?
|
390
|
+
schedule_title.title.text_value
|
391
|
+
elsif num
|
392
|
+
"Schedule #{num}"
|
393
|
+
else
|
394
|
+
"Schedule"
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def heading
|
399
|
+
if schedule_title.heading.respond_to? :content
|
400
|
+
schedule_title.heading.content.text_value
|
401
|
+
else
|
402
|
+
nil
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
def to_xml(b, idprefix=nil, i=1)
|
407
|
+
if num
|
408
|
+
n = num
|
409
|
+
component = "schedule#{n}"
|
410
|
+
else
|
411
|
+
n = i
|
412
|
+
# make a component name from the schedule title
|
413
|
+
component = self.alias.downcase().strip().gsub(/[^a-z0-9]/i, '').gsub(/ +/, '')
|
414
|
+
end
|
415
|
+
|
416
|
+
id = "#{idprefix}#{component}"
|
417
|
+
|
418
|
+
b.component(id: "component-#{id}") { |b|
|
419
|
+
b.doc_(name: component) { |b|
|
420
|
+
b.meta { |b|
|
421
|
+
b.identification(source: "#slaw") { |b|
|
422
|
+
b.FRBRWork { |b|
|
423
|
+
b.FRBRthis(value: "#{Act::WORK_URI}/#{component}")
|
424
|
+
b.FRBRuri(value: Act::WORK_URI)
|
425
|
+
b.FRBRalias(value: self.alias)
|
426
|
+
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
427
|
+
b.FRBRauthor(href: '#council')
|
428
|
+
b.FRBRcountry(value: 'za')
|
429
|
+
}
|
430
|
+
b.FRBRExpression { |b|
|
431
|
+
b.FRBRthis(value: "#{Act::EXPRESSION_URI}/#{component}")
|
432
|
+
b.FRBRuri(value: Act::EXPRESSION_URI)
|
433
|
+
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
434
|
+
b.FRBRauthor(href: '#council')
|
435
|
+
b.FRBRlanguage(language: 'eng')
|
436
|
+
}
|
437
|
+
b.FRBRManifestation { |b|
|
438
|
+
b.FRBRthis(value: "#{Act::MANIFESTATION_URI}/#{component}")
|
439
|
+
b.FRBRuri(value: Act::MANIFESTATION_URI)
|
440
|
+
b.FRBRdate(date: Time.now.strftime('%Y-%m-%d'), name: 'Generation')
|
441
|
+
b.FRBRauthor(href: '#slaw')
|
442
|
+
}
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
b.mainBody { |b|
|
447
|
+
idprefix = "#{id}."
|
448
|
+
|
449
|
+
# there is no good AKN hierarchy container for schedules, so we
|
450
|
+
# just use article because we don't use it anywhere else.
|
451
|
+
b.article(id: id) { |b|
|
452
|
+
b.heading(heading) if heading
|
453
|
+
body.children.elements.each_with_index { |e| e.to_xml(b, idprefix, i) } if body.is_a? Body
|
454
|
+
}
|
455
|
+
}
|
456
|
+
}
|
457
|
+
}
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
class ScheduleStatement < Treetop::Runtime::SyntaxNode
|
462
|
+
def to_xml(b, idprefix)
|
463
|
+
b.p { |b| clauses.to_xml(b, idprefix) } if clauses
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|