slaw 2.2.0 → 3.0.0
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 +10 -0
- data/bin/slaw +5 -0
- data/lib/slaw/grammars/inlines.treetop +24 -6
- data/lib/slaw/grammars/inlines_nodes.rb +36 -14
- data/lib/slaw/grammars/schedules.treetop +2 -2
- data/lib/slaw/grammars/schedules_nodes.rb +3 -3
- data/lib/slaw/grammars/tables.treetop +1 -1
- data/lib/slaw/grammars/tables_nodes.rb +2 -2
- data/lib/slaw/grammars/za/act.treetop +39 -14
- data/lib/slaw/grammars/za/act_nodes.rb +56 -3
- data/lib/slaw/grammars/za/act_text.xsl +32 -5
- data/lib/slaw/version.rb +1 -1
- data/spec/generator_spec.rb +22 -0
- data/spec/za/act_block_spec.rb +167 -50
- data/spec/za/act_inline_spec.rb +171 -31
- data/spec/za/act_schedules_spec.rb +16 -10
- data/spec/za/act_table_spec.rb +12 -6
- metadata +2 -7
- data/lib/slaw/grammars/pl/act.treetop +0 -240
- data/lib/slaw/grammars/pl/act_nodes.rb +0 -441
- data/lib/slaw/grammars/pl/act_text.xsl +0 -271
- data/spec/pl/act_block_spec.rb +0 -677
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 655dd4179f692952514dc6341d332b92bb5ed09f
|
4
|
+
data.tar.gz: f94a6f5d09da791132c901343cdc7c0f228822ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dae4cc911be85f416e81252489f7914d8da142aa0eacf6e92a15c4f314f7569394eb718cad620ccabe098c352c87f02c4a5ae0bdb8cc7430523a4db1f65add54
|
7
|
+
data.tar.gz: ea1bc757d9a29b0f998366f36bd5c5baec6b2b0196705369a06a9ded88aafb1740ac27e364a9ccd1b5320a14a00cb57179911294cd858fd94f5106a2ff5f2d18
|
data/README.md
CHANGED
@@ -84,6 +84,16 @@ You can create your own grammar by creating a gem that provides these files and
|
|
84
84
|
|
85
85
|
## Changelog
|
86
86
|
|
87
|
+
### 3.0.0 (28 March 2019)
|
88
|
+
|
89
|
+
* Inline bold and italics
|
90
|
+
* Support for CROSSHEADING elements using an empty hcontainer until we support AKN 3.0
|
91
|
+
* Support for LONGTITLE in PREFACE
|
92
|
+
* Remarks and references support nested inline elements
|
93
|
+
* BREAKING: `clauses` rule renamed to `inline_elements` so as not to clash with real AKN clauses
|
94
|
+
* BREAKING: `block_paragraphs` rule renamed to `generic_container` and adjusted to be singular to be simpler to understand
|
95
|
+
* BREAKING: un-numbered paragraph elements have new ids, that should not clash with numbered paragraphs from other grammars
|
96
|
+
|
87
97
|
### 2.2.0 (18 March 2019)
|
88
98
|
|
89
99
|
* Schedules use hcontainer, not article
|
data/bin/slaw
CHANGED
@@ -10,18 +10,23 @@ module Slaw
|
|
10
10
|
# inline content
|
11
11
|
|
12
12
|
rule inline_statement
|
13
|
-
space? '\\'?
|
13
|
+
space? '\\'? inline_items eol
|
14
14
|
<NakedStatement>
|
15
15
|
end
|
16
16
|
|
17
17
|
# one or more words, allowing inline elements
|
18
|
-
|
19
|
-
|
20
|
-
<
|
18
|
+
# TODO: this is badly named, a better name would be inline_items
|
19
|
+
rule inline_items
|
20
|
+
inline_item+ <InlineItems>
|
21
|
+
end
|
22
|
+
|
23
|
+
rule inline_item
|
24
|
+
remark / image / ref / bold / italics / [^\n]
|
25
|
+
<InlineItem>
|
21
26
|
end
|
22
27
|
|
23
28
|
rule remark
|
24
|
-
'[[' content:(
|
29
|
+
'[[' content:(!']]' inline_item)+ ']]'
|
25
30
|
<Remark>
|
26
31
|
end
|
27
32
|
|
@@ -34,12 +39,25 @@ module Slaw
|
|
34
39
|
<Image>
|
35
40
|
end
|
36
41
|
|
42
|
+
rule bold
|
43
|
+
# **foo**
|
44
|
+
'**' content:(!'**' inline_item)+ '**'
|
45
|
+
<Bold>
|
46
|
+
end
|
47
|
+
|
48
|
+
rule italics
|
49
|
+
# //foo//
|
50
|
+
'//' content:(!'//' inline_item)+ '//'
|
51
|
+
<Italics>
|
52
|
+
end
|
53
|
+
|
37
54
|
rule ref
|
38
55
|
# links like markdown
|
39
56
|
# eg. [link text](link url)
|
40
|
-
'[' content:(!']('
|
57
|
+
'[' content:(!'](' inline_item)+ '](' href:([^)\n]+) ')'
|
41
58
|
<Ref>
|
42
59
|
end
|
60
|
+
|
43
61
|
end
|
44
62
|
end
|
45
63
|
end
|
@@ -3,22 +3,18 @@ module Slaw
|
|
3
3
|
module Inlines
|
4
4
|
class NakedStatement < Treetop::Runtime::SyntaxNode
|
5
5
|
def to_xml(b, idprefix, i=0)
|
6
|
-
b.p { |b|
|
6
|
+
b.p { |b| inline_items.to_xml(b, idprefix) } if inline_items
|
7
7
|
end
|
8
8
|
|
9
9
|
def content
|
10
|
-
|
10
|
+
inline_items
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
class
|
14
|
+
class InlineItems < Treetop::Runtime::SyntaxNode
|
15
15
|
def to_xml(b, idprefix=nil)
|
16
16
|
for e in elements
|
17
|
-
|
18
|
-
e.to_xml(b, idprefix)
|
19
|
-
else
|
20
|
-
b.text(e.text_value)
|
21
|
-
end
|
17
|
+
e.to_xml(b, idprefix)
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
@@ -28,11 +24,7 @@ module Slaw
|
|
28
24
|
b.remark(status: 'editorial') do |b|
|
29
25
|
b.text('[')
|
30
26
|
for e in content.elements
|
31
|
-
|
32
|
-
e.to_xml(b, idprefix)
|
33
|
-
else
|
34
|
-
b.text(e.text_value)
|
35
|
-
end
|
27
|
+
e.inline_item.to_xml(b, idprefix)
|
36
28
|
end
|
37
29
|
b.text(']')
|
38
30
|
end
|
@@ -47,9 +39,39 @@ module Slaw
|
|
47
39
|
end
|
48
40
|
end
|
49
41
|
|
42
|
+
class InlineItem < Treetop::Runtime::SyntaxNode
|
43
|
+
def to_xml(b, idprefix)
|
44
|
+
b.text(text_value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
50
48
|
class Ref < Treetop::Runtime::SyntaxNode
|
51
49
|
def to_xml(b, idprefix)
|
52
|
-
b.ref(
|
50
|
+
b.ref(href: href.text_value) { |b|
|
51
|
+
for e in content.elements
|
52
|
+
e.inline_item.to_xml(b, idprefix)
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Bold < Treetop::Runtime::SyntaxNode
|
59
|
+
def to_xml(b, idprefix)
|
60
|
+
b.b { |b|
|
61
|
+
for e in content.elements
|
62
|
+
e.inline_item.to_xml(b, idprefix)
|
63
|
+
end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Italics < Treetop::Runtime::SyntaxNode
|
69
|
+
def to_xml(b, idprefix)
|
70
|
+
b.i { |b|
|
71
|
+
for e in content.elements
|
72
|
+
e.inline_item.to_xml(b, idprefix)
|
73
|
+
end
|
74
|
+
}
|
53
75
|
end
|
54
76
|
end
|
55
77
|
|
@@ -20,8 +20,8 @@ module Slaw
|
|
20
20
|
end
|
21
21
|
|
22
22
|
rule schedule_title
|
23
|
-
space? schedule_title_prefix space? "\""? num:alphanums? "\""? [ \t:.-]* title:
|
24
|
-
subheading:(newline space?
|
23
|
+
space? schedule_title_prefix space? "\""? num:alphanums? "\""? [ \t:.-]* title:inline_items?
|
24
|
+
subheading:(newline space? inline_items)?
|
25
25
|
eol
|
26
26
|
end
|
27
27
|
|
@@ -27,7 +27,7 @@ module Slaw
|
|
27
27
|
def alias
|
28
28
|
if not schedule_title.title.text_value.blank?
|
29
29
|
# plain-text elements only
|
30
|
-
schedule_title.title.elements.select { |x|
|
30
|
+
schedule_title.title.elements.select { |x| x.instance_of? ::Slaw::Grammars::Inlines::InlineItem }.map { |x| x.text_value }.join('').strip
|
31
31
|
elsif num
|
32
32
|
"Schedule #{num}"
|
33
33
|
else
|
@@ -45,7 +45,7 @@ module Slaw
|
|
45
45
|
|
46
46
|
def subheading
|
47
47
|
if not schedule_title.subheading.text_value.blank?
|
48
|
-
schedule_title.subheading.
|
48
|
+
schedule_title.subheading.inline_items
|
49
49
|
else
|
50
50
|
nil
|
51
51
|
end
|
@@ -113,7 +113,7 @@ module Slaw
|
|
113
113
|
|
114
114
|
class ScheduleStatement < Treetop::Runtime::SyntaxNode
|
115
115
|
def to_xml(b, idprefix)
|
116
|
-
b.p { |b|
|
116
|
+
b.p { |b| inline_items.to_xml(b, idprefix) } if inline_items
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
@@ -59,12 +59,12 @@ module Slaw
|
|
59
59
|
class TableLine < Treetop::Runtime::SyntaxNode
|
60
60
|
# line of table content
|
61
61
|
def to_xml(b, i, tail)
|
62
|
-
|
62
|
+
inline_items.to_xml(b) unless inline_items.empty?
|
63
63
|
|
64
64
|
# add trailing newlines.
|
65
65
|
# for the first line, eat whitespace at the start
|
66
66
|
# for the last line, eat whitespace at the end
|
67
|
-
if not tail and (i > 0 or not
|
67
|
+
if not tail and (i > 0 or not inline_items.empty?)
|
68
68
|
eol.text_value.count("\n").times { b.eol }
|
69
69
|
end
|
70
70
|
end
|
@@ -16,6 +16,8 @@ module Slaw
|
|
16
16
|
|
17
17
|
########
|
18
18
|
# major containers
|
19
|
+
#
|
20
|
+
# These are AKN's heirarchical containers which wrap actual content.
|
19
21
|
|
20
22
|
rule act
|
21
23
|
empty_line*
|
@@ -28,33 +30,33 @@ module Slaw
|
|
28
30
|
rule preface
|
29
31
|
!'PREAMBLE'
|
30
32
|
('PREFACE'i space? eol)?
|
31
|
-
statements:(!'PREAMBLE'
|
33
|
+
statements:(!'PREAMBLE' preface_statement)* <Preface>
|
32
34
|
end
|
33
35
|
|
34
36
|
rule preamble
|
35
37
|
'PREAMBLE'i space? eol
|
36
|
-
statements:
|
38
|
+
statements:preamble_statement* <Preamble>
|
37
39
|
end
|
38
40
|
|
39
41
|
rule body
|
40
|
-
children:(chapter / part / section / subsection /
|
42
|
+
children:(chapter / part / section / subsection / generic_container)+ <Body>
|
41
43
|
end
|
42
44
|
|
43
45
|
rule chapter
|
44
46
|
heading:chapter_heading
|
45
|
-
children:(part / section / subsection /
|
47
|
+
children:(part / section / subsection / generic_container)*
|
46
48
|
<Chapter>
|
47
49
|
end
|
48
50
|
|
49
51
|
rule part
|
50
52
|
heading:part_heading
|
51
|
-
children:(section / subsection /
|
53
|
+
children:(section / subsection / generic_container)*
|
52
54
|
<Part>
|
53
55
|
end
|
54
56
|
|
55
57
|
rule section
|
56
58
|
section_title
|
57
|
-
children:(subsection /
|
59
|
+
children:(subsection / generic_container)* <Section>
|
58
60
|
end
|
59
61
|
|
60
62
|
rule subsection
|
@@ -66,6 +68,22 @@ module Slaw
|
|
66
68
|
children:block_element* <Subsection>
|
67
69
|
end
|
68
70
|
|
71
|
+
rule generic_container
|
72
|
+
crossheading / block_elements
|
73
|
+
end
|
74
|
+
|
75
|
+
rule crossheading
|
76
|
+
'CROSSHEADING ' inline_items:inline_items eol
|
77
|
+
<Crossheading>
|
78
|
+
end
|
79
|
+
|
80
|
+
# Consecutive non-structured content. We allow many elements
|
81
|
+
# here so that we wrap consecutive block elements in one <content> tag,
|
82
|
+
# rather than multiple containers for each.
|
83
|
+
rule block_elements
|
84
|
+
block_element+ <BlockElements>
|
85
|
+
end
|
86
|
+
|
69
87
|
##########
|
70
88
|
# group elements
|
71
89
|
#
|
@@ -129,10 +147,6 @@ module Slaw
|
|
129
147
|
##########
|
130
148
|
# blocks of content inside containers
|
131
149
|
|
132
|
-
rule block_paragraphs
|
133
|
-
block_element+ <BlockParagraph>
|
134
|
-
end
|
135
|
-
|
136
150
|
rule block_element
|
137
151
|
(table / blocklist / naked_statement)
|
138
152
|
end
|
@@ -149,7 +163,7 @@ module Slaw
|
|
149
163
|
|
150
164
|
rule blocklist_item
|
151
165
|
# TODO: this whitespace should probably be space, to allow empty blocklist items followed by plain text
|
152
|
-
space? blocklist_item_prefix whitespace item_content:(!blocklist_item_prefix
|
166
|
+
space? blocklist_item_prefix whitespace item_content:(!blocklist_item_prefix inline_items:inline_items? eol)? eol?
|
153
167
|
<BlocklistItem>
|
154
168
|
end
|
155
169
|
|
@@ -164,15 +178,26 @@ module Slaw
|
|
164
178
|
# and is ignored. This allows escaping of section headings, etc.
|
165
179
|
|
166
180
|
rule naked_statement
|
167
|
-
space? !(chapter_heading / part_heading / section_title / schedule_title / subsection_prefix) '\\'?
|
181
|
+
space? !(chapter_heading / part_heading / section_title / schedule_title / subsection_prefix / crossheading) '\\'? inline_items eol
|
168
182
|
<NakedStatement>
|
169
183
|
end
|
170
184
|
|
171
|
-
rule
|
172
|
-
space? !(chapter_heading / part_heading / section_title / schedule_title)
|
185
|
+
rule preface_statement
|
186
|
+
space? !(chapter_heading / part_heading / section_title / schedule_title)
|
187
|
+
content:(longtitle / ('\\'? inline_items:inline_items eol))
|
188
|
+
<PrefaceStatement>
|
189
|
+
end
|
190
|
+
|
191
|
+
rule preamble_statement
|
192
|
+
space? !(chapter_heading / part_heading / section_title / schedule_title) '\\'? inline_items eol
|
173
193
|
<NakedStatement>
|
174
194
|
end
|
175
195
|
|
196
|
+
rule longtitle
|
197
|
+
'LONGTITLE ' inline_items:inline_items eol
|
198
|
+
<LongTitle>
|
199
|
+
end
|
200
|
+
|
176
201
|
##########
|
177
202
|
# prefixes
|
178
203
|
|
@@ -91,6 +91,32 @@ module Slaw
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
class PrefaceStatement < Treetop::Runtime::SyntaxNode
|
95
|
+
def to_xml(b, idprefix, i=0)
|
96
|
+
if longtitle
|
97
|
+
longtitle.to_xml(b, idprefix)
|
98
|
+
else
|
99
|
+
b.p { |b| inline_items.to_xml(b, idprefix) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def longtitle
|
104
|
+
self.content if self.content.is_a? LongTitle
|
105
|
+
end
|
106
|
+
|
107
|
+
def inline_items
|
108
|
+
content.inline_items if content.respond_to? :inline_items
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class LongTitle < Treetop::Runtime::SyntaxNode
|
113
|
+
def to_xml(b, idprefix, i=0)
|
114
|
+
b.longTitle { |b|
|
115
|
+
b.p { |b| inline_items.to_xml(b, idprefix) }
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
94
120
|
class Preamble < Treetop::Runtime::SyntaxNode
|
95
121
|
def to_xml(b, *args)
|
96
122
|
if text_value != ""
|
@@ -232,9 +258,17 @@ module Slaw
|
|
232
258
|
end
|
233
259
|
end
|
234
260
|
|
235
|
-
class
|
261
|
+
class BlockElements < Treetop::Runtime::SyntaxNode
|
262
|
+
@@counters = {}
|
263
|
+
|
264
|
+
def self.counters
|
265
|
+
@@counters
|
266
|
+
end
|
267
|
+
|
236
268
|
def to_xml(b, idprefix='', i=0)
|
237
|
-
|
269
|
+
@@counters[idprefix] ||= -1
|
270
|
+
@@counters[idprefix] += 1
|
271
|
+
id = "#{idprefix}paragraph#{@@counters[idprefix]}"
|
238
272
|
idprefix = "#{id}."
|
239
273
|
|
240
274
|
b.paragraph(id: id) { |b|
|
@@ -295,12 +329,31 @@ module Slaw
|
|
295
329
|
b.item(id: idprefix + num.gsub(/[()]/, '')) { |b|
|
296
330
|
b.num(num)
|
297
331
|
b.p { |b|
|
298
|
-
item_content.
|
332
|
+
item_content.inline_items.to_xml(b, idprefix) if respond_to? :item_content and item_content.respond_to? :inline_items
|
299
333
|
}
|
300
334
|
}
|
301
335
|
end
|
302
336
|
end
|
303
337
|
|
338
|
+
class Crossheading < Treetop::Runtime::SyntaxNode
|
339
|
+
@@counters = {}
|
340
|
+
|
341
|
+
def self.counters
|
342
|
+
@@counters
|
343
|
+
end
|
344
|
+
|
345
|
+
def to_xml(b, idprefix, i=0)
|
346
|
+
@@counters[idprefix] ||= -1
|
347
|
+
@@counters[idprefix] += 1
|
348
|
+
id = "#{idprefix}crossheading-#{@@counters[idprefix]}"
|
349
|
+
|
350
|
+
b.hcontainer(id: id, name: 'crossheading') { |b|
|
351
|
+
b.heading { |b|
|
352
|
+
inline_items.to_xml(b, idprefix)
|
353
|
+
}
|
354
|
+
}
|
355
|
+
end
|
356
|
+
end
|
304
357
|
end
|
305
358
|
end
|
306
359
|
end
|
@@ -88,6 +88,20 @@
|
|
88
88
|
<xsl:apply-templates select="./*[not(self::a:num) and not(self::a:heading)]" />
|
89
89
|
</xsl:template>
|
90
90
|
|
91
|
+
<!-- crossheadings -->
|
92
|
+
<xsl:template match="a:hcontainer[@name='crossheading']">
|
93
|
+
<xsl:text>CROSSHEADING </xsl:text>
|
94
|
+
<xsl:apply-templates select="a:heading" />
|
95
|
+
<xsl:text> </xsl:text>
|
96
|
+
</xsl:template>
|
97
|
+
|
98
|
+
<!-- longtitle -->
|
99
|
+
<xsl:template match="a:longTitle">
|
100
|
+
<xsl:text>LONGTITLE </xsl:text>
|
101
|
+
<xsl:apply-templates />
|
102
|
+
<xsl:text> </xsl:text>
|
103
|
+
</xsl:template>
|
104
|
+
|
91
105
|
<!-- p tags must end with a blank line -->
|
92
106
|
<xsl:template match="a:p">
|
93
107
|
<xsl:apply-templates/>
|
@@ -127,7 +141,7 @@
|
|
127
141
|
<!-- components/schedules -->
|
128
142
|
<!-- new-style schedules, "article" elements -->
|
129
143
|
<xsl:template match="a:hcontainer[@name='schedule']">
|
130
|
-
<xsl:text>
|
144
|
+
<xsl:text>SCHEDULE - </xsl:text>
|
131
145
|
<xsl:apply-templates select="a:heading" />
|
132
146
|
<xsl:text> </xsl:text>
|
133
147
|
|
@@ -143,16 +157,17 @@
|
|
143
157
|
|
144
158
|
<!-- old-style schedules, "article" elements -->
|
145
159
|
<xsl:template match="a:doc/a:mainBody/a:article">
|
146
|
-
<xsl:text>
|
160
|
+
<xsl:text>SCHEDULE - </xsl:text>
|
147
161
|
<xsl:value-of select="../../a:meta/a:identification/a:FRBRWork/a:FRBRalias/@value" />
|
148
162
|
<xsl:text> </xsl:text>
|
149
163
|
|
150
|
-
<xsl:if test="
|
151
|
-
|
164
|
+
<xsl:if test="a:heading">
|
165
|
+
<xsl:apply-templates select="a:heading" />
|
152
166
|
<xsl:text> </xsl:text>
|
153
167
|
</xsl:if>
|
154
168
|
|
155
|
-
<xsl:
|
169
|
+
<xsl:text> </xsl:text>
|
170
|
+
<xsl:apply-templates select="./*[not(self::a:heading)]"/>
|
156
171
|
</xsl:template>
|
157
172
|
|
158
173
|
|
@@ -238,6 +253,18 @@
|
|
238
253
|
<xsl:text>)</xsl:text>
|
239
254
|
</xsl:template>
|
240
255
|
|
256
|
+
<xsl:template match="a:i">
|
257
|
+
<xsl:text>//</xsl:text>
|
258
|
+
<xsl:apply-templates />
|
259
|
+
<xsl:text>//</xsl:text>
|
260
|
+
</xsl:template>
|
261
|
+
|
262
|
+
<xsl:template match="a:b">
|
263
|
+
<xsl:text>**</xsl:text>
|
264
|
+
<xsl:apply-templates />
|
265
|
+
<xsl:text>**</xsl:text>
|
266
|
+
</xsl:template>
|
267
|
+
|
241
268
|
<xsl:template match="a:eol">
|
242
269
|
<xsl:text> </xsl:text>
|
243
270
|
</xsl:template>
|