slaw 10.4.1 → 11.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +22 -0
- data/README.md +17 -0
- data/lib/slaw/extract/html_to_akn_text.xsl +29 -23
- data/lib/slaw/grammars/inlines.treetop +7 -1
- data/lib/slaw/grammars/inlines_nodes.rb +15 -2
- data/lib/slaw/grammars/schedules_nodes.rb +3 -2
- data/lib/slaw/grammars/za/act_nodes.rb +10 -6
- data/lib/slaw/grammars/za/act_text.xsl +156 -34
- data/lib/slaw/version.rb +1 -1
- data/spec/fixtures/roundtrip-escapes.txt +24 -0
- data/spec/generator_spec.rb +81 -15
- data/spec/za/act_block_spec.rb +13 -25
- data/spec/za/act_inline_spec.rb +14 -1
- data/spec/za/act_schedules_spec.rb +42 -42
- data/spec/za/act_table_spec.rb +2 -2
- metadata +6 -4
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 736f598c8a9924a22e2474b2380a229a49188b9fab567280a167cc187554fdb0
|
4
|
+
data.tar.gz: 01de6d73cd7352ff0d6dfbf201b25e7eeb219f6f213dbb8d4c7e05bca40e5b6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faab27a9d122bde77325b295e1d9f705edd314cb9a7abd2cdff8b5e08fd9cdc43333c879e8e7c7e7dd1c7ba9e702457ef683372c890726739f46fc002ee26f3e
|
7
|
+
data.tar.gz: 0c289d9a797771c43be62059cf0b08f4a0730ca637400c2e38aedd2285c193cf1c6ce44763b1a4c6c33335200c00351982ff46002fd60cd5c5e194444b8798b6
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
strategy:
|
10
|
+
matrix:
|
11
|
+
ruby-version: [2.7, 2.6]
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
16
|
+
uses: ruby/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: ${{ matrix.ruby-version }}
|
19
|
+
- name: Install dependencies
|
20
|
+
run: bundle install
|
21
|
+
- name: Run tests
|
22
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -86,6 +86,23 @@ You can create your own grammar by creating a gem that provides these files and
|
|
86
86
|
|
87
87
|
## Changelog
|
88
88
|
|
89
|
+
### 11.0.0 (2021-10-29)
|
90
|
+
|
91
|
+
* Prefix eId attributes in attachments with attachement's eId
|
92
|
+
* Use crossHeading element for crossheadings
|
93
|
+
|
94
|
+
### 10.7.0 (11 June 2021)
|
95
|
+
|
96
|
+
* Support underlines with `__text__`
|
97
|
+
|
98
|
+
### 10.6.0 (10 May 2021)
|
99
|
+
|
100
|
+
* Handle sup and sub when extracting from HTML.
|
101
|
+
|
102
|
+
### 10.5.0 (20 April 2021)
|
103
|
+
|
104
|
+
* Handle escaping inlines when unparsing.
|
105
|
+
|
89
106
|
### 10.4.1 (14 April 2021)
|
90
107
|
|
91
108
|
* Handle escaping in inlines, so that forward slashes in link text are unescaped correctly, eg `[https:\/\/example.com](https://example.com)`
|
@@ -11,9 +11,10 @@
|
|
11
11
|
|
12
12
|
<xsl:template match="head|style|script|link" />
|
13
13
|
|
14
|
-
|
14
|
+
<!-- block containers that end with newlines -->
|
15
|
+
<xsl:template match="ul|ol|section|article|h1|h2|h3|h4|h5">
|
15
16
|
<xsl:apply-templates />
|
16
|
-
<xsl:text> </xsl:text>
|
17
|
+
<xsl:text> </xsl:text>
|
17
18
|
</xsl:template>
|
18
19
|
|
19
20
|
<xsl:template match="ul/li">
|
@@ -23,20 +24,23 @@
|
|
23
24
|
<xsl:text> </xsl:text>
|
24
25
|
</xsl:template>
|
25
26
|
|
27
|
+
<!-- numbered lists should include a number -->
|
26
28
|
<xsl:template match="ol/li">
|
27
|
-
<!-- 1. foo -->
|
29
|
+
<!-- \1. foo -->
|
28
30
|
<xsl:text>\</xsl:text>
|
29
|
-
<xsl:
|
31
|
+
<xsl:choose>
|
32
|
+
<xsl:when test="@value">
|
33
|
+
<xsl:value-of select="@value" />
|
34
|
+
</xsl:when>
|
35
|
+
<xsl:otherwise>
|
36
|
+
<xsl:value-of select="position()" />
|
37
|
+
</xsl:otherwise>
|
38
|
+
</xsl:choose>
|
30
39
|
<xsl:text>. </xsl:text>
|
31
40
|
<xsl:apply-templates />
|
32
41
|
<xsl:text> </xsl:text>
|
33
42
|
</xsl:template>
|
34
43
|
|
35
|
-
<xsl:template match="h1|h2|h3|h4|h5">
|
36
|
-
<xsl:apply-templates />
|
37
|
-
<xsl:text> </xsl:text>
|
38
|
-
</xsl:template>
|
39
|
-
|
40
44
|
<xsl:template match="p|div">
|
41
45
|
<xsl:choose>
|
42
46
|
<xsl:when test="starts-with(., '[') and substring(., string-length(.)) = ']'">
|
@@ -51,32 +55,27 @@
|
|
51
55
|
<xsl:text> </xsl:text>
|
52
56
|
</xsl:template>
|
53
57
|
|
58
|
+
<!-- START tables -->
|
59
|
+
|
54
60
|
<xsl:template match="table">
|
55
61
|
<xsl:text>{| </xsl:text>
|
56
|
-
<xsl:text>
|
57
|
-
|-</xsl:text>
|
62
|
+
<xsl:text> |-</xsl:text>
|
58
63
|
<xsl:apply-templates />
|
59
|
-
<xsl:text>
|
60
|
-
|}
|
61
|
-
|
62
|
-
</xsl:text>
|
64
|
+
<xsl:text> |} </xsl:text>
|
63
65
|
</xsl:template>
|
64
66
|
|
65
67
|
<xsl:template match="tr">
|
66
68
|
<xsl:apply-templates />
|
67
|
-
<xsl:text>
|
68
|
-
|-</xsl:text>
|
69
|
+
<xsl:text> |-</xsl:text>
|
69
70
|
</xsl:template>
|
70
71
|
|
71
72
|
<xsl:template match="th|td">
|
72
73
|
<xsl:choose>
|
73
74
|
<xsl:when test="local-name(.) = 'th'">
|
74
|
-
<xsl:text>
|
75
|
-
! </xsl:text>
|
75
|
+
<xsl:text> ! </xsl:text>
|
76
76
|
</xsl:when>
|
77
77
|
<xsl:when test="local-name(.) = 'td'">
|
78
|
-
<xsl:text>
|
79
|
-
| </xsl:text>
|
78
|
+
<xsl:text> | </xsl:text>
|
80
79
|
</xsl:when>
|
81
80
|
</xsl:choose>
|
82
81
|
|
@@ -118,8 +117,15 @@
|
|
118
117
|
</xsl:template>
|
119
118
|
|
120
119
|
<xsl:template match="br">
|
121
|
-
<xsl:text>
|
122
|
-
</xsl:
|
120
|
+
<xsl:text> </xsl:text>
|
121
|
+
</xsl:template>
|
122
|
+
|
123
|
+
<xsl:template match="sup">
|
124
|
+
<xsl:text>^^</xsl:text><xsl:apply-templates /><xsl:text>^^</xsl:text>
|
125
|
+
</xsl:template>
|
126
|
+
|
127
|
+
<xsl:template match="sub">
|
128
|
+
<xsl:text>_^</xsl:text><xsl:apply-templates /><xsl:text>^_</xsl:text>
|
123
129
|
</xsl:template>
|
124
130
|
|
125
131
|
|
@@ -20,7 +20,7 @@ module Slaw
|
|
20
20
|
end
|
21
21
|
|
22
22
|
rule inline_item
|
23
|
-
remark / image / ref / bold / italics / superscript / subscript / [^\n]
|
23
|
+
remark / image / ref / bold / italics / superscript / subscript / underline / '\\'? [^\n]
|
24
24
|
<InlineItem>
|
25
25
|
end
|
26
26
|
|
@@ -69,6 +69,12 @@ module Slaw
|
|
69
69
|
<Subscript>
|
70
70
|
end
|
71
71
|
|
72
|
+
rule underline
|
73
|
+
# __foo__
|
74
|
+
'__' content:(!'__' inline_item)+ '__'
|
75
|
+
<Underline>
|
76
|
+
end
|
77
|
+
|
72
78
|
end
|
73
79
|
end
|
74
80
|
end
|
@@ -37,8 +37,12 @@ module Slaw
|
|
37
37
|
|
38
38
|
class InlineItem < Treetop::Runtime::SyntaxNode
|
39
39
|
def to_xml(b, idprefix)
|
40
|
-
|
41
|
-
|
40
|
+
if text_value.start_with? '\\'
|
41
|
+
# handle escaped characters: \a -> a
|
42
|
+
b.text(text_value[1..])
|
43
|
+
else
|
44
|
+
b.text(text_value)
|
45
|
+
end
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
@@ -92,6 +96,15 @@ module Slaw
|
|
92
96
|
end
|
93
97
|
end
|
94
98
|
|
99
|
+
class Underline < Treetop::Runtime::SyntaxNode
|
100
|
+
def to_xml(b, idprefix)
|
101
|
+
b.u { |b|
|
102
|
+
for e in content.elements
|
103
|
+
e.inline_item.to_xml(b, idprefix)
|
104
|
+
end
|
105
|
+
}
|
106
|
+
end
|
107
|
+
end
|
95
108
|
end
|
96
109
|
end
|
97
110
|
end
|
@@ -97,8 +97,9 @@ module Slaw
|
|
97
97
|
|
98
98
|
# the schedule id is derived from the heading
|
99
99
|
schedule_id = self.schedule_id(heading_text, i)
|
100
|
+
eId = "att_#{i}"
|
100
101
|
|
101
|
-
b.attachment(eId:
|
102
|
+
b.attachment(eId: eId) { |b|
|
102
103
|
schedule_title.to_xml(b, '', heading_text)
|
103
104
|
b.doc_(name: "schedule") { |b|
|
104
105
|
b.meta { |b|
|
@@ -128,7 +129,7 @@ module Slaw
|
|
128
129
|
}
|
129
130
|
|
130
131
|
b.mainBody { |b|
|
131
|
-
body.children.elements.each_with_index { |e| e.to_xml(b,
|
132
|
+
body.children.elements.each_with_index { |e| e.to_xml(b, eId + "__", i) } if body.is_a? Body
|
132
133
|
}
|
133
134
|
}
|
134
135
|
}
|
@@ -234,8 +234,14 @@ module Slaw
|
|
234
234
|
section_title.num
|
235
235
|
end
|
236
236
|
|
237
|
-
def to_xml(b, *args)
|
237
|
+
def to_xml(b, idprefix='', *args)
|
238
238
|
id = "sec_#{Slaw::Grammars::Counters.clean(num)}"
|
239
|
+
# For historical reasons, we normally ignore the idprefix for sections, assuming
|
240
|
+
# them to be unique. However, in an attachment (eg. a schedule), ensure they
|
241
|
+
# are correctly prefixed
|
242
|
+
# TODO: always include the idprefix
|
243
|
+
id = idprefix + id if idprefix.start_with? 'att_'
|
244
|
+
|
239
245
|
b.section(eId: id) { |b|
|
240
246
|
section_title.to_xml(b)
|
241
247
|
|
@@ -371,13 +377,11 @@ module Slaw
|
|
371
377
|
|
372
378
|
class Crossheading < Treetop::Runtime::SyntaxNode
|
373
379
|
def to_xml(b, idprefix, i=0)
|
374
|
-
cnt = Slaw::Grammars::Counters.counters[idprefix]['
|
375
|
-
id = "#{idprefix}
|
380
|
+
cnt = Slaw::Grammars::Counters.counters[idprefix]['crossHeading'] += 1
|
381
|
+
id = "#{idprefix}crossHeading_#{cnt}"
|
376
382
|
|
377
|
-
b.
|
378
|
-
b.heading { |b|
|
383
|
+
b.crossHeading(eId: id) { |b|
|
379
384
|
inline_items.to_xml(b, idprefix)
|
380
|
-
}
|
381
385
|
}
|
382
386
|
end
|
383
387
|
end
|
@@ -9,31 +9,147 @@
|
|
9
9
|
<xsl:strip-space elements="*"/>
|
10
10
|
<xsl:preserve-space elements="a:a a:affectedDocument a:b a:block a:caption a:change a:concept a:courtType a:date a:def a:del a:docCommittee a:docDate a:docIntroducer a:docJurisdiction a:docNumber a:docProponent a:docPurpose a:docStage a:docStatus a:docTitle a:docType a:docketNumber a:entity a:event a:extractText a:fillIn a:from a:heading a:i a:inline a:ins a:judge a:lawyer a:legislature a:li a:listConclusion a:listIntroduction a:location a:mmod a:mod a:mref a:narrative a:neutralCitation a:num a:object a:omissis a:opinion a:organization a:outcome a:p a:party a:person a:placeholder a:process a:quantity a:quotedText a:recordedTime a:ref a:relatedDocument a:remark a:rmod a:role a:rref a:scene a:session a:shortTitle a:signature a:span a:sub a:subheading a:summary a:sup a:term a:tocItem a:u a:vote"/>
|
11
11
|
|
12
|
+
<!-- replaces "value" in "text" with "replacement" -->
|
13
|
+
<xsl:template name="string-replace-all">
|
14
|
+
<xsl:param name="text" />
|
15
|
+
<xsl:param name="value" />
|
16
|
+
<xsl:param name="replacement" />
|
17
|
+
|
18
|
+
<xsl:choose>
|
19
|
+
<xsl:when test="$text = '' or $value = '' or not($value)">
|
20
|
+
<xsl:value-of select="$text" />
|
21
|
+
</xsl:when>
|
22
|
+
<xsl:when test="contains($text, $value)">
|
23
|
+
<xsl:value-of select="substring-before($text, $value)"/>
|
24
|
+
<xsl:value-of select="$replacement" />
|
25
|
+
<xsl:call-template name="string-replace-all">
|
26
|
+
<xsl:with-param name="text" select="substring-after($text, $value)" />
|
27
|
+
<xsl:with-param name="value" select="$value" />
|
28
|
+
<xsl:with-param name="replacement" select="$replacement" />
|
29
|
+
</xsl:call-template>
|
30
|
+
</xsl:when>
|
31
|
+
<xsl:otherwise>
|
32
|
+
<xsl:value-of select="$text" />
|
33
|
+
</xsl:otherwise>
|
34
|
+
</xsl:choose>
|
35
|
+
</xsl:template>
|
36
|
+
|
37
|
+
<!-- Escape inline markers with a backslash -->
|
38
|
+
<xsl:template name="escape-inlines">
|
39
|
+
<xsl:param name="text" />
|
40
|
+
|
41
|
+
<!-- This works from the inside out, first escaping backslash chars themselves, then escaping
|
42
|
+
the different types of inline markers -->
|
43
|
+
<xsl:call-template name="string-replace-all">
|
44
|
+
<xsl:with-param name="text">
|
45
|
+
<xsl:call-template name="string-replace-all">
|
46
|
+
<xsl:with-param name="text">
|
47
|
+
<xsl:call-template name="string-replace-all">
|
48
|
+
<xsl:with-param name="text">
|
49
|
+
<xsl:call-template name="string-replace-all">
|
50
|
+
<xsl:with-param name="text">
|
51
|
+
<xsl:call-template name="string-replace-all">
|
52
|
+
<xsl:with-param name="text">
|
53
|
+
<xsl:call-template name="string-replace-all">
|
54
|
+
<xsl:with-param name="text">
|
55
|
+
<xsl:call-template name="string-replace-all">
|
56
|
+
<xsl:with-param name="text">
|
57
|
+
<xsl:call-template name="string-replace-all">
|
58
|
+
<xsl:with-param name="text">
|
59
|
+
<xsl:call-template name="string-replace-all">
|
60
|
+
<xsl:with-param name="text">
|
61
|
+
<xsl:call-template name="string-replace-all">
|
62
|
+
<xsl:with-param name="text">
|
63
|
+
<xsl:call-template name="string-replace-all">
|
64
|
+
<xsl:with-param name="text" select="$text" />
|
65
|
+
<xsl:with-param name="value"><xsl:value-of select="'\'" /></xsl:with-param>
|
66
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\\'" /></xsl:with-param>
|
67
|
+
</xsl:call-template>
|
68
|
+
</xsl:with-param>
|
69
|
+
<xsl:with-param name="value"><xsl:value-of select="'**'" /></xsl:with-param>
|
70
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\*\*'" /></xsl:with-param>
|
71
|
+
</xsl:call-template>
|
72
|
+
</xsl:with-param>
|
73
|
+
<xsl:with-param name="value"><xsl:value-of select="'__'" /></xsl:with-param>
|
74
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\_\_'" /></xsl:with-param>
|
75
|
+
</xsl:call-template>
|
76
|
+
</xsl:with-param>
|
77
|
+
<xsl:with-param name="value"><xsl:value-of select="'//'" /></xsl:with-param>
|
78
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\/\/'" /></xsl:with-param>
|
79
|
+
</xsl:call-template>
|
80
|
+
</xsl:with-param>
|
81
|
+
<xsl:with-param name="value"><xsl:value-of select="'_^'" /></xsl:with-param>
|
82
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\_^'" /></xsl:with-param>
|
83
|
+
</xsl:call-template>
|
84
|
+
</xsl:with-param>
|
85
|
+
<xsl:with-param name="value"><xsl:value-of select="'^_'" /></xsl:with-param>
|
86
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\^_'" /></xsl:with-param>
|
87
|
+
</xsl:call-template>
|
88
|
+
</xsl:with-param>
|
89
|
+
<xsl:with-param name="value"><xsl:value-of select="'^^'" /></xsl:with-param>
|
90
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\^\^'" /></xsl:with-param>
|
91
|
+
</xsl:call-template>
|
92
|
+
</xsl:with-param>
|
93
|
+
<xsl:with-param name="value"><xsl:value-of select="'!['" /></xsl:with-param>
|
94
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\!['" /></xsl:with-param>
|
95
|
+
</xsl:call-template>
|
96
|
+
</xsl:with-param>
|
97
|
+
<xsl:with-param name="value"><xsl:value-of select="']('" /></xsl:with-param>
|
98
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\]('" /></xsl:with-param>
|
99
|
+
</xsl:call-template>
|
100
|
+
</xsl:with-param>
|
101
|
+
<xsl:with-param name="value"><xsl:value-of select="'[['" /></xsl:with-param>
|
102
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\[\['" /></xsl:with-param>
|
103
|
+
</xsl:call-template>
|
104
|
+
</xsl:with-param>
|
105
|
+
<xsl:with-param name="value"><xsl:value-of select="']]'" /></xsl:with-param>
|
106
|
+
<xsl:with-param name="replacement"><xsl:value-of select="'\]\]'" /></xsl:with-param>
|
107
|
+
</xsl:call-template>
|
108
|
+
</xsl:template>
|
109
|
+
|
12
110
|
<!-- adds a backslash to the start of the value param, if necessary -->
|
13
|
-
<xsl:template name="escape">
|
111
|
+
<xsl:template name="escape-prefixes">
|
14
112
|
<xsl:param name="value"/>
|
15
113
|
|
16
114
|
<xsl:variable name="prefix" select="translate(substring($value, 1, 13), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
|
17
115
|
<!-- '(' is considered special, so translate numbers into '(' so we can find and escape them -->
|
18
116
|
<xsl:variable name="numprefix" select="translate(substring($value, 1, 3), '1234567890', '((((((((((')" />
|
19
117
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
118
|
+
<xsl:variable name="slash">
|
119
|
+
<!-- p tags must escape initial content that looks like a block element marker -->
|
120
|
+
<xsl:if test="$prefix = 'BODY' or
|
121
|
+
$prefix = 'PREAMBLE' or
|
122
|
+
$prefix = 'PREFACE' or
|
123
|
+
starts-with($prefix, 'CHAPTER ') or
|
124
|
+
starts-with($prefix, 'PART ') or
|
125
|
+
starts-with($prefix, 'SUBPART ') or
|
126
|
+
starts-with($prefix, 'SCHEDULE ') or
|
127
|
+
starts-with($prefix, 'HEADING ') or
|
128
|
+
starts-with($prefix, 'SUBHEADING ') or
|
129
|
+
starts-with($prefix, 'LONGTITLE ') or
|
130
|
+
starts-with($prefix, 'CROSSHEADING ') or
|
131
|
+
starts-with($prefix, '{|') or
|
132
|
+
starts-with($numprefix, '(')">
|
133
|
+
<xsl:value-of select="'\'" />
|
134
|
+
</xsl:if>
|
135
|
+
</xsl:variable>
|
136
|
+
|
137
|
+
<xsl:value-of select="concat($slash, $value)" />
|
138
|
+
</xsl:template>
|
139
|
+
|
140
|
+
<!-- adds a backslash to the start of the text param, if necessary -->
|
141
|
+
<xsl:template name="escape">
|
142
|
+
<xsl:param name="value"/>
|
143
|
+
|
144
|
+
<xsl:variable name="escaped">
|
145
|
+
<xsl:call-template name="escape-inlines">
|
146
|
+
<xsl:with-param name="text" select="$value" />
|
147
|
+
</xsl:call-template>
|
148
|
+
</xsl:variable>
|
149
|
+
|
150
|
+
<xsl:call-template name="escape-prefixes">
|
151
|
+
<xsl:with-param name="value" select="$escaped" />
|
152
|
+
</xsl:call-template>
|
37
153
|
</xsl:template>
|
38
154
|
|
39
155
|
<xsl:template match="a:act">
|
@@ -115,9 +231,9 @@
|
|
115
231
|
</xsl:template>
|
116
232
|
|
117
233
|
<!-- crossheadings -->
|
118
|
-
<xsl:template match="a:
|
234
|
+
<xsl:template match="a:crossHeading">
|
119
235
|
<xsl:text>CROSSHEADING </xsl:text>
|
120
|
-
<xsl:apply-templates
|
236
|
+
<xsl:apply-templates />
|
121
237
|
<xsl:text> </xsl:text>
|
122
238
|
</xsl:template>
|
123
239
|
|
@@ -157,12 +273,19 @@
|
|
157
273
|
</xsl:template>
|
158
274
|
|
159
275
|
<!-- first text nodes of these elems must be escaped if they have special chars -->
|
160
|
-
<xsl:template match="a:p[not(ancestor::a:table)]/text()[
|
276
|
+
<xsl:template match="a:p[not(ancestor::a:table)]/text()[not(preceding-sibling::*)] | a:listIntroduction/text()[not(preceding-sibling::*)] | a:intro/text()[not(preceding-sibling::*)]">
|
161
277
|
<xsl:call-template name="escape">
|
162
278
|
<xsl:with-param name="value" select="." />
|
163
279
|
</xsl:call-template>
|
164
280
|
</xsl:template>
|
165
281
|
|
282
|
+
<!-- escape inlines in text nodes -->
|
283
|
+
<xsl:template match="text()">
|
284
|
+
<xsl:call-template name="escape-inlines">
|
285
|
+
<xsl:with-param name="text" select="." />
|
286
|
+
</xsl:call-template>
|
287
|
+
</xsl:template>
|
288
|
+
|
166
289
|
|
167
290
|
<!-- attachments/schedules -->
|
168
291
|
<xsl:template match="a:attachment">
|
@@ -176,7 +299,7 @@
|
|
176
299
|
<xsl:text> </xsl:text>
|
177
300
|
</xsl:if>
|
178
301
|
|
179
|
-
<xsl:text>

|
302
|
+
<xsl:text> </xsl:text>
|
180
303
|
<xsl:apply-templates select="a:doc/a:mainBody" />
|
181
304
|
</xsl:template>
|
182
305
|
|
@@ -192,31 +315,24 @@
|
|
192
315
|
<xsl:value-of select="." />
|
193
316
|
<xsl:text>" </xsl:text>
|
194
317
|
</xsl:for-each>
|
195
|
-
<xsl:text>
|
196
|
-
|-</xsl:text>
|
318
|
+
<xsl:text> |-</xsl:text>
|
197
319
|
|
198
320
|
<xsl:apply-templates />
|
199
|
-
<xsl:text>
|
200
|
-
|}
|
201
|
-
|
202
|
-
</xsl:text>
|
321
|
+
<xsl:text> |} </xsl:text>
|
203
322
|
</xsl:template>
|
204
323
|
|
205
324
|
<xsl:template match="a:tr">
|
206
325
|
<xsl:apply-templates />
|
207
|
-
<xsl:text>
|
208
|
-
|-</xsl:text>
|
326
|
+
<xsl:text> |-</xsl:text>
|
209
327
|
</xsl:template>
|
210
328
|
|
211
329
|
<xsl:template match="a:th|a:td">
|
212
330
|
<xsl:choose>
|
213
331
|
<xsl:when test="local-name(.) = 'th'">
|
214
|
-
<xsl:text>
|
215
|
-
! </xsl:text>
|
332
|
+
<xsl:text> ! </xsl:text>
|
216
333
|
</xsl:when>
|
217
334
|
<xsl:when test="local-name(.) = 'td'">
|
218
|
-
<xsl:text>
|
219
|
-
| </xsl:text>
|
335
|
+
<xsl:text> | </xsl:text>
|
220
336
|
</xsl:when>
|
221
337
|
</xsl:choose>
|
222
338
|
|
@@ -287,6 +403,12 @@
|
|
287
403
|
<xsl:text>^_</xsl:text>
|
288
404
|
</xsl:template>
|
289
405
|
|
406
|
+
<xsl:template match="a:u">
|
407
|
+
<xsl:text>__</xsl:text>
|
408
|
+
<xsl:apply-templates />
|
409
|
+
<xsl:text>__</xsl:text>
|
410
|
+
</xsl:template>
|
411
|
+
|
290
412
|
<xsl:template match="a:eol">
|
291
413
|
<xsl:text> </xsl:text>
|
292
414
|
</xsl:template>
|
data/lib/slaw/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
BODY
|
2
|
+
|
3
|
+
1. Section that tests escapes
|
4
|
+
|
5
|
+
text \\ with a single slash
|
6
|
+
|
7
|
+
some **inlines \/\/ [with \/\/ slashes](#foo)**
|
8
|
+
|
9
|
+
inlines that \*\* should \/\/ be \[\[ escaped \![ and \]\]
|
10
|
+
|
11
|
+
refs [https:\/\/example.com with ] and and \]( and **nested \*\* stars \*\***](#foo)
|
12
|
+
|
13
|
+
nested ** stars \*\* in bold \*\***
|
14
|
+
|
15
|
+
nested // slashes \/\/ in italics \/\///
|
16
|
+
|
17
|
+
nested ** stars in // italics \*\* // and bold **
|
18
|
+
|
19
|
+
super ^^with \^\^ hats \^\^^^ and sub _^\_^ with \^_ end tokens \^_^_
|
20
|
+
|
21
|
+
underlines __underline with _ underscores__ and \_\_escaped underlines \_\_
|
22
|
+
|
23
|
+
mixed __underline **and \_\_ bold**__
|
24
|
+
|
data/spec/generator_spec.rb
CHANGED
@@ -78,45 +78,81 @@ XML
|
|
78
78
|
|
79
79
|
1. Section
|
80
80
|
|
81
|
-
|
81
|
+
\\Chapter 2 ignored
|
82
82
|
|
83
83
|
Chapters
|
84
84
|
|
85
|
-
|
85
|
+
\\Part 2 ignored
|
86
86
|
|
87
87
|
participation
|
88
88
|
|
89
|
-
|
89
|
+
\\Schedule 2 ignored
|
90
90
|
|
91
91
|
Schedules
|
92
92
|
|
93
|
-
|
93
|
+
\\HEADING x
|
94
94
|
|
95
|
-
|
95
|
+
\\SUBHEADING x
|
96
96
|
|
97
97
|
BODY not escaped
|
98
98
|
|
99
|
-
|
99
|
+
\\BODY
|
100
100
|
|
101
101
|
PREAMBLE not escaped
|
102
102
|
|
103
|
-
|
103
|
+
\\PREAMBLE
|
104
104
|
|
105
105
|
PREFACE not escaped
|
106
106
|
|
107
|
-
|
107
|
+
\\PREFACE
|
108
108
|
|
109
|
-
|
109
|
+
\\2. ignored
|
110
110
|
|
111
|
-
|
111
|
+
\\2.1 ignored
|
112
112
|
|
113
|
-
|
113
|
+
\\(2) ignored
|
114
114
|
|
115
|
-
|
115
|
+
\\(a) ignored
|
116
116
|
|
117
|
-
|
117
|
+
\\(2a) ignored
|
118
118
|
|
119
|
-
|
119
|
+
\\{| ignored
|
120
|
+
|
121
|
+
'
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should escape inlines when unparsing' do
|
125
|
+
doc = xml2doc(section(<<'XML'
|
126
|
+
<num>1.</num>
|
127
|
+
<heading>Section</heading>
|
128
|
+
<paragraph id="section-1.paragraph-0">
|
129
|
+
<content>
|
130
|
+
<p>text \ with a single slash</p>
|
131
|
+
<p>some <b>inlines // <ref href="#foo">with // slashes</ref></b></p>
|
132
|
+
<p>inlines that ** should // be [[ escaped ![ and ]]</p>
|
133
|
+
<p>refs <ref href="#foo">https://example.com with ] and ]( and <b>nested **</b></ref></p>
|
134
|
+
<p>super <sup>with ^^</sup> and sub <sub>_^ with ^_</sub></p>
|
135
|
+
</content>
|
136
|
+
</paragraph>
|
137
|
+
XML
|
138
|
+
))
|
139
|
+
|
140
|
+
text = subject.text_from_act(doc)
|
141
|
+
# NOTE: in single quoted strings, backslash sequences aren't considered special, EXCEPT a double backslash
|
142
|
+
# which is actually a single backslash. So \\ needs to be \\\\ while \* is just \*. The mind boggles.
|
143
|
+
text.should == 'BODY
|
144
|
+
|
145
|
+
1. Section
|
146
|
+
|
147
|
+
text \\\\ with a single slash
|
148
|
+
|
149
|
+
some **inlines \/\/ [with \/\/ slashes](#foo)**
|
150
|
+
|
151
|
+
inlines that \*\* should \/\/ be \[\[ escaped \![ and \]\]
|
152
|
+
|
153
|
+
refs [https:\/\/example.com with ] and \]( and **nested \*\***](#foo)
|
154
|
+
|
155
|
+
super ^^with \^\^^^ and sub _^\_^ with \^_^_
|
120
156
|
|
121
157
|
'
|
122
158
|
end
|
@@ -148,7 +184,7 @@ XML
|
|
148
184
|
|
149
185
|
1. Section
|
150
186
|
|
151
|
-
|
187
|
+
\\(2) A special meeting [[ foo ]]:
|
152
188
|
|
153
189
|
(a) the chairperson so directs; or
|
154
190
|
|
@@ -201,6 +237,27 @@ XML
|
|
201
237
|
|
202
238
|
Hello [there](/za/act/123) friend.
|
203
239
|
|
240
|
+
'
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should unparse underlines correctly' do
|
244
|
+
doc = xml2doc(section(<<XML
|
245
|
+
<num>1.</num>
|
246
|
+
<paragraph id="section-19.paragraph-0">
|
247
|
+
<content>
|
248
|
+
<p>Hello <u>underlined</u>.</p>
|
249
|
+
</content>
|
250
|
+
</paragraph>
|
251
|
+
XML
|
252
|
+
))
|
253
|
+
|
254
|
+
text = subject.text_from_act(doc)
|
255
|
+
text.should == 'BODY
|
256
|
+
|
257
|
+
1.
|
258
|
+
|
259
|
+
Hello __underlined__.
|
260
|
+
|
204
261
|
'
|
205
262
|
end
|
206
263
|
|
@@ -269,4 +326,13 @@ Subject to approval in terms of this By-Law.
|
|
269
326
|
'
|
270
327
|
end
|
271
328
|
end
|
329
|
+
|
330
|
+
describe 'round trip' do
|
331
|
+
it 'should be idempotent for escapes' do
|
332
|
+
text = File.open('spec/fixtures/roundtrip-escapes.txt', 'r').read()
|
333
|
+
act = subject.generate_from_text(text)
|
334
|
+
xml = act.to_xml(encoding: 'utf-8')
|
335
|
+
subject.text_from_act(act).should == text
|
336
|
+
end
|
337
|
+
end
|
272
338
|
end
|
data/spec/za/act_block_spec.rb
CHANGED
@@ -59,9 +59,7 @@ EOS
|
|
59
59
|
<p>Hello there</p>
|
60
60
|
</content>
|
61
61
|
</hcontainer>
|
62
|
-
<
|
63
|
-
<heading>crossheading</heading>
|
64
|
-
</hcontainer>
|
62
|
+
<crossHeading eId="sec_1__crossHeading_1">crossheading</crossHeading>
|
65
63
|
</section>
|
66
64
|
</body>'
|
67
65
|
end
|
@@ -96,9 +94,7 @@ EOS
|
|
96
94
|
</blockList>
|
97
95
|
</content>
|
98
96
|
</hcontainer>
|
99
|
-
<
|
100
|
-
<heading>crossheading</heading>
|
101
|
-
</hcontainer>
|
97
|
+
<crossHeading eId="crossHeading_1">crossheading</crossHeading>
|
102
98
|
<section eId="sec_1">
|
103
99
|
<num>1.</num>
|
104
100
|
<heading>Section</heading>
|
@@ -107,9 +103,7 @@ EOS
|
|
107
103
|
<p>Hello there</p>
|
108
104
|
</content>
|
109
105
|
</hcontainer>
|
110
|
-
<
|
111
|
-
<heading>crossheading</heading>
|
112
|
-
</hcontainer>
|
106
|
+
<crossHeading eId="sec_1__crossHeading_1">crossheading</crossHeading>
|
113
107
|
</section>
|
114
108
|
</body>'
|
115
109
|
end
|
@@ -117,16 +111,19 @@ EOS
|
|
117
111
|
it 'should handle escaped content' do
|
118
112
|
node = parse :body, <<EOS
|
119
113
|
\\1. ignored
|
114
|
+
foo \\\\bar
|
120
115
|
|
121
116
|
\\CROSSHEADING cross\\heading
|
122
117
|
|
123
118
|
1. Sec\\tion
|
124
119
|
\\Chapter 2 ignored
|
120
|
+
Some text with a \\\\real backslash
|
125
121
|
EOS
|
126
122
|
to_xml(node).should == '<body>
|
127
123
|
<hcontainer eId="hcontainer_1" name="hcontainer">
|
128
124
|
<content>
|
129
125
|
<p>1. ignored</p>
|
126
|
+
<p>foo \\bar</p>
|
130
127
|
<p>CROSSHEADING crossheading</p>
|
131
128
|
</content>
|
132
129
|
</hcontainer>
|
@@ -136,6 +133,7 @@ EOS
|
|
136
133
|
<hcontainer eId="sec_1__hcontainer_1" name="hcontainer">
|
137
134
|
<content>
|
138
135
|
<p>Chapter 2 ignored</p>
|
136
|
+
<p>Some text with a \\real backslash</p>
|
139
137
|
</content>
|
140
138
|
</hcontainer>
|
141
139
|
</section>
|
@@ -256,10 +254,8 @@ EOS
|
|
256
254
|
to_xml(node).should == '<chapter eId="chp_2">
|
257
255
|
<num>2</num>
|
258
256
|
<heading>The Chapter Heading</heading>
|
259
|
-
<
|
260
|
-
|
261
|
-
</hcontainer>
|
262
|
-
<hcontainer eId="chp_2__hcontainer_2" name="hcontainer">
|
257
|
+
<crossHeading eId="chp_2__crossHeading_1">crossheading</crossHeading>
|
258
|
+
<hcontainer eId="chp_2__hcontainer_1" name="hcontainer">
|
263
259
|
<content>
|
264
260
|
<p>Some lines at the start of the chapter.</p>
|
265
261
|
</content>
|
@@ -485,9 +481,7 @@ EOS
|
|
485
481
|
to_xml(node).should == '<part eId="part_2">
|
486
482
|
<num>2</num>
|
487
483
|
<heading>The Part Heading</heading>
|
488
|
-
<
|
489
|
-
<heading>crossheading</heading>
|
490
|
-
</hcontainer>
|
484
|
+
<crossHeading eId="part_2__crossHeading_1">crossheading</crossHeading>
|
491
485
|
<section eId="sec_1">
|
492
486
|
<num>1.</num>
|
493
487
|
<heading>Section</heading>
|
@@ -1868,9 +1862,7 @@ EOS
|
|
1868
1862
|
context 'crossheadings' do
|
1869
1863
|
it 'should handle a inline_items in crossheadings' do
|
1870
1864
|
node = parse :crossheading, "CROSSHEADING something [[remark]] [link](/foo/bar)\n"
|
1871
|
-
to_xml(node, '').should == '<
|
1872
|
-
<heading>something <remark status="editorial">[remark]</remark> <ref href="/foo/bar">link</ref></heading>
|
1873
|
-
</hcontainer>'
|
1865
|
+
to_xml(node, '').should == '<crossHeading eId="crossHeading_1">something <remark status="editorial">[remark]</remark> <ref href="/foo/bar">link</ref></crossHeading>'
|
1874
1866
|
end
|
1875
1867
|
|
1876
1868
|
it 'should not be allowed in preface' do
|
@@ -1920,9 +1912,7 @@ Text
|
|
1920
1912
|
<p>Some text</p>
|
1921
1913
|
</preface>
|
1922
1914
|
<body>
|
1923
|
-
<
|
1924
|
-
<heading>In the body</heading>
|
1925
|
-
</hcontainer>
|
1915
|
+
<crossHeading eId="crossHeading_1">In the body</crossHeading>
|
1926
1916
|
<section eId="sec_1">
|
1927
1917
|
<num>1.</num>
|
1928
1918
|
<heading>Section 1</heading>
|
@@ -1983,9 +1973,7 @@ Text
|
|
1983
1973
|
<p>Some text</p>
|
1984
1974
|
</preamble>
|
1985
1975
|
<body>
|
1986
|
-
<
|
1987
|
-
<heading>In the body</heading>
|
1988
|
-
</hcontainer>
|
1976
|
+
<crossHeading eId="crossHeading_1">In the body</crossHeading>
|
1989
1977
|
<section eId="sec_1">
|
1990
1978
|
<num>1.</num>
|
1991
1979
|
<heading>Section 1</heading>
|
data/spec/za/act_inline_spec.rb
CHANGED
@@ -197,7 +197,7 @@ EOS
|
|
197
197
|
</identification>
|
198
198
|
</meta>
|
199
199
|
<mainBody>
|
200
|
-
<hcontainer eId="
|
200
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
201
201
|
<content>
|
202
202
|
<p>
|
203
203
|
<remark status="editorial">[Schedule 1 added by Act 23 of 2004]</remark>
|
@@ -535,4 +535,17 @@ EOS
|
|
535
535
|
end
|
536
536
|
end
|
537
537
|
|
538
|
+
describe 'underline' do
|
539
|
+
it 'should handle underline' do
|
540
|
+
node = parse :generic_container, <<EOS
|
541
|
+
Text __with underline__ and _ under__scores__.
|
542
|
+
EOS
|
543
|
+
to_xml(node, "").should == '<hcontainer eId="hcontainer_1" name="hcontainer">
|
544
|
+
<content>
|
545
|
+
<p>Text <u>with underline</u> and _ under<u>scores</u>.</p>
|
546
|
+
</content>
|
547
|
+
</hcontainer>'
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
538
551
|
end
|
@@ -88,11 +88,11 @@ EOS
|
|
88
88
|
</identification>
|
89
89
|
</meta>
|
90
90
|
<mainBody>
|
91
|
-
<section eId="
|
91
|
+
<section eId="att_1__sec_1">
|
92
92
|
<num>1.</num>
|
93
93
|
<heading>Foo</heading>
|
94
94
|
</section>
|
95
|
-
<section eId="
|
95
|
+
<section eId="att_1__sec_2">
|
96
96
|
<num>2.</num>
|
97
97
|
<heading>Bar</heading>
|
98
98
|
</section>
|
@@ -129,7 +129,7 @@ EOS
|
|
129
129
|
</identification>
|
130
130
|
</meta>
|
131
131
|
<mainBody>
|
132
|
-
<hcontainer eId="
|
132
|
+
<hcontainer eId="att_2__hcontainer_1" name="hcontainer">
|
133
133
|
<content>
|
134
134
|
<p>Baz</p>
|
135
135
|
<p>Boom</p>
|
@@ -186,16 +186,16 @@ EOS
|
|
186
186
|
</identification>
|
187
187
|
</meta>
|
188
188
|
<mainBody>
|
189
|
-
<hcontainer eId="
|
189
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
190
190
|
<content>
|
191
191
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
192
192
|
</content>
|
193
193
|
</hcontainer>
|
194
|
-
<section eId="
|
194
|
+
<section eId="att_1__sec_1">
|
195
195
|
<num>1.</num>
|
196
196
|
<heading>Foo</heading>
|
197
197
|
</section>
|
198
|
-
<section eId="
|
198
|
+
<section eId="att_1__sec_2">
|
199
199
|
<num>2.</num>
|
200
200
|
<heading>Bar</heading>
|
201
201
|
</section>
|
@@ -246,16 +246,16 @@ EOS
|
|
246
246
|
</identification>
|
247
247
|
</meta>
|
248
248
|
<mainBody>
|
249
|
-
<hcontainer eId="
|
249
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
250
250
|
<content>
|
251
251
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
252
252
|
</content>
|
253
253
|
</hcontainer>
|
254
|
-
<section eId="
|
254
|
+
<section eId="att_1__sec_1">
|
255
255
|
<num>1.</num>
|
256
256
|
<heading>Foo</heading>
|
257
257
|
</section>
|
258
|
-
<section eId="
|
258
|
+
<section eId="att_1__sec_2">
|
259
259
|
<num>2.</num>
|
260
260
|
<heading>Bar</heading>
|
261
261
|
</section>
|
@@ -304,16 +304,16 @@ EOS
|
|
304
304
|
</identification>
|
305
305
|
</meta>
|
306
306
|
<mainBody>
|
307
|
-
<hcontainer eId="
|
307
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
308
308
|
<content>
|
309
309
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
310
310
|
</content>
|
311
311
|
</hcontainer>
|
312
|
-
<section eId="
|
312
|
+
<section eId="att_1__sec_1">
|
313
313
|
<num>1.</num>
|
314
314
|
<heading>Foo</heading>
|
315
315
|
</section>
|
316
|
-
<section eId="
|
316
|
+
<section eId="att_1__sec_2">
|
317
317
|
<num>2.</num>
|
318
318
|
<heading>Bar</heading>
|
319
319
|
</section>
|
@@ -372,19 +372,19 @@ EOS
|
|
372
372
|
</identification>
|
373
373
|
</meta>
|
374
374
|
<mainBody>
|
375
|
-
<part eId="
|
375
|
+
<part eId="att_1__part_I">
|
376
376
|
<num>I</num>
|
377
377
|
<heading>Form of authentication statement</heading>
|
378
|
-
<hcontainer eId="
|
378
|
+
<hcontainer eId="att_1__part_I__hcontainer_1" name="hcontainer">
|
379
379
|
<content>
|
380
380
|
<p>This printed impression has been carefully compared by me with the bill which was passed by Parliament and found by me to be a true copy of the bill.</p>
|
381
381
|
</content>
|
382
382
|
</hcontainer>
|
383
383
|
</part>
|
384
|
-
<part eId="
|
384
|
+
<part eId="att_1__part_II">
|
385
385
|
<num>II</num>
|
386
386
|
<heading>Form of statement of the President’s assent.</heading>
|
387
|
-
<hcontainer eId="
|
387
|
+
<hcontainer eId="att_1__part_II__hcontainer_1" name="hcontainer">
|
388
388
|
<content>
|
389
389
|
<p>I signify my assent to the bill and a whole bunch of other stuff.</p>
|
390
390
|
</content>
|
@@ -447,7 +447,7 @@ EOS
|
|
447
447
|
</identification>
|
448
448
|
</meta>
|
449
449
|
<mainBody>
|
450
|
-
<hcontainer eId="
|
450
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
451
451
|
<content>
|
452
452
|
<p>Subject to approval in terms of this By-Law.</p>
|
453
453
|
<p>Schedule another</p>
|
@@ -499,7 +499,7 @@ EOS
|
|
499
499
|
</identification>
|
500
500
|
</meta>
|
501
501
|
<mainBody>
|
502
|
-
<hcontainer eId="
|
502
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
503
503
|
<content>
|
504
504
|
<p>Subject to approval in terms of this By-Law.</p>
|
505
505
|
</content>
|
@@ -550,16 +550,16 @@ EOS
|
|
550
550
|
</identification>
|
551
551
|
</meta>
|
552
552
|
<mainBody>
|
553
|
-
<hcontainer eId="
|
553
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
554
554
|
<content>
|
555
555
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
556
556
|
</content>
|
557
557
|
</hcontainer>
|
558
|
-
<section eId="
|
558
|
+
<section eId="att_1__sec_1">
|
559
559
|
<num>1.</num>
|
560
560
|
<heading>Foo</heading>
|
561
561
|
</section>
|
562
|
-
<section eId="
|
562
|
+
<section eId="att_1__sec_2">
|
563
563
|
<num>2.</num>
|
564
564
|
<heading>Bar</heading>
|
565
565
|
</section>
|
@@ -608,12 +608,12 @@ EOS
|
|
608
608
|
</identification>
|
609
609
|
</meta>
|
610
610
|
<mainBody>
|
611
|
-
<hcontainer eId="
|
611
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
612
612
|
<content>
|
613
613
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
614
614
|
</content>
|
615
615
|
</hcontainer>
|
616
|
-
<section eId="
|
616
|
+
<section eId="att_1__sec_1">
|
617
617
|
<num>1.</num>
|
618
618
|
<heading>Foo</heading>
|
619
619
|
</section>
|
@@ -665,16 +665,16 @@ EOS
|
|
665
665
|
</identification>
|
666
666
|
</meta>
|
667
667
|
<mainBody>
|
668
|
-
<hcontainer eId="
|
668
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
669
669
|
<content>
|
670
670
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
671
671
|
</content>
|
672
672
|
</hcontainer>
|
673
|
-
<section eId="
|
673
|
+
<section eId="att_1__sec_1">
|
674
674
|
<num>1.</num>
|
675
675
|
<heading>Foo</heading>
|
676
676
|
</section>
|
677
|
-
<section eId="
|
677
|
+
<section eId="att_1__sec_2">
|
678
678
|
<num>2.</num>
|
679
679
|
<heading>Bar</heading>
|
680
680
|
</section>
|
@@ -729,11 +729,11 @@ EOS
|
|
729
729
|
</identification>
|
730
730
|
</meta>
|
731
731
|
<mainBody>
|
732
|
-
<section eId="
|
732
|
+
<section eId="att_1__sec_1">
|
733
733
|
<num>1.</num>
|
734
734
|
<heading>Foo</heading>
|
735
735
|
</section>
|
736
|
-
<section eId="
|
736
|
+
<section eId="att_1__sec_2">
|
737
737
|
<num>2.</num>
|
738
738
|
<heading>Bar</heading>
|
739
739
|
</section>
|
@@ -770,7 +770,7 @@ EOS
|
|
770
770
|
</identification>
|
771
771
|
</meta>
|
772
772
|
<mainBody>
|
773
|
-
<hcontainer eId="
|
773
|
+
<hcontainer eId="att_2__hcontainer_1" name="hcontainer">
|
774
774
|
<content>
|
775
775
|
<p>Baz</p>
|
776
776
|
<p>Boom</p>
|
@@ -826,16 +826,16 @@ EOS
|
|
826
826
|
</identification>
|
827
827
|
</meta>
|
828
828
|
<mainBody>
|
829
|
-
<hcontainer eId="
|
829
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
830
830
|
<content>
|
831
831
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
832
832
|
</content>
|
833
833
|
</hcontainer>
|
834
|
-
<section eId="
|
834
|
+
<section eId="att_1__sec_1">
|
835
835
|
<num>1.</num>
|
836
836
|
<heading>Foo</heading>
|
837
837
|
</section>
|
838
|
-
<section eId="
|
838
|
+
<section eId="att_1__sec_2">
|
839
839
|
<num>2.</num>
|
840
840
|
<heading>Bar</heading>
|
841
841
|
</section>
|
@@ -885,16 +885,16 @@ EOS
|
|
885
885
|
</identification>
|
886
886
|
</meta>
|
887
887
|
<mainBody>
|
888
|
-
<hcontainer eId="
|
888
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
889
889
|
<content>
|
890
890
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
891
891
|
</content>
|
892
892
|
</hcontainer>
|
893
|
-
<section eId="
|
893
|
+
<section eId="att_1__sec_1">
|
894
894
|
<num>1.</num>
|
895
895
|
<heading>Foo</heading>
|
896
896
|
</section>
|
897
|
-
<section eId="
|
897
|
+
<section eId="att_1__sec_2">
|
898
898
|
<num>2.</num>
|
899
899
|
<heading>Bar</heading>
|
900
900
|
</section>
|
@@ -942,16 +942,16 @@ EOS
|
|
942
942
|
</identification>
|
943
943
|
</meta>
|
944
944
|
<mainBody>
|
945
|
-
<hcontainer eId="
|
945
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
946
946
|
<content>
|
947
947
|
<p>Subject to approval in terms of this By-Law, the erection:</p>
|
948
948
|
</content>
|
949
949
|
</hcontainer>
|
950
|
-
<section eId="
|
950
|
+
<section eId="att_1__sec_1">
|
951
951
|
<num>1.</num>
|
952
952
|
<heading>Foo</heading>
|
953
953
|
</section>
|
954
|
-
<section eId="
|
954
|
+
<section eId="att_1__sec_2">
|
955
955
|
<num>2.</num>
|
956
956
|
<heading>Bar</heading>
|
957
957
|
</section>
|
@@ -1001,16 +1001,16 @@ EOS
|
|
1001
1001
|
</identification>
|
1002
1002
|
</meta>
|
1003
1003
|
<mainBody>
|
1004
|
-
<hcontainer eId="
|
1004
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
1005
1005
|
<content>
|
1006
1006
|
<p>Other than as is set out hereinbelow, no signs other than locality bound signs, temporary signs including loose portable sign, estate agents signs, newspaper headline posters and posters (the erection of which must comply with the appropriate schedules pertinent thereto) shall be erected on Municipal owned land.</p>
|
1007
1007
|
</content>
|
1008
1008
|
</hcontainer>
|
1009
|
-
<section eId="
|
1009
|
+
<section eId="att_1__sec_1">
|
1010
1010
|
<num>1.</num>
|
1011
1011
|
<heading>Foo</heading>
|
1012
1012
|
</section>
|
1013
|
-
<section eId="
|
1013
|
+
<section eId="att_1__sec_2">
|
1014
1014
|
<num>2.</num>
|
1015
1015
|
<heading>Bar</heading>
|
1016
1016
|
</section>
|
@@ -1060,7 +1060,7 @@ EOS
|
|
1060
1060
|
</identification>
|
1061
1061
|
</meta>
|
1062
1062
|
<mainBody>
|
1063
|
-
<hcontainer eId="
|
1063
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
1064
1064
|
<content>
|
1065
1065
|
<p>Subject to approval in terms of this By-Law.</p>
|
1066
1066
|
</content>
|
data/spec/za/act_table_spec.rb
CHANGED
@@ -298,10 +298,10 @@ EOS
|
|
298
298
|
</identification>
|
299
299
|
</meta>
|
300
300
|
<mainBody>
|
301
|
-
<hcontainer eId="
|
301
|
+
<hcontainer eId="att_1__hcontainer_1" name="hcontainer">
|
302
302
|
<content>
|
303
303
|
<p>Heres a table:</p>
|
304
|
-
<table eId="
|
304
|
+
<table eId="att_1__hcontainer_1__table_1">
|
305
305
|
<tr>
|
306
306
|
<td>
|
307
307
|
<p>r1c1</p>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slaw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 11.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Kempe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -103,9 +103,9 @@ executables:
|
|
103
103
|
extensions: []
|
104
104
|
extra_rdoc_files: []
|
105
105
|
files:
|
106
|
+
- ".github/workflows/test.yml"
|
106
107
|
- ".gitignore"
|
107
108
|
- ".rspec"
|
108
|
-
- ".travis.yml"
|
109
109
|
- Gemfile
|
110
110
|
- LICENSE.txt
|
111
111
|
- README.md
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- spec/counters_spec.rb
|
145
145
|
- spec/extract/extractor_spec.rb
|
146
146
|
- spec/fixtures/community-fire-safety.xml
|
147
|
+
- spec/fixtures/roundtrip-escapes.txt
|
147
148
|
- spec/generator_spec.rb
|
148
149
|
- spec/parse/blocklists_spec.rb
|
149
150
|
- spec/parse/builder_spec.rb
|
@@ -174,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
175
|
- !ruby/object:Gem::Version
|
175
176
|
version: '0'
|
176
177
|
requirements: []
|
177
|
-
rubygems_version: 3.
|
178
|
+
rubygems_version: 3.1.4
|
178
179
|
signing_key:
|
179
180
|
specification_version: 4
|
180
181
|
summary: A lightweight library for using Akoma Ntoso acts in Ruby.
|
@@ -182,6 +183,7 @@ test_files:
|
|
182
183
|
- spec/counters_spec.rb
|
183
184
|
- spec/extract/extractor_spec.rb
|
184
185
|
- spec/fixtures/community-fire-safety.xml
|
186
|
+
- spec/fixtures/roundtrip-escapes.txt
|
185
187
|
- spec/generator_spec.rb
|
186
188
|
- spec/parse/blocklists_spec.rb
|
187
189
|
- spec/parse/builder_spec.rb
|