metanorma-iso 1.8.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -13
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +4 -6
  5. data/lib/asciidoctor/iso/cleanup.rb +0 -1
  6. data/lib/asciidoctor/iso/isodoc.rng +65 -7
  7. data/lib/asciidoctor/iso/isostandard-amd.rng +3 -0
  8. data/lib/asciidoctor/iso/isostandard.rng +18 -3
  9. data/lib/asciidoctor/iso/section.rb +3 -0
  10. data/lib/asciidoctor/iso/validate.rb +4 -17
  11. data/lib/asciidoctor/iso/validate_section.rb +50 -34
  12. data/lib/asciidoctor/iso/validate_style.rb +3 -3
  13. data/lib/isodoc/iso/base_convert.rb +41 -16
  14. data/lib/isodoc/iso/html/isodoc.css +475 -20
  15. data/lib/isodoc/iso/html/isodoc.scss +456 -23
  16. data/lib/isodoc/iso/html/wordstyle.css +202 -31
  17. data/lib/isodoc/iso/html/wordstyle.scss +194 -32
  18. data/lib/isodoc/iso/iso.amendment.xsl +524 -400
  19. data/lib/isodoc/iso/iso.international-standard.xsl +524 -400
  20. data/lib/isodoc/iso/isosts_convert.rb +12 -13
  21. data/lib/isodoc/iso/metadata.rb +2 -2
  22. data/lib/isodoc/iso/presentation_xml_convert.rb +62 -9
  23. data/lib/isodoc/iso/sts_convert.rb +4 -5
  24. data/lib/isodoc/iso/word_convert.rb +153 -39
  25. data/lib/isodoc/iso/xref.rb +27 -10
  26. data/lib/metanorma/iso/version.rb +1 -1
  27. data/metanorma-iso.gemspec +4 -4
  28. data/spec/asciidoctor/section_spec.rb +128 -7
  29. data/spec/asciidoctor/validate_spec.rb +15 -15
  30. data/spec/isodoc/amd_spec.rb +193 -201
  31. data/spec/isodoc/blocks_spec.rb +100 -88
  32. data/spec/isodoc/i18n_spec.rb +36 -36
  33. data/spec/isodoc/inline_spec.rb +472 -2
  34. data/spec/isodoc/iso_spec.rb +86 -138
  35. data/spec/isodoc/postproc_spec.rb +19 -10
  36. data/spec/isodoc/ref_spec.rb +6 -6
  37. data/spec/isodoc/section_spec.rb +394 -276
  38. data/spec/isodoc/table_spec.rb +166 -231
  39. data/spec/isodoc/terms_spec.rb +11 -8
  40. data/spec/isodoc/xref_spec.rb +147 -118
  41. metadata +8 -8
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module ISO
3
- VERSION = "1.8.3".freeze
3
+ VERSION = "1.9.0".freeze
4
4
  end
5
5
  end
@@ -27,11 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
  spec.files = `git ls-files`.split("\n")
29
29
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
30
- spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
30
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
31
31
 
32
- spec.add_dependency "isodoc", "~> 1.6.2"
33
- spec.add_dependency "metanorma-standoc", "~> 1.9.0"
34
- spec.add_dependency "mn2sts", "~> 1.8.0"
32
+ spec.add_dependency "isodoc", "~> 1.7.0"
33
+ spec.add_dependency "metanorma-standoc", "~> 1.10.0"
34
+ spec.add_dependency "mnconvert", "~> 1.8.0"
35
35
  spec.add_dependency "ruby-jing"
36
36
  spec.add_dependency "tokenizer", "~> 0.3.0"
37
37
  spec.add_dependency "twitter_cldr"
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe Asciidoctor::ISO do
4
4
  it "processes sections" do
5
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
5
+ input = <<~INPUT
6
6
  #{ASCIIDOC_BLANK_HDR}
7
7
  == Foreword
8
8
 
@@ -56,6 +56,7 @@ RSpec.describe Asciidoctor::ISO do
56
56
 
57
57
  === Bibliography Subsection
58
58
  INPUT
59
+ output = <<~OUTPUT
59
60
  #{BLANK_HDR}
60
61
  <preface>
61
62
  <foreword id="_" obligation="informative">
@@ -151,10 +152,12 @@ RSpec.describe Asciidoctor::ISO do
151
152
  </bibliography>
152
153
  </iso-standard>
153
154
  OUTPUT
155
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
156
+ .to be_equivalent_to xmlpp(output)
154
157
  end
155
158
 
156
159
  it "processes section obligations" do
157
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
160
+ input = <<~INPUT
158
161
  #{ASCIIDOC_BLANK_HDR}
159
162
  [obligation=informative]
160
163
  == Clause 1
@@ -167,6 +170,7 @@ RSpec.describe Asciidoctor::ISO do
167
170
  [appendix,obligation=informative]
168
171
  == Annex
169
172
  INPUT
173
+ output = <<~OUTPUT
170
174
  #{BLANK_HDR}
171
175
  <sections>
172
176
  <clause id="_" inline-header="false" obligation="informative">
@@ -184,10 +188,12 @@ RSpec.describe Asciidoctor::ISO do
184
188
  </annex>
185
189
  </iso-standard>
186
190
  OUTPUT
191
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
192
+ .to be_equivalent_to xmlpp(output)
187
193
  end
188
194
 
189
195
  it "processes inline headers" do
190
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
196
+ input = <<~INPUT
191
197
  #{ASCIIDOC_BLANK_HDR}
192
198
  == Clause 1
193
199
 
@@ -200,6 +206,7 @@ RSpec.describe Asciidoctor::ISO do
200
206
  [%inline-header]
201
207
  === Clause Aa
202
208
  INPUT
209
+ output = <<~OUTPUT
203
210
  #{BLANK_HDR}
204
211
  <sections>
205
212
  <clause id="_" inline-header="false" obligation="normative">
@@ -217,16 +224,19 @@ RSpec.describe Asciidoctor::ISO do
217
224
  </annex>
218
225
  </iso-standard>
219
226
  OUTPUT
227
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
228
+ .to be_equivalent_to xmlpp(output)
220
229
  end
221
230
 
222
231
  it "processes blank headers" do
223
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
232
+ input = <<~INPUT
224
233
  #{ASCIIDOC_BLANK_HDR}
225
234
  == Clause 1
226
235
 
227
236
  === {blank}
228
237
 
229
238
  INPUT
239
+ output = <<~OUTPUT
230
240
  #{BLANK_HDR}
231
241
  <sections>
232
242
  <clause id="_" inline-header="false" obligation="normative">
@@ -236,10 +246,12 @@ RSpec.describe Asciidoctor::ISO do
236
246
  </sections>
237
247
  </iso-standard>
238
248
  OUTPUT
249
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
250
+ .to be_equivalent_to xmlpp(output)
239
251
  end
240
252
 
241
253
  it "processes terms & definitions with external source" do
242
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
254
+ input = <<~INPUT
243
255
  #{ASCIIDOC_BLANK_HDR}
244
256
 
245
257
  Foreword
@@ -250,6 +262,7 @@ RSpec.describe Asciidoctor::ISO do
250
262
  === Term1
251
263
 
252
264
  INPUT
265
+ output = <<~OUTPUT
253
266
  #{BLANK_HDR.sub(/<boilerplate>/, '<termdocsource bibitemid="iso1234"/><termdocsource bibitemid="iso5678"/><boilerplate>')}
254
267
  <preface>
255
268
  <foreword id="_" obligation="informative">
@@ -285,10 +298,12 @@ RSpec.describe Asciidoctor::ISO do
285
298
  </sections>
286
299
  </iso-standard>
287
300
  OUTPUT
301
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
302
+ .to be_equivalent_to xmlpp(output)
288
303
  end
289
304
 
290
305
  it "processes empty terms & definitions" do
291
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
306
+ input = <<~INPUT
292
307
  #{ASCIIDOC_BLANK_HDR}
293
308
 
294
309
  Foreword
@@ -297,6 +312,7 @@ RSpec.describe Asciidoctor::ISO do
297
312
 
298
313
 
299
314
  INPUT
315
+ output = <<~OUTPUT
300
316
  #{BLANK_HDR}
301
317
  <preface>
302
318
  <foreword id="_" obligation="informative">
@@ -331,10 +347,12 @@ RSpec.describe Asciidoctor::ISO do
331
347
  </iso-standard>
332
348
 
333
349
  OUTPUT
350
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
351
+ .to be_equivalent_to xmlpp(output)
334
352
  end
335
353
 
336
354
  it "processes empty terms & definitions with external source" do
337
- expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", *OPTIONS)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
355
+ input = <<~INPUT
338
356
  #{ASCIIDOC_BLANK_HDR}
339
357
 
340
358
  Foreword
@@ -343,6 +361,7 @@ RSpec.describe Asciidoctor::ISO do
343
361
  == Terms and Definitions
344
362
 
345
363
  INPUT
364
+ output = <<~OUTPUT
346
365
  #{BLANK_HDR.sub(/<boilerplate>/, '<termdocsource bibitemid="iso1234"/><termdocsource bibitemid="iso5678"/><boilerplate>')}
347
366
  <preface>
348
367
  <foreword id="_" obligation="informative">
@@ -375,5 +394,107 @@ RSpec.describe Asciidoctor::ISO do
375
394
  </sections>
376
395
  </iso-standard>
377
396
  OUTPUT
397
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
398
+ .to be_equivalent_to xmlpp(output)
399
+ end
400
+
401
+ it "ignores multiple terms & definitions in default documents" do
402
+ input = <<~INPUT
403
+ #{ASCIIDOC_BLANK_HDR}
404
+
405
+ == Terms and Definitions
406
+
407
+ == Clause
408
+
409
+ [heading=terms and definitions]
410
+ == More terms
411
+
412
+ INPUT
413
+ output = <<~OUTPUT
414
+ #{BLANK_HDR}
415
+ <sections>
416
+ <terms id='_' obligation='normative'>
417
+ <title>Terms and definitions</title>
418
+ <p id='_'>No terms and definitions are listed in this document.</p>
419
+ <p id='_'>
420
+ ISO and IEC maintain terminological databases for use in standardization
421
+ at the following addresses:
422
+ </p>
423
+ <ul id='_'>
424
+ <li>
425
+ <p id='_'>
426
+ ISO Online browsing platform: available at
427
+ <link target='http://www.iso.org/obp'/>
428
+ </p>
429
+ </li>
430
+ <li>
431
+ <p id='_'>
432
+ IEC Electropedia: available at
433
+ <link target='http://www.electropedia.org'/>
434
+ </p>
435
+ </li>
436
+ </ul>
437
+ </terms>
438
+ <clause id='_' inline-header='false' obligation='normative'>
439
+ <title>Clause</title>
440
+ </clause>
441
+ <clause id='_' inline-header='false' obligation='normative'>
442
+ <title>More terms</title>
443
+ </clause>
444
+ </sections>
445
+ </iso-standard>
446
+ OUTPUT
447
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
448
+ .to be_equivalent_to xmlpp(output)
449
+ end
450
+
451
+ it "permits multiple terms & definitions in vocabulary documents" do
452
+ input = <<~INPUT
453
+ #{ASCIIDOC_BLANK_HDR.sub(/:nodoc:/, ":nodoc:\n:docsubtype: vocabulary")}
454
+
455
+ == Terms and Definitions
456
+
457
+ == Clause
458
+
459
+ [heading=terms and definitions]
460
+ == More terms
461
+
462
+ INPUT
463
+ output = <<~OUTPUT
464
+ #{BLANK_HDR.sub(%r{<doctype>article</doctype>}, "<doctype>article</doctype><subdoctype>vocabulary</subdoctype>")}
465
+ <sections>
466
+ <terms id='_' obligation='normative'>
467
+ <title>Terms and definitions</title>
468
+ <p id='_'>No terms and definitions are listed in this document.</p>
469
+ <p id='_'>
470
+ ISO and IEC maintain terminological databases for use in standardization
471
+ at the following addresses:
472
+ </p>
473
+ <ul id='_'>
474
+ <li>
475
+ <p id='_'>
476
+ ISO Online browsing platform: available at
477
+ <link target='http://www.iso.org/obp'/>
478
+ </p>
479
+ </li>
480
+ <li>
481
+ <p id='_'>
482
+ IEC Electropedia: available at
483
+ <link target='http://www.electropedia.org'/>
484
+ </p>
485
+ </li>
486
+ </ul>
487
+ </terms>
488
+ <clause id='_' inline-header='false' obligation='normative'>
489
+ <title>Clause</title>
490
+ </clause>
491
+ <terms id='_' obligation='normative'>
492
+ <title>More terms</title>
493
+ </terms>
494
+ </sections>
495
+ </iso-standard>
496
+ OUTPUT
497
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
498
+ .to be_equivalent_to xmlpp(output)
378
499
  end
379
500
  end
@@ -802,6 +802,18 @@ RSpec.describe Asciidoctor::ISO do
802
802
  expect(File.read("test.err"))
803
803
  .to include "Symbols and Abbreviated Terms can only contain "\
804
804
  "a definition list"
805
+
806
+ Asciidoctor.convert(<<~"INPUT", *OPTIONS)
807
+ #{VALIDATING_BLANK_HDR}
808
+
809
+ == Symbols and Abbreviated Terms
810
+
811
+ A:: B
812
+ INPUT
813
+ expect(File.read("test.err"))
814
+ .not_to include "Symbols and Abbreviated Terms can only contain "\
815
+ "a definition list"
816
+
805
817
  end
806
818
 
807
819
  it "Warning if missing foreword" do
@@ -1187,7 +1199,9 @@ RSpec.describe Asciidoctor::ISO do
1187
1199
  expect(File.read("test.err"))
1188
1200
  .not_to include "Only annexes and references can follow clauses"
1189
1201
  expect(File.read("test.err"))
1190
- .to include "Only terms, annexes and references can follow clauses"
1202
+ .not_to include "Scope must occur before Terms and Definitions"
1203
+ expect(File.read("test.err"))
1204
+ .to include "Only annexes and references can follow terms and clauses"
1191
1205
  end
1192
1206
 
1193
1207
 
@@ -1678,20 +1692,6 @@ RSpec.describe Asciidoctor::ISO do
1678
1692
  .not_to include "exceeds the maximum clause depth of 7"
1679
1693
  end
1680
1694
 
1681
- it "Warn if term citation in Terms & Definitions not preceded with italicised term" do
1682
- Asciidoctor.convert(<<~"INPUT", *OPTIONS)
1683
- #{VALIDATING_BLANK_HDR}
1684
- == Terms and Definitions
1685
-
1686
- [[term]]
1687
- === Term
1688
-
1689
- The definition of a term (<<term>>) is a part of the specialized vocabulary of a particular field
1690
- INPUT
1691
- expect(File.read("test.err"))
1692
- .to include "term citation not preceded with italicised term"
1693
- end
1694
-
1695
1695
  it "Warn if an undated reference has no associated footnote" do
1696
1696
  Asciidoctor.convert(<<~"INPUT", *OPTIONS)
1697
1697
  #{VALIDATING_BLANK_HDR}
@@ -75,7 +75,7 @@ RSpec.describe IsoDoc do
75
75
  </ext>
76
76
  </bibdata>
77
77
  <preface>
78
- <foreword>
78
+ <foreword displayorder="1">
79
79
  <p>
80
80
  <xref target="N">Scope, Note</xref>
81
81
  <xref target="note1">Widgets, 1, Note 1</xref>
@@ -87,7 +87,7 @@ RSpec.describe IsoDoc do
87
87
  </foreword>
88
88
  </preface>
89
89
  <sections>
90
- <clause id="scope">
90
+ <clause id="scope" displayorder="2">
91
91
  <title depth="1">Scope</title>
92
92
  <note id="N">
93
93
  <name>NOTE</name>
@@ -99,8 +99,8 @@ RSpec.describe IsoDoc do
99
99
  <xref target="N">Note</xref>
100
100
  </p>
101
101
  </clause>
102
- <terms id="terms"/>
103
- <clause id="widgets">
102
+ <terms id="terms" displayorder="3"/>
103
+ <clause id="widgets" displayorder="4">
104
104
  <title depth="1">Widgets</title>
105
105
  <clause id="widgets1" inline-header="true">
106
106
  <note id="note1">
@@ -122,7 +122,7 @@ RSpec.describe IsoDoc do
122
122
  </clause>
123
123
  </clause>
124
124
  </sections>
125
- <annex id="annex1">
125
+ <annex id="annex1" displayorder="5">
126
126
  <title>
127
127
  <strong>Annex A</strong>
128
128
  <br/>(informative)</title>
@@ -235,97 +235,102 @@ RSpec.describe IsoDoc do
235
235
  INPUT
236
236
  expect(xmlpp(output).sub(%r{<localized-strings>.*</localized-strings>}m, ""))
237
237
  .to be_equivalent_to xmlpp(<<~"OUTPUT")
238
- <?xml version='1.0'?>
239
- <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
240
- <bibdata>
241
- <ext>
242
- <doctype language="">amendment</doctype>
243
- </ext>
244
- </bibdata>
245
- <preface>
246
- <foreword obligation="informative">
247
- <title>Foreword</title>
248
- <p id="A">This is a preamble
249
-
250
- <xref target="C">0.1</xref>
251
- <xref target="C1">0.2</xref>
252
- <xref target="D">Scope</xref>
253
- <xref target="H">[H]</xref>
254
- <xref target="I">[I]</xref>
255
- <xref target="J">[J]</xref>
256
- <xref target="K">[K]</xref>
257
- <xref target="L">[L]</xref>
258
- <xref target="M">Clause 4</xref>
259
- <xref target="N">Introduction</xref>
260
- <xref target="O">Clause 4.2</xref>
261
- <xref target="P">Annex A</xref>
262
- <xref target="Q">A.1</xref>
263
- <xref target="Q1">A.1.1</xref>
264
- <xref target="Q2">Annex A, Appendix 1</xref>
265
- <xref target="R">[R]</xref></p>
266
- </foreword>
267
- <introduction id="B" obligation="informative">
268
- <title depth="1">Introduction</title>
269
- <clause id="C" inline-header="false" obligation="informative">
270
- <title depth="2">Introduction Subsection</title>
271
- </clause>
272
- <clause id="C1" inline-header="true" obligation="informative">Text</clause>
273
- </introduction>
274
- </preface>
275
- <sections>
276
- <clause id="D" obligation="normative" type="scope">
277
- <title depth="1">Scope</title>
278
- <p id="E">Text</p>
279
- </clause>
280
- <clause id="M" inline-header="false" obligation="normative">
281
- <title depth="1">Clause 4</title>
282
- <clause id="N" inline-header="false" obligation="normative">
283
- <title depth="2">Introduction</title>
284
- </clause>
285
- <clause id="O" inline-header="false" obligation="normative">
286
- <title depth="2">Clause 4.2</title>
287
- </clause>
288
- </clause>
289
- </sections>
290
- <annex id="P" inline-header="false" obligation="normative">
291
- <title>
292
- <strong>Annex A</strong>
293
- <br/>(normative)
294
-
295
- <br/>
296
- <br/>
297
- <strong>Annex</strong></title>
298
- <clause id="Q" inline-header="false" obligation="normative">
299
- <title depth="2">A.1
300
-
301
- <tab/>
302
- Annex A.1</title>
303
- <clause id="Q1" inline-header="false" obligation="normative">
304
- <title depth="3">A.1.1
305
-
306
- <tab/>
307
- Annex A.1a</title>
308
- </clause>
309
- </clause>
310
- <appendix id="Q2" inline-header="false" obligation="normative">
311
- <title depth="2">Appendix 1
312
-
313
- <tab/>
314
- An Appendix</title>
315
- </appendix>
316
- </annex>
317
- <bibliography>
318
- <references id="R" normative="true" obligation="informative">
319
- <title depth="1">Normative References</title>
320
- </references>
321
- <clause id="S" obligation="informative">
322
- <title depth="1">Bibliography</title>
323
- <references id="T" normative="false" obligation="informative">
324
- <title depth="2">Bibliography Subsection</title>
325
- </references>
326
- </clause>
327
- </bibliography>
328
- </iso-standard>
238
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
239
+ <bibdata>
240
+ <ext>
241
+ <doctype language=''>amendment</doctype>
242
+ </ext>
243
+ </bibdata>
244
+
245
+ <preface>
246
+ <foreword obligation='informative' displayorder='1'>
247
+ <title>Foreword</title>
248
+ <p id='A'>
249
+ This is a preamble
250
+ <xref target='C'>0.1</xref>
251
+ <xref target='C1'>0.2</xref>
252
+ <xref target='D'>Scope</xref>
253
+ <xref target='H'>[H]</xref>
254
+ <xref target='I'>[I]</xref>
255
+ <xref target='J'>[J]</xref>
256
+ <xref target='K'>[K]</xref>
257
+ <xref target='L'>[L]</xref>
258
+ <xref target='M'>Clause 4</xref>
259
+ <xref target='N'>Introduction</xref>
260
+ <xref target='O'>Clause 4.2</xref>
261
+ <xref target='P'>Annex A</xref>
262
+ <xref target='Q'>A.1</xref>
263
+ <xref target='Q1'>A.1.1</xref>
264
+ <xref target='Q2'>Annex A, Appendix 1</xref>
265
+ <xref target='R'>[R]</xref>
266
+ </p>
267
+ </foreword>
268
+ <introduction id='B' obligation='informative' displayorder='2'>
269
+ <title depth='1'>Introduction</title>
270
+ <clause id='C' inline-header='false' obligation='informative'>
271
+ <title depth='2'>Introduction Subsection</title>
272
+ </clause>
273
+ <clause id='C1' inline-header='true' obligation='informative'>Text</clause>
274
+ </introduction>
275
+ </preface>
276
+ <sections>
277
+ <clause id='D' obligation='normative' type='scope' displayorder='3'>
278
+ <title depth='1'>Scope</title>
279
+ <p id='E'>Text</p>
280
+ </clause>
281
+ <clause id='M' inline-header='false' obligation='normative' displayorder='5'>
282
+ <title depth='1'>Clause 4</title>
283
+ <clause id='N' inline-header='false' obligation='normative'>
284
+ <title depth='2'>Introduction</title>
285
+ </clause>
286
+ <clause id='O' inline-header='false' obligation='normative'>
287
+ <title depth='2'>Clause 4.2</title>
288
+ </clause>
289
+ </clause>
290
+ </sections>
291
+ <annex id='P' inline-header='false' obligation='normative' displayorder='6'>
292
+ <title>
293
+ <strong>Annex A</strong>
294
+ <br/>
295
+ (normative)
296
+ <br/>
297
+ <br/>
298
+ <strong>Annex</strong>
299
+ </title>
300
+ <clause id='Q' inline-header='false' obligation='normative'>
301
+ <title depth='2'>
302
+ A.1
303
+ <tab/>
304
+ Annex A.1
305
+ </title>
306
+ <clause id='Q1' inline-header='false' obligation='normative'>
307
+ <title depth='3'>
308
+ A.1.1
309
+ <tab/>
310
+ Annex A.1a
311
+ </title>
312
+ </clause>
313
+ </clause>
314
+ <appendix id='Q2' inline-header='false' obligation='normative'>
315
+ <title depth='2'>
316
+ Appendix 1
317
+ <tab/>
318
+ An Appendix
319
+ </title>
320
+ </appendix>
321
+ </annex>
322
+ <bibliography>
323
+ <references id='R' normative='true' obligation='informative' displayorder='4'>
324
+ <title depth='1'>Normative References</title>
325
+ </references>
326
+ <clause id='S' obligation='informative' displayorder='7'>
327
+ <title depth='1'>Bibliography</title>
328
+ <references id='T' normative='false' obligation='informative'>
329
+ <title depth='2'>Bibliography Subsection</title>
330
+ </references>
331
+ </clause>
332
+ </bibliography>
333
+ </iso-standard>
329
334
  OUTPUT
330
335
  end
331
336
 
@@ -423,109 +428,96 @@ RSpec.describe IsoDoc do
423
428
  </iso-standard>
424
429
  INPUT
425
430
  presxml = <<~OUTPUT
426
- <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
427
- <bibdata>
428
- <ext>
429
- <doctype language="">amendment</doctype>
430
- </ext>
431
- </bibdata>
432
- <boilerplate>
433
- <copyright-statement>
434
- <clause>
435
- <title depth="1">Copyright</title>
436
- </clause>
437
- </copyright-statement>
438
- <license-statement>
439
- <clause>
440
- <title depth="1">License</title>
441
- </clause>
442
- </license-statement>
443
- <legal-statement>
444
- <clause>
445
- <title depth="1">Legal</title>
446
- </clause>
447
- </legal-statement>
448
- <feedback-statement>
449
- <clause>
450
- <title depth="1">Feedback</title>
451
- </clause>
452
- </feedback-statement>
453
- </boilerplate>
454
- <preface>
455
- <abstract obligation="informative">
456
- <title>Abstract</title>
457
- </abstract>
458
- <foreword obligation="informative">
459
- <title>Foreword</title>
460
- <p id="A">This is a preamble</p>
461
- </foreword>
462
- <introduction id="B" obligation="informative">
463
- <title depth="1">Introduction</title>
464
- <clause id="C" inline-header="false" obligation="informative">
465
- <title depth="2">Introduction Subsection</title>
466
- </clause>
467
- </introduction>
468
- <clause id="B1">
469
- <title depth="1">Dedication</title>
470
- </clause>
471
- <clause id="B2">
472
- <title depth="1">Note to reader</title>
473
- </clause>
474
- <acknowledgements obligation="informative">
475
- <title>Acknowledgements</title>
476
- </acknowledgements>
477
- </preface>
478
- <sections>
479
- <clause id="M" inline-header="false" obligation="normative">
480
- <title depth="1">Clause 4</title>
481
- <clause id="N" inline-header="false" obligation="normative">
482
- <title depth="2">Introduction</title>
483
- </clause>
484
- <clause id="O" inline-header="false" obligation="normative">
485
- <title depth="2">Clause 4.2</title>
486
- </clause>
487
- <clause id="O1" inline-header="true" obligation="normative"/>
488
- </clause>
489
- <clause id="D" obligation="normative">
490
- <title depth="1">Scope</title>
491
- <p id="E">Text</p>
492
- </clause>
493
- </sections>
494
- <annex id="P" inline-header="false" obligation="normative">
495
- <title>
496
- <strong>Annex A</strong>
497
- <br/>(normative)
498
- <br/>
499
- <br/>
500
- <strong>Annex</strong></title>
501
- <clause id="Q" inline-header="false" obligation="normative">
502
- <title depth="2">A.1
503
- <tab/>
504
- Annex A.1</title>
505
- <clause id="Q1" inline-header="false" obligation="normative">
506
- <title depth="3">A.1.1
507
- <tab/>
508
- Annex A.1a</title>
509
- </clause>
510
- </clause>
511
- </annex>
512
- <annex id="P1" inline-header="false" obligation="normative">
513
- <title>
514
- <strong>Annex B</strong>
515
- <br/>(normative)</title>
516
- </annex>
517
- <bibliography>
518
- <references id="R" normative="true" obligation="informative">
519
- <title depth="1">Normative References</title>
520
- </references>
521
- <clause id="S" obligation="informative">
522
- <title depth="1">Bibliography</title>
523
- <references id="T" normative="false" obligation="informative">
524
- <title depth="2">Bibliography Subsection</title>
525
- </references>
526
- </clause>
527
- </bibliography>
528
- </iso-standard>
431
+ <iso-standard xmlns="http://riboseinc.com/isoxml" type="presentation">
432
+ <bibdata>
433
+ <ext>
434
+ <doctype language="">amendment</doctype>
435
+ </ext>
436
+ </bibdata>
437
+ <boilerplate>
438
+ <copyright-statement>
439
+ <clause>
440
+ <title depth="1">Copyright</title>
441
+ </clause>
442
+ </copyright-statement>
443
+ <license-statement>
444
+ <clause>
445
+ <title depth="1">License</title>
446
+ </clause>
447
+ </license-statement>
448
+ <legal-statement>
449
+ <clause>
450
+ <title depth="1">Legal</title>
451
+ </clause>
452
+ </legal-statement>
453
+ <feedback-statement>
454
+ <clause>
455
+ <title depth="1">Feedback</title>
456
+ </clause>
457
+ </feedback-statement>
458
+ </boilerplate>
459
+ <preface>
460
+ <abstract obligation="informative" displayorder="1">
461
+ <title>Abstract</title>
462
+ </abstract>
463
+ <foreword obligation="informative" displayorder="2">
464
+ <title>Foreword</title>
465
+ <p id="A">This is a preamble</p>
466
+ </foreword>
467
+ <introduction id="B" obligation="informative" displayorder="3">
468
+ <title depth="1">Introduction</title>
469
+ <clause id="C" inline-header="false" obligation="informative">
470
+ <title depth="2">Introduction Subsection</title>
471
+ </clause>
472
+ </introduction>
473
+ <clause id="B1" displayorder="4">
474
+ <title depth="1">Dedication</title>
475
+ </clause>
476
+ <clause id="B2" displayorder="5">
477
+ <title depth="1">Note to reader</title>
478
+ </clause>
479
+ <acknowledgements obligation="informative" displayorder="6">
480
+ <title>Acknowledgements</title>
481
+ </acknowledgements>
482
+ </preface>
483
+ <sections>
484
+ <clause id="M" inline-header="false" obligation="normative" displayorder="8">
485
+ <title depth="1">Clause 4</title>
486
+ <clause id="N" inline-header="false" obligation="normative">
487
+ <title depth="2">Introduction</title>
488
+ </clause>
489
+ <clause id="O" inline-header="false" obligation="normative">
490
+ <title depth="2">Clause 4.2</title>
491
+ </clause>
492
+ <clause id="O1" inline-header="true" obligation="normative"/>
493
+ </clause>
494
+ <clause id="D" obligation="normative" displayorder="9">
495
+ <title depth="1">Scope</title>
496
+ <p id="E">Text</p>
497
+ </clause>
498
+ </sections>
499
+ <annex id="P" inline-header="false" obligation="normative" displayorder="10">
500
+ <title><strong>Annex A</strong><br/>(normative)<br/><br/><strong>Annex</strong></title>
501
+ <clause id="Q" inline-header="false" obligation="normative">
502
+ <title depth="2">A.1<tab/>Annex A.1</title>
503
+ <clause id="Q1" inline-header="false" obligation="normative">
504
+ <title depth="3">A.1.1<tab/>Annex A.1a</title>
505
+ </clause>
506
+ </clause>
507
+ </annex>
508
+ <annex id="P1" inline-header="false" obligation="normative" displayorder="11"><title><strong>Annex B</strong><br/>(normative)</title></annex>
509
+ <bibliography>
510
+ <references id="R" normative="true" obligation="informative" displayorder="7">
511
+ <title depth="1">Normative References</title>
512
+ </references>
513
+ <clause id="S" obligation="informative" displayorder="12">
514
+ <title depth="1">Bibliography</title>
515
+ <references id="T" normative="false" obligation="informative">
516
+ <title depth="2">Bibliography Subsection</title>
517
+ </references>
518
+ </clause>
519
+ </bibliography>
520
+ </iso-standard>
529
521
  OUTPUT
530
522
  html = <<~OUTPUT
531
523
  <html lang="en" xmlns:epub="http://www.idpf.org/2007/ops">
@@ -617,9 +609,9 @@ RSpec.describe IsoDoc do
617
609
  <br/>
618
610
  <b>Annex</b></h1>
619
611
  <div id="Q">
620
- <h2>A.1 &#160; Annex A.1</h2>
612
+ <h2>A.1&#160; Annex A.1</h2>
621
613
  <div id="Q1">
622
- <h3>A.1.1 &#160; Annex A.1a</h3>
614
+ <h3>A.1.1&#160; Annex A.1a</h3>
623
615
  </div>
624
616
  </div>
625
617
  </div>