slaw 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,365 @@
1
+ require 'slaw'
2
+ require 'builder'
3
+
4
+ describe Slaw::Parse::Builder do
5
+ def parse(rule, s)
6
+ subject.text_to_syntax_tree(s, rule)
7
+ end
8
+
9
+ def should_parse(rule, s)
10
+ s << "\n" unless s.end_with?("\n")
11
+ tree = subject.text_to_syntax_tree(s, rule)
12
+
13
+ if not tree
14
+ raise Exception.new(subject.failure_reason || "Couldn't match to grammar") if tree.nil?
15
+ else
16
+ # count an assertion
17
+ tree.should_not be_nil
18
+ end
19
+ end
20
+
21
+ def to_xml(node)
22
+ s = ""
23
+ b = Builder::XmlMarkup.new(target: s)
24
+ node.to_xml(b)
25
+ s
26
+ end
27
+
28
+ #-------------------------------------------------------------------------------
29
+ # Chapters
30
+ #
31
+ describe 'chapters' do
32
+ it 'should handle chapter headers' do
33
+ node = parse :chapter, <<EOS
34
+ ChaPTEr 2
35
+ The Chapter Heading
36
+ 1. Section
37
+ Hello there
38
+ EOS
39
+ node.num.should == "2"
40
+ node.heading.title.should == 'The Chapter Heading'
41
+ to_xml(node).should == "<chapter id=\"chapter-2\"><num>2</num><heading>The Chapter Heading</heading><section id=\"section-1\"><num>1.</num><heading>Section</heading><subsection id=\"section-1.subsection-0\"><content><p>Hello there</p></content></subsection></section></chapter>"
42
+ end
43
+ end
44
+
45
+ #-------------------------------------------------------------------------------
46
+ # Parts
47
+
48
+ describe 'parts' do
49
+ it 'should handle part headers' do
50
+ node = parse :part, <<EOS
51
+ pART 2
52
+ The Part Heading
53
+ 1. Section
54
+ Hello there
55
+ EOS
56
+ node.num.should == "2"
57
+ node.heading.title.should == 'The Part Heading'
58
+ to_xml(node).should == "<part id=\"part-2\"><num>2</num><heading>The Part Heading</heading><section id=\"section-1\"><num>1.</num><heading>Section</heading><subsection id=\"section-1.subsection-0\"><content><p>Hello there</p></content></subsection></section></part>"
59
+ end
60
+
61
+ it 'should handle parts and odd section numbers' do
62
+ subject.parse_options = {section_number_after_title: false}
63
+ node = parse :bylaw, <<EOS
64
+ PART 1
65
+ PREVENTION AND SUPPRESSION OF HEALTH NUISANCES
66
+ 1.
67
+ No owner or occupier of any shop or business premises or vacant land adjoining a shop or business premises shall cause a health nuisance.
68
+ EOS
69
+
70
+ part = node.elements[1].elements[0].elements[1].elements[0]
71
+ part.heading.num.should == "1"
72
+ part.heading.title.should == "PREVENTION AND SUPPRESSION OF HEALTH NUISANCES"
73
+
74
+ section = part.elements[1].elements[0]
75
+ section.section_title.title.should == ""
76
+ section.section_title.section_title_prefix.number_letter.text_value.should == "1"
77
+ end
78
+ end
79
+
80
+ #-------------------------------------------------------------------------------
81
+ # Subsections
82
+
83
+ describe 'subsection' do
84
+ it 'should handle basic subsections' do
85
+ should_parse :subsection, <<EOS
86
+ (2) foo bar
87
+ EOS
88
+ end
89
+
90
+ it 'should handle a naked statement' do
91
+ should_parse :subsection, 'naked statement'
92
+ end
93
+
94
+ it 'should handle a naked statement and blocklist' do
95
+ node = parse :subsection, <<EOS
96
+ naked statement (c) blah
97
+ (a) foo
98
+ (b) bar
99
+ EOS
100
+ node.statement.content.text_value.should == "naked statement (c) blah"
101
+ node.blocklist.elements.first.num.should == "(a)"
102
+ end
103
+
104
+ it 'should handle a blocklist' do
105
+ node = parse :subsection, <<EOS
106
+ (2) title
107
+ (a) one
108
+ (b) two
109
+ (c) three
110
+ (i) four
111
+ EOS
112
+ node.statement.num.should == "(2)"
113
+ node.statement.content.text_value.should == "title"
114
+ end
115
+
116
+ it 'should handle a subsection that dives straight into a list' do
117
+ node = parse(:subsection, <<EOS
118
+ (1) (a) one
119
+ (b) two
120
+ (c) three
121
+ (i) four
122
+ EOS
123
+ )
124
+ node.statement.content.should be_nil
125
+ node.blocklist.elements.first.num.should == "(a)"
126
+ node.blocklist.elements.first.content.should == "one"
127
+ end
128
+
129
+ it 'should handle a blocklist that dives straight into another list' do
130
+ node = parse(:subsection, <<EOS
131
+ (1) here's my really cool list,
132
+ (a) one
133
+ (b) (i) single
134
+ (ii) double
135
+ EOS
136
+ )
137
+ node.statement.content.text_value.should == "here's my really cool list,"
138
+ node.blocklist.elements.first.num.should == "(a)"
139
+ node.blocklist.elements.first.content.should == "one"
140
+ node.blocklist.elements[1].num.should == "(b)"
141
+ node.blocklist.elements[1].content.should be_nil
142
+ node.blocklist.elements[2].num.should == "(i)"
143
+ node.blocklist.elements[2].content.should == "single"
144
+ end
145
+
146
+ context 'dotted numbers' do
147
+ it 'should handle dotted number subsection numbers' do
148
+ node = parse :subsection, <<EOS
149
+ 9.9. foo
150
+ EOS
151
+ node.statement.content.text_value.should == "foo"
152
+ node.statement.num.should == "9.9"
153
+ end
154
+
155
+ it 'should handle dotted number sublists' do
156
+ node = parse(:subsection, <<EOS
157
+ 9.9 foo
158
+ 9.9.1 item1
159
+ 9.9.2 item2
160
+ 9.9.2.1 item3
161
+ EOS
162
+ )
163
+ node.statement.content.text_value.should == "foo"
164
+ node.blocklist.elements.first.num.should == "9.9.1"
165
+ node.blocklist.elements.first.content.should == "item1"
166
+
167
+ node.blocklist.elements[2].num.should == "9.9.2.1"
168
+ node.blocklist.elements[2].content.should == "item3"
169
+ end
170
+ end
171
+ end
172
+
173
+ #-------------------------------------------------------------------------------
174
+ # Numbered statements
175
+
176
+ describe 'numbered_statement' do
177
+ it 'should handle basic numbered statements' do
178
+ should_parse :numbered_statement, '(1) foo bar'
179
+ should_parse :numbered_statement, '(1a) foo bar'
180
+ end
181
+ end
182
+
183
+ #-------------------------------------------------------------------------------
184
+ # Preamble
185
+
186
+ context 'preamble' do
187
+ it 'should consider any text at the start to be preamble' do
188
+ node = parse :bylaw, <<EOS
189
+ foo
190
+ bar
191
+ (1) stuff
192
+ (2) more stuff
193
+ baz
194
+ 1. Section
195
+ (1) hello
196
+ EOS
197
+
198
+ node.elements.first.text_value.should == "foo
199
+ bar
200
+ (1) stuff
201
+ (2) more stuff
202
+ baz
203
+ "
204
+ end
205
+
206
+ it 'should support an optional preamble' do
207
+ node = parse :bylaw, <<EOS
208
+ PREAMBLE
209
+ foo
210
+ 1. Section
211
+ (1) hello
212
+ EOS
213
+
214
+ node.elements.first.text_value.should == "PREAMBLE\nfoo\n"
215
+ end
216
+
217
+ it 'should support no preamble' do
218
+ node = parse :bylaw, <<EOS
219
+ 1. Section
220
+ bar
221
+ EOS
222
+
223
+ node.elements.first.text_value.should == ""
224
+ end
225
+ end
226
+
227
+
228
+ #-------------------------------------------------------------------------------
229
+ # Sections
230
+
231
+ context 'sections' do
232
+ it 'should handle section numbers after title' do
233
+ subject.parse_options = {section_number_after_title: true}
234
+ node = parse :bylaw, <<EOS
235
+ Section
236
+ 1. (1) hello
237
+ EOS
238
+
239
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
240
+ section.section_title.content.text_value.should == "Section"
241
+ section.section_title.section_title_prefix.number_letter.text_value.should == "1"
242
+ end
243
+
244
+ it 'should handle section numbers before title' do
245
+ subject.parse_options = {section_number_after_title: false}
246
+ node = parse :bylaw, <<EOS
247
+ 1. Section
248
+ (1) hello
249
+ EOS
250
+
251
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
252
+ section.section_title.title.should == "Section"
253
+ section.section_title.num.should == "1"
254
+ end
255
+
256
+ it 'should handle section numbers without a dot' do
257
+ subject.parse_options = {section_number_after_title: false}
258
+ node = parse :bylaw, <<EOS
259
+ 1 A section
260
+ (1) hello
261
+ 2 Another section
262
+ (2) Another line
263
+ EOS
264
+
265
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
266
+ section.section_title.title.should == "A section"
267
+ section.section_title.num.should == "1"
268
+
269
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[1]
270
+ section.section_title.title.should == "Another section"
271
+ section.section_title.num.should == "2"
272
+ end
273
+
274
+ it 'should handle sections without titles' do
275
+ subject.parse_options = {section_number_after_title: false}
276
+ node = parse :bylaw, <<EOS
277
+ 1. No owner or occupier of any shop or business premises or vacant land, blah blah
278
+ 2. Notwithstanding the provision of any other By-law or legislation no person shall—
279
+ EOS
280
+
281
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
282
+ section.section_title.title.should == "No owner or occupier of any shop or business premises or vacant land, blah blah"
283
+ section.section_title.num.should == "1"
284
+
285
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[1]
286
+ section.section_title.title.should == ""
287
+ section.section_title.num.should == "2"
288
+ section.subsections.elements[0].statement.content.text_value.should == "Notwithstanding the provision of any other By-law or legislation no person shall—"
289
+ end
290
+
291
+ it 'should handle sections without titles and with subsections' do
292
+ subject.parse_options = {section_number_after_title: false}
293
+ node = parse :bylaw, <<EOS
294
+ 10. (1) Transporters must remove medical waste.
295
+ (2) Without limiting generality, stuff.
296
+ EOS
297
+
298
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
299
+ section.section_title.title.should == ""
300
+ section.section_title.num.should == "10"
301
+ section.subsections.elements[0].statement.num.should == "(1)"
302
+ section.subsections.elements[0].statement.content.text_value.should == "Transporters must remove medical waste."
303
+ end
304
+
305
+ it 'should realise complex section titles are actually section content' do
306
+ subject.parse_options = {section_number_after_title: false}
307
+ node = parse :bylaw, <<EOS
308
+ 10. The owner of any premises which is let or sublet to more than one tenant, shall maintain at all times in a clean and sanitary condition every part of such premises as may be used in common by more than one tenant.
309
+ 11. No person shall keep, cause or suffer to be kept any factory or trade premises so as to cause or give rise to smells or effluvia that constitute a health nuisance.
310
+ EOS
311
+
312
+ section = node.elements[1].elements[0].elements[1].elements[0].elements[1].elements[0]
313
+ section.section_title.title.should == ""
314
+ section.section_title.num.should == "10"
315
+ section.subsections.elements[0].statement.content.text_value.should == "The owner of any premises which is let or sublet to more than one tenant, shall maintain at all times in a clean and sanitary condition every part of such premises as may be used in common by more than one tenant."
316
+ end
317
+ end
318
+
319
+ #-------------------------------------------------------------------------------
320
+ # schedules
321
+
322
+ context 'schedules' do
323
+ it 'should handle a simple schedule' do
324
+ node = parse :schedules, <<EOS
325
+ Schedule
326
+ Subject to approval in terms of this By-Law, the erection:
327
+ 1. Foo
328
+ 2. Bar
329
+ EOS
330
+
331
+ sched = node.schedules.elements[0]
332
+ sched.schedule_heading.schedule_heading_prefix.text_value.should == "Schedule"
333
+ sched.statements.elements[0].content.text_value.should == "Subject to approval in terms of this By-Law, the erection:"
334
+ sched.statements.elements[1].content.text_value.should == "1. Foo"
335
+ sched.statements.elements[2].content.text_value.should == "2. Bar"
336
+ end
337
+
338
+ it 'should handle many schedules' do
339
+ node = parse :schedules, <<EOS
340
+ Schedule "1"
341
+ A Title
342
+ 1. Foo
343
+ 2. Bar
344
+ Schedule 2
345
+ Another Title
346
+ Baz
347
+ Boom
348
+ EOS
349
+
350
+ sched = node.schedules.elements[0]
351
+ sched.schedule_heading.schedule_heading_prefix.text_value.should == "Schedule"
352
+ sched.schedule_heading.schedule_title.content.text_value.should == "A Title"
353
+ sched.schedule_heading.num.text_value.should == "1"
354
+ sched.statements.elements[0].content.text_value.should == "1. Foo"
355
+ sched.statements.elements[1].content.text_value.should == "2. Bar"
356
+
357
+ sched = node.schedules.elements[1]
358
+ sched.schedule_heading.schedule_heading_prefix.text_value.should == "Schedule"
359
+ sched.schedule_heading.schedule_title.content.text_value.should == "Another Title"
360
+ sched.schedule_heading.num.text_value.should == "2"
361
+ sched.statements.elements[0].content.text_value.should == "Baz"
362
+ sched.statements.elements[1].content.text_value.should == "Boom"
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ require 'slaw'
4
+
5
+ describe Slaw::Parse::Cleanser do
6
+ describe '#remove_empty_lines' do
7
+ it 'should remove empty lines' do
8
+ subject.remove_empty_lines("foo\n \n\n bar\n\n\nbaz\n").should == "foo\n bar\nbaz"
9
+ end
10
+ end
11
+
12
+ describe '#unbreak_lines' do
13
+ it 'should unbreak simple lines' do
14
+ subject.unbreak_lines("""
15
+ 8.2.3 an additional fee or tariff, which is
16
+ to be determined by the City in its
17
+ sole discretion, in respect of additional
18
+ costs incurred or services.
19
+ 8.3 In the event that a person qualifies for
20
+ a permit, but has motivated in writing
21
+ the inability to pay the fee contemplated.""").should == """
22
+ 8.2.3 an additional fee or tariff, which is to be determined by the City in its sole discretion, in respect of additional costs incurred or services.
23
+ 8.3 In the event that a person qualifies for a permit, but has motivated in writing the inability to pay the fee contemplated."""
24
+ end
25
+
26
+ it 'should not unbreak section headers' do
27
+ subject.unbreak_lines("""
28
+ 8.4.3 must be a South African citizen, failing which, must be in possession of
29
+ a valid work permit which includes, but is not limited to, a refugee
30
+ permit; and
31
+ 8.4.4 must not employ and actively utilise the services of more than 20
32
+ (twenty) persons.""").should == """
33
+ 8.4.3 must be a South African citizen, failing which, must be in possession of a valid work permit which includes, but is not limited to, a refugee permit; and
34
+ 8.4.4 must not employ and actively utilise the services of more than 20
35
+ (twenty) persons."""
36
+ end
37
+ end
38
+
39
+ describe '#break_lines' do
40
+ it 'should break nested lists' do
41
+ subject.break_lines('stored, if known; (b) the number of trolleys').should == "stored, if known;\n(b) the number of trolleys"
42
+
43
+ subject.break_lines("(5) The officer-in-Charge may – (a) remove all withered natural flowers, faded or damaged artificial flowers and any receptacle placed on a grave; or\n(b) 30 days after publishing a general").should == "(5) The officer-in-Charge may –\n(a) remove all withered natural flowers, faded or damaged artificial flowers and any receptacle placed on a grave; or\n(b) 30 days after publishing a general"
44
+
45
+ subject.break_lines("(2) No person may – (a) plant, cut or remove plants, shrubs or flowers on a grave without the permission of the officer-in-charge; (b) plant, cut or remove plants, shrubs or flowers on the berm section; or").should == "(2) No person may –\n(a) plant, cut or remove plants, shrubs or flowers on a grave without the permission of the officer-in-charge;\n(b) plant, cut or remove plants, shrubs or flowers on the berm section; or"
46
+
47
+ subject.break_lines('(b) its successor in title; or (c) a structure or person exercising a delegated power or carrying out an instruction, where any power in these By-laws, has been delegated or sub-delegated or an instruction given as contemplated in, section 59 of the Local Government: Municipal Systems Act, 2000 (Act No. 32 of 2000); or (d) a service provider fulfilling a responsibility under these By-laws, assigned to it in terms of section 81(2) of the Local Government: Municipal Systems Act, 2000, or any other law, as the case may be;').should == "(b) its successor in title; or\n(c) a structure or person exercising a delegated power or carrying out an instruction, where any power in these By-laws, has been delegated or sub-delegated or an instruction given as contemplated in, section 59 of the Local Government: Municipal Systems Act, 2000 (Act No. 32 of 2000); or\n(d) a service provider fulfilling a responsibility under these By-laws, assigned to it in terms of section 81(2) of the Local Government: Municipal Systems Act, 2000, or any other law, as the case may be;"
48
+ end
49
+
50
+ it 'should break at likely subsections' do
51
+ subject.break_lines('(c) place a metal cot on any grave. (3) A person may only erect, place or leave, an object or decoration on a grave during the first 30 days following the burial. (4) Natural or artificial flowers contained in receptacles may be placed on a grave at any time, but in a grave within a berm section or with a headstone, such flowers may only be placed in the socket provided. (5) The officer-in-Charge may – (a) remove all withered natural flowers, faded or damaged artificial flowers and any receptacle placed on a grave; or').should == "(c) place a metal cot on any grave.\n(3) A person may only erect, place or leave, an object or decoration on a grave during the first 30 days following the burial.\n(4) Natural or artificial flowers contained in receptacles may be placed on a grave at any time, but in a grave within a berm section or with a headstone, such flowers may only be placed in the socket provided.\n(5) The officer-in-Charge may – (a) remove all withered natural flowers, faded or damaged artificial flowers and any receptacle placed on a grave; or"
52
+ end
53
+
54
+ it 'should break lines at likely section titles' do
55
+ subject.break_lines('foo bar. New section title 62. (1) For the purpose').should == "foo bar.\nNew section title\n62. (1) For the purpose"
56
+ subject.break_lines('New section title 62. (1) For the purpose').should == "New section title\n62. (1) For the purpose"
57
+ end
58
+
59
+ it 'should clean up wrapped definition lines after pdf' do
60
+ subject.break_lines('“agricultural holding” means a portion of land not less than 0.8 hectares in extent used solely or mainly for the purpose of agriculture, horticulture or for breeding or keeping domesticated animals, poultry or bees; “approved” means as approved by the Council; “bund wall” means a containment wall surrounding an above ground storage tank, constructed of an impervious material and designed to contain 110% of the contents of the tank; “certificate of fitness” means a certificate contemplated in section 20; “certificate of registration” means a certificate contemplated in section 35;').should == "“agricultural holding” means a portion of land not less than 0.8 hectares in extent used solely or mainly for the purpose of agriculture, horticulture or for breeding or keeping domesticated animals, poultry or bees;\n“approved” means as approved by the Council;\n“bund wall” means a containment wall surrounding an above ground storage tank, constructed of an impervious material and designed to contain 110% of the contents of the tank;\n“certificate of fitness” means a certificate contemplated in section 20;\n“certificate of registration” means a certificate contemplated in section 35;"
61
+ end
62
+ end
63
+
64
+ describe '#strip_toc' do
65
+ it 'should handle no toc' do
66
+ s = "City of Johannesburg Metropolitan Municipality
67
+ CULTURE AND RECREATION BY-LAWS ( )PUBLISHED IN PROVINCIAL GAZETTE EXTRAORDINARY NO 179 DATED 21 MAY 2004 UNDER NOTICE NUMBER 825
68
+
69
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
70
+ CULTURE AND RECREATION BY-LAWS
71
+ The Municipal Manager of the City of Johannesburg Metropolitan Municipality hereby, in terms of Section 13(a) of the Local Government: Municipal Systems Act, 2000 (Act No. 32 of 2000), publishes the Culture and RecreationBy-laws for the City of Johannesburg Metropolitan Municipality, as approved by its Council, as set out hereunder.
72
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
73
+ CULTURE AND RECREATION BY-LAWS
74
+ CHAPTER 1 LIBRARY AND INFORMATION SERVICES
75
+ Definitions and interpretation
76
+ 1. (1) In this Chapter, unless the context otherwise indicates-"
77
+ subject.strip_toc(s).should == s
78
+ end
79
+
80
+ it 'should strip table of contents' do
81
+ subject.strip_toc("City of Johannesburg Metropolitan Municipality
82
+ CULTURE AND RECREATION BY-LAWS ( )PUBLISHED IN PROVINCIAL GAZETTE EXTRAORDINARY NO 179 DATED 21 MAY 2004 UNDER NOTICE NUMBER 825
83
+
84
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
85
+ CULTURE AND RECREATION BY-LAWS
86
+ The Municipal Manager of the City of Johannesburg Metropolitan Municipality hereby, in terms of Section 13(a) of the Local Government: Municipal Systems Act, 2000 (Act No. 32 of 2000), publishes the Culture and RecreationBy-laws for the City of Johannesburg Metropolitan Municipality, as approved by its Council, as set out hereunder.
87
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
88
+ CULTURE AND RECREATION BY-LAWS
89
+ TABLE OF CONTENTS
90
+ CHAPTER 1
91
+ LIBRARY AND INFORMATION SERVICES
92
+ 1. Definitions and interpretation 2. Admission to library buildings 3. Membership 4. Loan of library material 5. Return of library material 6. Overdue library material 7. Reservation of library material 8. Lost and damaged library material 9. Handling of library material 10. Exposure of library material to notifiable and infectious diseases 11. Library material for special and reference purposes 12. Reproduction of library material and objects and use of facsimile facilities 13. Library hours 14. Hire and use of auditoria and lecture rooms or library space 15. Internet viewing stations 16. Hiring of multimedia library space 17. Performing arts library 18. Availability of By-laws and notices in a library 19. Conduct in the libraries
93
+ CHAPTER 2
94
+ ARTS AND CULTURE AND COMMUNITY CENTRE FACILITIES
95
+
96
+ Part 1: Hire and use of community arts & culture facilities
97
+ 20. Definitions and interpretation 21. Rights and status of artists 22. Co-operation between Council departments 23. Application for hiring of premises 24. Prescribed fees 25. Payment of fees 26. Period of hire 27. Adjustment of period of hire 28. Joint hire 29. Sub-letting 30. Condition of premises 31. Duties of the hirer 32. Advertisements and decorations 33. Admissions and sale of tickets 34. Overcrowding 35. Sale of refreshments 36. Services 37. Cancellation due to destruction of premises 38. Cancellation due to non-compliance 39. Termination of period of hire 40 Fire hazards and Insurance 41. Storage facilities 42. Equipment 43. Right of entry 44. Inspection 45. Regulations 46. Nuisance
98
+ Part 2: Community centres
99
+ 47. Group activities 48. Membership 49. Membership fees 50. Use of centres for religious or personal purposes 51. Dress code 52. Conduct of children 53. Application of certain sections of part 1 of Chapter 2 to centres 54. Application of certain sections of Part 2 of Chapter 3 to centres
100
+
101
+ CHAPTER 3
102
+ RECREATION AND SPORT
103
+ Part 1: Camping and caravan parks
104
+ 55. Definitions and interpretation 56. Lighting of fires prohibited 57. Permits 58. Extension of permits 59. Limitation on the period of occupancy of a camping site 60. Allocation and Use of sites 61. Proper use of roads and pathways 62. Reservation of sites 63. Right of refusal to issue or renew permits 64. Obligations of permit holders 65. Cancellation of permits 66. Access and loitering by members of the public prohibited 67. Site to be left in a clean condition 68. Washing of clothes and utensils and preparation of foodstuffs 69. Trading without permission 70. Damage to Vegetation or Property 71. Instructions of camping officer to be complied with 72 Registration and use of firearms 73. Protection of wildlife 74. Special requirements regarding caravan parks and caravans
105
+ Part 2: Sport Facilities
106
+ 75. Definitions and interpretation 76. Administration 77. Access conditions 78. Smoking 79. Alcoholic beverages 80. Duties of hirer 81. Dress code 82. Hiring of sport facilities 83. Reservation of sport facilities by the Council 84. Group activities 85. Public decency 86. Clothing and personal effects 87. Prescribed fees 88. Generally prohibited conduct 89. Animals 90. Infectious Diseases 91. Firearms and Traditional Weapons 92. Disturbance by sound systems 93. Sale of food and refreshments 94. Filming and photographs 95. Sport advisory forum
107
+
108
+ CHAPTER 4 MISCELLANEOUS 96. Definitions and interpretation 97. Animals in facilities 98. Liability for acts and omissions 99. Offences and penalties 100.
109
+ Repeal
110
+ SCHEDULE 1 BY-LAWS REPEALED
111
+ CHAPTER 1 LIBRARY AND INFORMATION SERVICES
112
+ Definitions and interpretation
113
+ 1. (1) In this Chapter, unless the context otherwise indicates-").should == "City of Johannesburg Metropolitan Municipality
114
+ CULTURE AND RECREATION BY-LAWS ( )PUBLISHED IN PROVINCIAL GAZETTE EXTRAORDINARY NO 179 DATED 21 MAY 2004 UNDER NOTICE NUMBER 825
115
+
116
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
117
+ CULTURE AND RECREATION BY-LAWS
118
+ The Municipal Manager of the City of Johannesburg Metropolitan Municipality hereby, in terms of Section 13(a) of the Local Government: Municipal Systems Act, 2000 (Act No. 32 of 2000), publishes the Culture and RecreationBy-laws for the City of Johannesburg Metropolitan Municipality, as approved by its Council, as set out hereunder.
119
+ CITY OF JOHANNESBURG METROPOLITAN MUNICIPALITY
120
+ CULTURE AND RECREATION BY-LAWS
121
+ CHAPTER 1 LIBRARY AND INFORMATION SERVICES
122
+ Definitions and interpretation
123
+ 1. (1) In this Chapter, unless the context otherwise indicates-"
124
+ end
125
+ end
126
+ end
@@ -0,0 +1 @@
1
+ require 'xml_helpers'
@@ -0,0 +1,46 @@
1
+ def xml2doc(xml)
2
+ Nokogiri::XML(xml, &:noblanks)
3
+ end
4
+
5
+ def subsection(xml)
6
+ pre = <<XML
7
+ <?xml version="1.0" encoding="UTF-8"?>
8
+ <akomaNtoso xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.akomantoso.org/2.0" xsi:schemaLocation="http://www.akomantoso.org/2.0 akomantoso20.xsd">
9
+ <act contains="singleVersion">
10
+ <body>
11
+ <section id="section-10">
12
+ <num>10.</num>
13
+ <heading>Effect of order for <term refersTo="#term-eviction" id="trm236">eviction</term></heading>
14
+ <subsection id="section-10.1">
15
+ <num>(1)</num>
16
+ <content>
17
+ XML
18
+ post = <<XML
19
+ </content>
20
+ </subsection>
21
+ </section>
22
+ </body>
23
+ </act>
24
+ </akomaNtoso>
25
+ XML
26
+
27
+ return pre + xml + post
28
+ end
29
+
30
+ def section(xml)
31
+ pre = <<XML
32
+ <?xml version="1.0" encoding="UTF-8"?>
33
+ <akomaNtoso xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.akomantoso.org/2.0" xsi:schemaLocation="http://www.akomantoso.org/2.0 akomantoso20.xsd">
34
+ <act contains="singleVersion">
35
+ <body>
36
+ <section id="section-10">
37
+ XML
38
+ post = <<XML
39
+ </section>
40
+ </body>
41
+ </act>
42
+ </akomaNtoso>
43
+ XML
44
+
45
+ return pre + xml + post
46
+ end