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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 872b9abcfdb880f255e429e07a51f465a86b1ce640639146066220f954baed9d
4
- data.tar.gz: 5cc6f53df26d3893959d056dca4df32fa2328820975b0d3d1f5b02259b7e2bf5
3
+ metadata.gz: 5ed924bc3ba2524cc7c23bf29d69aac408195ae35348e45ca6e7f6d14a018620
4
+ data.tar.gz: 0ac2bc7e3a1089c56234cabaca35f8961a04db7960655f539412a21293c7ea09
5
5
  SHA512:
6
- metadata.gz: ac9b7e1c43cfcabff3035c510f102cf7e0b43148234527ff0f6f093efaf43ef197197d3be07fb492449f96f95629b104ec5bfd33f2b1437302531f81ad8f77cb
7
- data.tar.gz: 0ddb2245be02b53d08fc03bca1be7616a1cd100518686aa555c2a2fdc341408fdb0f59208685b07d15520c01461a116aefadbdc39ef52d3ab152a41288e3815a
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
- space? schedule_title_prefix space? "\""? num:alphanums? "\""? [ \t:.-]* title:inline_items?
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 Schedule < Treetop::Runtime::SyntaxNode
22
- def num
23
- n = schedule_title.num.text_value
24
- return (n && !n.empty?) ? n : nil
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 alias
28
- if not schedule_title.title.text_value.blank?
29
- # plain-text elements only
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
- "Schedule"
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
- def title
39
- if not schedule_title.title.text_value.blank?
40
- schedule_title.title
41
- else
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 subheading
47
- if not schedule_title.subheading.text_value.blank?
48
- schedule_title.subheading.inline_items
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
- nil
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
- if num
56
- n = num
57
- component = "schedule#{n}"
58
- else
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 = "#{idprefix}#{component}"
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-#{id}") { |b|
67
- b.doc_(name: component) { |b|
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}/#{component}")
103
+ b.FRBRthis(value: "#{WORK_URI}/#{schedule_id}")
72
104
  b.FRBRuri(value: WORK_URI)
73
- b.FRBRalias(value: self.alias)
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}/#{component}")
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}/#{component}")
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 = "#{id}."
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: id, name: "schedule") { |b|
100
- if title and title.elements
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, "article" elements -->
156
+ <!-- new-style schedules, "hcontainer" elements -->
155
157
  <xsl:template match="a:hcontainer[@name='schedule']">
156
- <xsl:text>SCHEDULE - </xsl:text>
158
+ <xsl:text>SCHEDULE&#10;HEADING </xsl:text>
157
159
  <xsl:apply-templates select="a:heading" />
158
160
  <xsl:text>&#10;</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>&#10;</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 - </xsl:text>
175
+ <xsl:text>SCHEDULE&#10;HEADING </xsl:text>
173
176
  <xsl:value-of select="../../a:meta/a:identification/a:FRBRWork/a:FRBRalias/@value" />
174
177
  <xsl:text>&#10;</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>&#10;</xsl:text>
179
183
  </xsl:if>
data/lib/slaw/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Slaw
2
- VERSION = "4.2.0"
2
+ VERSION = "5.0.0"
3
3
  end
@@ -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
- Schedule - First Schedule [[remark]]
246
- Subheading [[another]]
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 - First Schedule [[remark]]
257
- Subheading [[another]]
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