Skip to content

Commit 3051af2

Browse files
Merge pull request #2292 from laws-africa/refs
Support "of that Act" for citations
2 parents f407cd2 + db92dde commit 3051af2

File tree

3 files changed

+221
-7
lines changed

3 files changed

+221
-7
lines changed

indigo/analysis/refs/provision_refs.peg

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ grammar ProvisionRefs
5050
/ ((WS* comma)? WS* or__i18n WS+) %and_or
5151
/ (WS* comma WS*) %and_or
5252

53-
target <- of_this / of_the_act / thereof / of
53+
target <- of_this / of_the_act / thereof / of_that_act / of
5454

5555
# of this...
5656
of_this <- comma? WS* (of_this__i18n) WS+ %of_this
@@ -64,6 +64,9 @@ grammar ProvisionRefs
6464
# thereof
6565
thereof <- comma? WS* (thereof__i18n) %thereof
6666

67+
# of that act (synonym for thereof)
68+
of_that_act <- comma? WS* (of_that_act__i18n) %thereof
69+
6770
# this is simply all text after the reference, which could be none. This is required because
6871
# the grammar expects to match the entire input, but we don't care about anything beyond the end
6972
# of the reference.
@@ -79,6 +82,7 @@ grammar ProvisionRefs
7982
and__i18n <- ""
8083
of__i18n <- ""
8184
of_the_act__i18n <- ""
85+
of_that_act__i18n <- ""
8286
of_this__i18n <- ""
8387
or__i18n <- ""
8488
thereof__i18n <- ""
@@ -151,7 +155,11 @@ grammar ProvisionRefs
151155

152156
of_the_act_eng <- `of the Act` / `of the act`
153157
of_the_act_afr <- `van die Wet` / `van die wet`
154-
of_the_act_fra <- `de la loi` / `de la Loi`
158+
of_the_act_fra <- `de la Loi` / `de la loi`
159+
160+
of_that_act_eng <- `of that Act` / `of that act`
161+
of_that_act_afr <- `van daardie Wet` / `van daardie wet`
162+
of_that_act_fra <- `de cette Loi` / `de cette loi`
155163

156164
thereof_eng <- `thereof`
157165
thereof_afr <- `daarvan`

indigo/analysis/refs/provision_refs.py

Lines changed: 207 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ def __init__(self, text, offset, elements):
159159
self.thereof__i18n = elements[2]
160160

161161

162+
class TreeNode24(TreeNode):
163+
def __init__(self, text, offset, elements):
164+
super(TreeNode24, self).__init__(text, offset, elements)
165+
self.of_that_act__i18n = elements[2]
166+
167+
162168
FAILURE = object()
163169

164170

@@ -1089,9 +1095,12 @@ def _read_target(self):
10891095
address0 = self._read_thereof()
10901096
if address0 is FAILURE:
10911097
self._offset = index1
1092-
address0 = self._read_of()
1098+
address0 = self._read_of_that_act()
10931099
if address0 is FAILURE:
10941100
self._offset = index1
1101+
address0 = self._read_of()
1102+
if address0 is FAILURE:
1103+
self._offset = index1
10951104
self._cache['target'][index0] = (address0, self._offset)
10961105
return address0
10971106

@@ -1335,6 +1344,57 @@ def _read_thereof(self):
13351344
self._cache['thereof'][index0] = (address0, self._offset)
13361345
return address0
13371346

1347+
def _read_of_that_act(self):
1348+
address0, index0 = FAILURE, self._offset
1349+
cached = self._cache['of_that_act'].get(index0)
1350+
if cached:
1351+
self._offset = cached[1]
1352+
return cached[0]
1353+
index1, elements0 = self._offset, []
1354+
address1 = FAILURE
1355+
index2 = self._offset
1356+
address1 = self._read_comma()
1357+
if address1 is FAILURE:
1358+
address1 = TreeNode(self._input[index2:index2], index2, [])
1359+
self._offset = index2
1360+
if address1 is not FAILURE:
1361+
elements0.append(address1)
1362+
address2 = FAILURE
1363+
index3, elements1, address3 = self._offset, [], None
1364+
while True:
1365+
address3 = self._read_WS()
1366+
if address3 is not FAILURE:
1367+
elements1.append(address3)
1368+
else:
1369+
break
1370+
if len(elements1) >= 0:
1371+
address2 = TreeNode(self._input[index3:self._offset], index3, elements1)
1372+
self._offset = self._offset
1373+
else:
1374+
address2 = FAILURE
1375+
if address2 is not FAILURE:
1376+
elements0.append(address2)
1377+
address4 = FAILURE
1378+
address4 = self._read_of_that_act__i18n()
1379+
if address4 is not FAILURE:
1380+
elements0.append(address4)
1381+
else:
1382+
elements0 = None
1383+
self._offset = index1
1384+
else:
1385+
elements0 = None
1386+
self._offset = index1
1387+
else:
1388+
elements0 = None
1389+
self._offset = index1
1390+
if elements0 is None:
1391+
address0 = FAILURE
1392+
else:
1393+
address0 = self._actions.thereof(self._input, index1, self._offset, elements0)
1394+
self._offset = self._offset
1395+
self._cache['of_that_act'][index0] = (address0, self._offset)
1396+
return address0
1397+
13381398
def _read_tail(self):
13391399
address0, index0 = FAILURE, self._offset
13401400
cached = self._cache['tail'].get(index0)
@@ -1431,6 +1491,28 @@ def _read_of_the_act__i18n(self):
14311491
self._cache['of_the_act__i18n'][index0] = (address0, self._offset)
14321492
return address0
14331493

1494+
def _read_of_that_act__i18n(self):
1495+
address0, index0 = FAILURE, self._offset
1496+
cached = self._cache['of_that_act__i18n'].get(index0)
1497+
if cached:
1498+
self._offset = cached[1]
1499+
return cached[0]
1500+
chunk0, max0 = None, self._offset + 0
1501+
if max0 <= self._input_size:
1502+
chunk0 = self._input[self._offset:max0]
1503+
if chunk0 == '':
1504+
address0 = TreeNode(self._input[self._offset:self._offset + 0], self._offset, [])
1505+
self._offset = self._offset + 0
1506+
else:
1507+
address0 = FAILURE
1508+
if self._offset > self._failure:
1509+
self._failure = self._offset
1510+
self._expected = []
1511+
if self._offset == self._failure:
1512+
self._expected.append(('ProvisionRefs::of_that_act__i18n', '""'))
1513+
self._cache['of_that_act__i18n'][index0] = (address0, self._offset)
1514+
return address0
1515+
14341516
def _read_of_this__i18n(self):
14351517
address0, index0 = FAILURE, self._offset
14361518
cached = self._cache['of_this__i18n'].get(index0)
@@ -3079,7 +3161,7 @@ def _read_of_the_act_fra(self):
30793161
chunk0, max0 = None, self._offset + 9
30803162
if max0 <= self._input_size:
30813163
chunk0 = self._input[self._offset:max0]
3082-
if chunk0 is not None and chunk0.lower() == 'de la loi'.lower():
3164+
if chunk0 is not None and chunk0.lower() == 'de la Loi'.lower():
30833165
address0 = TreeNode(self._input[self._offset:self._offset + 9], self._offset, [])
30843166
self._offset = self._offset + 9
30853167
else:
@@ -3088,13 +3170,13 @@ def _read_of_the_act_fra(self):
30883170
self._failure = self._offset
30893171
self._expected = []
30903172
if self._offset == self._failure:
3091-
self._expected.append(('ProvisionRefs::of_the_act_fra', '`de la loi`'))
3173+
self._expected.append(('ProvisionRefs::of_the_act_fra', '`de la Loi`'))
30923174
if address0 is FAILURE:
30933175
self._offset = index1
30943176
chunk1, max1 = None, self._offset + 9
30953177
if max1 <= self._input_size:
30963178
chunk1 = self._input[self._offset:max1]
3097-
if chunk1 is not None and chunk1.lower() == 'de la Loi'.lower():
3179+
if chunk1 is not None and chunk1.lower() == 'de la loi'.lower():
30983180
address0 = TreeNode(self._input[self._offset:self._offset + 9], self._offset, [])
30993181
self._offset = self._offset + 9
31003182
else:
@@ -3103,12 +3185,132 @@ def _read_of_the_act_fra(self):
31033185
self._failure = self._offset
31043186
self._expected = []
31053187
if self._offset == self._failure:
3106-
self._expected.append(('ProvisionRefs::of_the_act_fra', '`de la Loi`'))
3188+
self._expected.append(('ProvisionRefs::of_the_act_fra', '`de la loi`'))
31073189
if address0 is FAILURE:
31083190
self._offset = index1
31093191
self._cache['of_the_act_fra'][index0] = (address0, self._offset)
31103192
return address0
31113193

3194+
def _read_of_that_act_eng(self):
3195+
address0, index0 = FAILURE, self._offset
3196+
cached = self._cache['of_that_act_eng'].get(index0)
3197+
if cached:
3198+
self._offset = cached[1]
3199+
return cached[0]
3200+
index1 = self._offset
3201+
chunk0, max0 = None, self._offset + 11
3202+
if max0 <= self._input_size:
3203+
chunk0 = self._input[self._offset:max0]
3204+
if chunk0 is not None and chunk0.lower() == 'of that Act'.lower():
3205+
address0 = TreeNode(self._input[self._offset:self._offset + 11], self._offset, [])
3206+
self._offset = self._offset + 11
3207+
else:
3208+
address0 = FAILURE
3209+
if self._offset > self._failure:
3210+
self._failure = self._offset
3211+
self._expected = []
3212+
if self._offset == self._failure:
3213+
self._expected.append(('ProvisionRefs::of_that_act_eng', '`of that Act`'))
3214+
if address0 is FAILURE:
3215+
self._offset = index1
3216+
chunk1, max1 = None, self._offset + 11
3217+
if max1 <= self._input_size:
3218+
chunk1 = self._input[self._offset:max1]
3219+
if chunk1 is not None and chunk1.lower() == 'of that act'.lower():
3220+
address0 = TreeNode(self._input[self._offset:self._offset + 11], self._offset, [])
3221+
self._offset = self._offset + 11
3222+
else:
3223+
address0 = FAILURE
3224+
if self._offset > self._failure:
3225+
self._failure = self._offset
3226+
self._expected = []
3227+
if self._offset == self._failure:
3228+
self._expected.append(('ProvisionRefs::of_that_act_eng', '`of that act`'))
3229+
if address0 is FAILURE:
3230+
self._offset = index1
3231+
self._cache['of_that_act_eng'][index0] = (address0, self._offset)
3232+
return address0
3233+
3234+
def _read_of_that_act_afr(self):
3235+
address0, index0 = FAILURE, self._offset
3236+
cached = self._cache['of_that_act_afr'].get(index0)
3237+
if cached:
3238+
self._offset = cached[1]
3239+
return cached[0]
3240+
index1 = self._offset
3241+
chunk0, max0 = None, self._offset + 15
3242+
if max0 <= self._input_size:
3243+
chunk0 = self._input[self._offset:max0]
3244+
if chunk0 is not None and chunk0.lower() == 'van daardie Wet'.lower():
3245+
address0 = TreeNode(self._input[self._offset:self._offset + 15], self._offset, [])
3246+
self._offset = self._offset + 15
3247+
else:
3248+
address0 = FAILURE
3249+
if self._offset > self._failure:
3250+
self._failure = self._offset
3251+
self._expected = []
3252+
if self._offset == self._failure:
3253+
self._expected.append(('ProvisionRefs::of_that_act_afr', '`van daardie Wet`'))
3254+
if address0 is FAILURE:
3255+
self._offset = index1
3256+
chunk1, max1 = None, self._offset + 15
3257+
if max1 <= self._input_size:
3258+
chunk1 = self._input[self._offset:max1]
3259+
if chunk1 is not None and chunk1.lower() == 'van daardie wet'.lower():
3260+
address0 = TreeNode(self._input[self._offset:self._offset + 15], self._offset, [])
3261+
self._offset = self._offset + 15
3262+
else:
3263+
address0 = FAILURE
3264+
if self._offset > self._failure:
3265+
self._failure = self._offset
3266+
self._expected = []
3267+
if self._offset == self._failure:
3268+
self._expected.append(('ProvisionRefs::of_that_act_afr', '`van daardie wet`'))
3269+
if address0 is FAILURE:
3270+
self._offset = index1
3271+
self._cache['of_that_act_afr'][index0] = (address0, self._offset)
3272+
return address0
3273+
3274+
def _read_of_that_act_fra(self):
3275+
address0, index0 = FAILURE, self._offset
3276+
cached = self._cache['of_that_act_fra'].get(index0)
3277+
if cached:
3278+
self._offset = cached[1]
3279+
return cached[0]
3280+
index1 = self._offset
3281+
chunk0, max0 = None, self._offset + 12
3282+
if max0 <= self._input_size:
3283+
chunk0 = self._input[self._offset:max0]
3284+
if chunk0 is not None and chunk0.lower() == 'de cette Loi'.lower():
3285+
address0 = TreeNode(self._input[self._offset:self._offset + 12], self._offset, [])
3286+
self._offset = self._offset + 12
3287+
else:
3288+
address0 = FAILURE
3289+
if self._offset > self._failure:
3290+
self._failure = self._offset
3291+
self._expected = []
3292+
if self._offset == self._failure:
3293+
self._expected.append(('ProvisionRefs::of_that_act_fra', '`de cette Loi`'))
3294+
if address0 is FAILURE:
3295+
self._offset = index1
3296+
chunk1, max1 = None, self._offset + 12
3297+
if max1 <= self._input_size:
3298+
chunk1 = self._input[self._offset:max1]
3299+
if chunk1 is not None and chunk1.lower() == 'de cette loi'.lower():
3300+
address0 = TreeNode(self._input[self._offset:self._offset + 12], self._offset, [])
3301+
self._offset = self._offset + 12
3302+
else:
3303+
address0 = FAILURE
3304+
if self._offset > self._failure:
3305+
self._failure = self._offset
3306+
self._expected = []
3307+
if self._offset == self._failure:
3308+
self._expected.append(('ProvisionRefs::of_that_act_fra', '`de cette loi`'))
3309+
if address0 is FAILURE:
3310+
self._offset = index1
3311+
self._cache['of_that_act_fra'][index0] = (address0, self._offset)
3312+
return address0
3313+
31123314
def _read_thereof_eng(self):
31133315
address0, index0 = FAILURE, self._offset
31143316
cached = self._cache['thereof_eng'].get(index0)

indigo/tests/test_provision_refs.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,7 @@ def test_remote_sections(self):
905905
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and section 26(a)(2)(iii)(bb) thereof.</p>
906906
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and section 26(b)(b)(iii)(dd)(A), thereof.</p>
907907
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and <i>given</i> a tail section 31, thereof.</p>
908+
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and <i>given</i> a tail section 31, of that act.</p>
908909
</content>
909910
</section>
910911
"""))
@@ -920,6 +921,7 @@ def test_remote_sections(self):
920921
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and section <ref href="/akn/za/act/2009/1/~sec_26__subsec_a__para_2">26(a)(2)</ref>(iii)(bb) thereof.</p>
921922
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and section <ref href="/akn/za/act/2009/1/~sec_26__subsec_b">26(b)</ref>(b)(iii)(dd)(A), thereof.</p>
922923
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and <i>given</i> a tail section <ref href="/akn/za/act/2009/1/~sec_31">31</ref>, thereof.</p>
924+
<p>Concerning <ref href="/akn/za/act/2009/1">Act 1 of 2009</ref> and <i>given</i> a tail section <ref href="/akn/za/act/2009/1/~sec_31">31</ref>, of that act.</p>
923925
</content>
924926
</section>
925927
"""))
@@ -944,6 +946,7 @@ def test_remote_sections_afr(self):
944946
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en afdeling 26(a)(2)(iii)(bb) daarvan.</p>
945947
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en afdeling 26(b)(b)(iii)(dd)(A), daarvan.</p>
946948
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en <i>gegee</i> 'n stert afdeling 31, daarvan.</p>
949+
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en <i>gegee</i> 'n stert afdeling 31, van daardie wet.</p>
947950
</content>
948951
</section>
949952
"""))
@@ -959,6 +962,7 @@ def test_remote_sections_afr(self):
959962
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en afdeling <ref href="/akn/za/act/2009/1/~sec_26__subsec_a__para_2">26(a)(2)</ref>(iii)(bb) daarvan.</p>
960963
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en afdeling <ref href="/akn/za/act/2009/1/~sec_26__subsec_b">26(b)</ref>(b)(iii)(dd)(A), daarvan.</p>
961964
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en <i>gegee</i> 'n stert afdeling <ref href="/akn/za/act/2009/1/~sec_31">31</ref>, daarvan.</p>
965+
<p>Aangaande <ref href="/akn/za/act/2009/1">Wet 1 van 2009</ref> en <i>gegee</i> 'n stert afdeling <ref href="/akn/za/act/2009/1/~sec_31">31</ref>, van daardie wet.</p>
962966
</content>
963967
</section>
964968
"""))

0 commit comments

Comments
 (0)