slaw 4.2.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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