slaw 4.2.0 → 5.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 +5 -0
- data/lib/slaw/grammars/schedules.treetop +24 -1
- data/lib/slaw/grammars/schedules_nodes.rb +68 -41
- data/lib/slaw/grammars/za/act_text.xsl +7 -3
- data/lib/slaw/version.rb +1 -1
- data/spec/generator_spec.rb +12 -4
- data/spec/za/act_block_spec.rb +0 -576
- data/spec/za/act_inline_spec.rb +21 -0
- data/spec/za/act_schedules_spec.rb +625 -155
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ed924bc3ba2524cc7c23bf29d69aac408195ae35348e45ca6e7f6d14a018620
|
4
|
+
data.tar.gz: 0ac2bc7e3a1089c56234cabaca35f8961a04db7960655f539412a21293c7ea09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c43f632d52c957e236a117e33d228093f9c41387fca0743b62efa7195f327492a68fb23c215b985ace37f7c89582ad77ad4aecede444da0ace2fd0335437389c
|
7
|
+
data.tar.gz: cc262fe65f346c9bf4b2d959121ec76c091e3aafd1f5f4d8e55e074082c8436f2fe50db5b777b33c7a8c12690fb3fc42f9aa60839fb5ff6733907254e82b0349
|
data/README.md
CHANGED
@@ -81,6 +81,11 @@ You can create your own grammar by creating a gem that provides these files and
|
|
81
81
|
|
82
82
|
## Changelog
|
83
83
|
|
84
|
+
### 5.0.0 (25 Oct 2019)
|
85
|
+
|
86
|
+
* Schedules have a new grammar to make it easier for users to understand headings and subheadings.
|
87
|
+
* The way schedule IDs are generated has been simplified.
|
88
|
+
|
84
89
|
### 4.2.0 (7 Sept 2019)
|
85
90
|
|
86
91
|
* BODY is allowed to be empty
|
@@ -20,9 +20,32 @@ module Slaw
|
|
20
20
|
end
|
21
21
|
|
22
22
|
rule schedule_title
|
23
|
-
|
23
|
+
new_schedule_title / legacy_schedule_title
|
24
|
+
end
|
25
|
+
|
26
|
+
rule new_schedule_title
|
27
|
+
space? 'SCHEDULE'
|
28
|
+
eol
|
29
|
+
heading:schedule_heading?
|
30
|
+
subheading:schedule_subheading?
|
31
|
+
<ScheduleTitle>
|
32
|
+
end
|
33
|
+
|
34
|
+
rule schedule_heading
|
35
|
+
'HEADING' space? title:inline_items? eol
|
36
|
+
end
|
37
|
+
|
38
|
+
rule schedule_subheading
|
39
|
+
'SUBHEADING' space? title:inline_items? eol
|
40
|
+
end
|
41
|
+
|
42
|
+
# The legacy schedule mechanism is retained because it matches PDF imports well.
|
43
|
+
# Subsequent edits will use the new schedule format.
|
44
|
+
rule legacy_schedule_title
|
45
|
+
space? schedule_title_prefix [ \t:.-]* heading:inline_items?
|
24
46
|
subheading:(newline space? inline_items)?
|
25
47
|
eol
|
48
|
+
<LegacyScheduleTitle>
|
26
49
|
end
|
27
50
|
|
28
51
|
rule schedule_title_prefix
|
@@ -18,72 +18,104 @@ module Slaw
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
class
|
22
|
-
def
|
23
|
-
|
24
|
-
|
21
|
+
class ScheduleTitle < Treetop::Runtime::SyntaxNode
|
22
|
+
def heading_text
|
23
|
+
if heading.empty? or heading.title.empty?
|
24
|
+
nil
|
25
|
+
else
|
26
|
+
heading.title.elements
|
27
|
+
.select { |x| x.instance_of? ::Slaw::Grammars::Inlines::InlineItem }
|
28
|
+
.map { |x| x.text_value }
|
29
|
+
.join('')
|
30
|
+
.strip
|
31
|
+
end
|
25
32
|
end
|
26
33
|
|
27
|
-
def
|
28
|
-
if not
|
29
|
-
|
30
|
-
schedule_title.title.elements.select { |x| x.instance_of? ::Slaw::Grammars::Inlines::InlineItem }.map { |x| x.text_value }.join('').strip
|
31
|
-
elsif num
|
32
|
-
"Schedule #{num}"
|
34
|
+
def to_xml(b, idprefix=nil, heading_text)
|
35
|
+
if not heading.empty? and not heading.title.empty?
|
36
|
+
b.heading { |b| heading.title.to_xml(b, idprefix) }
|
33
37
|
else
|
34
|
-
|
38
|
+
b.heading(heading_text)
|
39
|
+
end
|
40
|
+
|
41
|
+
if not subheading.empty? and not subheading.title.empty?
|
42
|
+
b.subheading { |b| subheading.title.to_xml(b, idprefix) }
|
35
43
|
end
|
36
44
|
end
|
45
|
+
end
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
47
|
+
class LegacyScheduleTitle < Treetop::Runtime::SyntaxNode
|
48
|
+
def heading_plain_text
|
49
|
+
heading.elements
|
50
|
+
.select { |x| x.instance_of? ::Slaw::Grammars::Inlines::InlineItem }
|
51
|
+
.map { |x| x.text_value }
|
52
|
+
.join('')
|
53
|
+
.strip
|
54
|
+
end
|
55
|
+
|
56
|
+
def heading_text
|
57
|
+
if heading.empty?
|
42
58
|
nil
|
59
|
+
else
|
60
|
+
text = self.heading_plain_text
|
61
|
+
|
62
|
+
# change legacy titles that are just numbers (eg. the "1" in "Schedule 1")
|
63
|
+
# to "Schedule 1"
|
64
|
+
text = "Schedule #{text}" if /^\d+$/.match?(text)
|
65
|
+
|
66
|
+
text
|
43
67
|
end
|
44
68
|
end
|
45
69
|
|
46
|
-
def
|
47
|
-
if not
|
48
|
-
|
70
|
+
def to_xml(b, idprefix=nil, heading_text)
|
71
|
+
if not heading.empty? and not (/^\d+$/.match?(self.heading_plain_text))
|
72
|
+
b.heading { |b| heading.to_xml(b, idprefix) }
|
49
73
|
else
|
50
|
-
|
74
|
+
b.heading(heading_text)
|
75
|
+
end
|
76
|
+
|
77
|
+
if not subheading.empty?
|
78
|
+
b.subheading { |b| subheading.inline_items.to_xml(b, idprefix) }
|
51
79
|
end
|
52
80
|
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Schedule < Treetop::Runtime::SyntaxNode
|
84
|
+
def schedule_id(heading_text, i)
|
85
|
+
heading_text.downcase().strip().gsub(/[^a-z0-9]/i, '').gsub(/ +/, '')
|
86
|
+
end
|
53
87
|
|
54
88
|
def to_xml(b, idprefix=nil, i=1)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
n = i
|
60
|
-
# make a component name from the schedule title
|
61
|
-
component = self.alias.downcase().strip().gsub(/[^a-z0-9]/i, '').gsub(/ +/, '')
|
89
|
+
heading_text = self.schedule_title.heading_text
|
90
|
+
if not heading_text
|
91
|
+
heading_text = "Schedule"
|
92
|
+
heading_text << " #{i}" if i > 1
|
62
93
|
end
|
63
94
|
|
64
|
-
id
|
95
|
+
# the schedule id is derived from the heading
|
96
|
+
schedule_id = self.schedule_id(heading_text, i)
|
65
97
|
|
66
|
-
b.component(id: "component-#{
|
67
|
-
b.doc_(name:
|
98
|
+
b.component(id: "component-#{schedule_id}") { |b|
|
99
|
+
b.doc_(name: schedule_id) { |b|
|
68
100
|
b.meta { |b|
|
69
101
|
b.identification(source: "#slaw") { |b|
|
70
102
|
b.FRBRWork { |b|
|
71
|
-
b.FRBRthis(value: "#{WORK_URI}/#{
|
103
|
+
b.FRBRthis(value: "#{WORK_URI}/#{schedule_id}")
|
72
104
|
b.FRBRuri(value: WORK_URI)
|
73
|
-
b.FRBRalias(value:
|
105
|
+
b.FRBRalias(value: heading_text)
|
74
106
|
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
75
107
|
b.FRBRauthor(href: '#council')
|
76
108
|
b.FRBRcountry(value: 'za')
|
77
109
|
}
|
78
110
|
b.FRBRExpression { |b|
|
79
|
-
b.FRBRthis(value: "#{EXPRESSION_URI}/#{
|
111
|
+
b.FRBRthis(value: "#{EXPRESSION_URI}/#{schedule_id}")
|
80
112
|
b.FRBRuri(value: EXPRESSION_URI)
|
81
113
|
b.FRBRdate(date: '1980-01-01', name: 'Generation')
|
82
114
|
b.FRBRauthor(href: '#council')
|
83
115
|
b.FRBRlanguage(language: 'eng')
|
84
116
|
}
|
85
117
|
b.FRBRManifestation { |b|
|
86
|
-
b.FRBRthis(value: "#{MANIFESTATION_URI}/#{
|
118
|
+
b.FRBRthis(value: "#{MANIFESTATION_URI}/#{schedule_id}")
|
87
119
|
b.FRBRuri(value: MANIFESTATION_URI)
|
88
120
|
b.FRBRdate(date: Time.now.strftime('%Y-%m-%d'), name: 'Generation')
|
89
121
|
b.FRBRauthor(href: '#slaw')
|
@@ -92,17 +124,12 @@ module Slaw
|
|
92
124
|
}
|
93
125
|
|
94
126
|
b.mainBody { |b|
|
95
|
-
idprefix = "#{
|
127
|
+
idprefix = "#{schedule_id}."
|
96
128
|
|
97
129
|
# there is no good AKN hierarchy container for schedules, so we
|
98
130
|
# use hcontainer instead
|
99
|
-
b.hcontainer(id:
|
100
|
-
|
101
|
-
b.heading { |b| title.to_xml(b, idprefix) }
|
102
|
-
else
|
103
|
-
b.heading(self.alias)
|
104
|
-
end
|
105
|
-
b.subheading { |b| subheading.to_xml(b, idprefix) } if subheading
|
131
|
+
b.hcontainer(id: schedule_id, name: "schedule") { |b|
|
132
|
+
schedule_title.to_xml(b, idprefix, heading_text)
|
106
133
|
body.children.elements.each_with_index { |e| e.to_xml(b, idprefix, i) } if body.is_a? Body
|
107
134
|
}
|
108
135
|
}
|
@@ -24,6 +24,8 @@
|
|
24
24
|
starts-with($prefix, 'CHAPTER ') or
|
25
25
|
starts-with($prefix, 'PART ') or
|
26
26
|
starts-with($prefix, 'SCHEDULE ') or
|
27
|
+
starts-with($prefix, 'HEADING ') or
|
28
|
+
starts-with($prefix, 'SUBHEADING ') or
|
27
29
|
starts-with($prefix, 'LONGTITLE ') or
|
28
30
|
starts-with($prefix, 'CROSSHEADING ') or
|
29
31
|
starts-with($prefix, '{|') or
|
@@ -151,13 +153,14 @@
|
|
151
153
|
|
152
154
|
|
153
155
|
<!-- components/schedules -->
|
154
|
-
<!-- new-style schedules, "
|
156
|
+
<!-- new-style schedules, "hcontainer" elements -->
|
155
157
|
<xsl:template match="a:hcontainer[@name='schedule']">
|
156
|
-
<xsl:text>SCHEDULE
|
158
|
+
<xsl:text>SCHEDULE HEADING </xsl:text>
|
157
159
|
<xsl:apply-templates select="a:heading" />
|
158
160
|
<xsl:text> </xsl:text>
|
159
161
|
|
160
162
|
<xsl:if test="a:subheading">
|
163
|
+
<xsl:text>SUBHEADING </xsl:text>
|
161
164
|
<xsl:apply-templates select="a:subheading" />
|
162
165
|
<xsl:text> </xsl:text>
|
163
166
|
</xsl:if>
|
@@ -169,11 +172,12 @@
|
|
169
172
|
|
170
173
|
<!-- old-style schedules, "article" elements -->
|
171
174
|
<xsl:template match="a:doc/a:mainBody/a:article">
|
172
|
-
<xsl:text>SCHEDULE
|
175
|
+
<xsl:text>SCHEDULE HEADING </xsl:text>
|
173
176
|
<xsl:value-of select="../../a:meta/a:identification/a:FRBRWork/a:FRBRalias/@value" />
|
174
177
|
<xsl:text> </xsl:text>
|
175
178
|
|
176
179
|
<xsl:if test="a:heading">
|
180
|
+
<xsl:text>SUBHEADING </xsl:text>
|
177
181
|
<xsl:apply-templates select="a:heading" />
|
178
182
|
<xsl:text> </xsl:text>
|
179
183
|
</xsl:if>
|
data/lib/slaw/version.rb
CHANGED
data/spec/generator_spec.rb
CHANGED
@@ -54,6 +54,8 @@ Some content.
|
|
54
54
|
<p>participation</p>
|
55
55
|
<p>Schedule 2 ignored</p>
|
56
56
|
<p>Schedules</p>
|
57
|
+
<p>HEADING x</p>
|
58
|
+
<p>SUBHEADING x</p>
|
57
59
|
<p>BODY not escaped</p>
|
58
60
|
<p>BODY</p>
|
59
61
|
<p>PREAMBLE not escaped</p>
|
@@ -88,6 +90,10 @@ participation
|
|
88
90
|
|
89
91
|
Schedules
|
90
92
|
|
93
|
+
\HEADING x
|
94
|
+
|
95
|
+
\SUBHEADING x
|
96
|
+
|
91
97
|
BODY not escaped
|
92
98
|
|
93
99
|
\BODY
|
@@ -242,8 +248,9 @@ three
|
|
242
248
|
doc = subject.generate_from_text(<<EOS
|
243
249
|
1. Something
|
244
250
|
|
245
|
-
|
246
|
-
|
251
|
+
SCHEDULE
|
252
|
+
HEADING First Schedule [[remark]]
|
253
|
+
SUBHEADING Subheading [[another]]
|
247
254
|
|
248
255
|
Subject to approval in terms of this By-Law.
|
249
256
|
EOS
|
@@ -253,8 +260,9 @@ EOS
|
|
253
260
|
|
254
261
|
1. Something
|
255
262
|
|
256
|
-
SCHEDULE
|
257
|
-
|
263
|
+
SCHEDULE
|
264
|
+
HEADING First Schedule [[remark]]
|
265
|
+
SUBHEADING Subheading [[another]]
|
258
266
|
|
259
267
|
Subject to approval in terms of this By-Law.
|
260
268
|
|