metanorma-iso 2.0.3 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/isodoc/iso/html/header.html +42 -33
  4. data/lib/isodoc/iso/html/html_iso_titlepage.html +1 -1
  5. data/lib/isodoc/iso/html/isodoc.css +9 -7
  6. data/lib/isodoc/iso/html/isodoc.scss +7 -5
  7. data/lib/isodoc/iso/html/style-human.css +0 -1
  8. data/lib/isodoc/iso/html/style-human.scss +0 -1
  9. data/lib/isodoc/iso/html/style-iso.css +0 -1
  10. data/lib/isodoc/iso/html/style-iso.scss +0 -1
  11. data/lib/isodoc/iso/html/word_iso_titlepage.html +12 -11
  12. data/lib/isodoc/iso/html/wordstyle.css +46 -19
  13. data/lib/isodoc/iso/html/wordstyle.scss +52 -25
  14. data/lib/isodoc/iso/i18n-en.yaml +29 -2
  15. data/lib/isodoc/iso/i18n-fr.yaml +27 -3
  16. data/lib/isodoc/iso/i18n-ru.yaml +45 -0
  17. data/lib/isodoc/iso/i18n-zh-Hans.yaml +27 -3
  18. data/lib/isodoc/iso/i18n.rb +1 -0
  19. data/lib/isodoc/iso/init.rb +1 -2
  20. data/lib/isodoc/iso/iso.amendment.xsl +1204 -615
  21. data/lib/isodoc/iso/iso.international-standard.xsl +1204 -615
  22. data/lib/isodoc/iso/metadata.rb +12 -2
  23. data/lib/isodoc/iso/presentation_xml_convert.rb +58 -21
  24. data/lib/metanorma/iso/boilerplate-fr.xml +6 -7
  25. data/lib/metanorma/iso/boilerplate-ru.xml +37 -0
  26. data/lib/metanorma/iso/boilerplate.xml +6 -7
  27. data/lib/metanorma/iso/cleanup.rb +48 -11
  28. data/lib/metanorma/iso/front.rb +1 -1
  29. data/lib/metanorma/iso/front_id.rb +2 -0
  30. data/lib/metanorma/iso/isodoc.rng +73 -3
  31. data/lib/metanorma/iso/processor.rb +14 -7
  32. data/lib/metanorma/iso/validate.rb +30 -2
  33. data/lib/metanorma/iso/validate_image.rb +3 -3
  34. data/lib/metanorma/iso/validate_list.rb +122 -0
  35. data/lib/metanorma/iso/validate_section.rb +39 -32
  36. data/lib/metanorma/iso/validate_style.rb +32 -2
  37. data/lib/metanorma/iso/validate_title.rb +13 -1
  38. data/lib/metanorma/iso/version.rb +1 -1
  39. data/metanorma-iso.gemspec +1 -1
  40. data/spec/isodoc/amd_spec.rb +10 -5
  41. data/spec/isodoc/i18n_spec.rb +350 -9
  42. data/spec/isodoc/inline_spec.rb +127 -10
  43. data/spec/isodoc/metadata_spec.rb +153 -3
  44. data/spec/isodoc/postproc_spec.rb +3 -4
  45. data/spec/isodoc/section_spec.rb +1 -0
  46. data/spec/isodoc/terms_spec.rb +4 -4
  47. data/spec/metanorma/base_spec.rb +434 -326
  48. data/spec/metanorma/cleanup_spec.rb +11 -11
  49. data/spec/metanorma/refs_spec.rb +273 -61
  50. data/spec/metanorma/section_spec.rb +18 -26
  51. data/spec/metanorma/validate_spec.rb +448 -17
  52. data/spec/spec_helper.rb +6 -4
  53. data/spec/vcr_cassettes/docrels.yml +393 -0
  54. data/spec/vcr_cassettes/withdrawn_iso.yml +301 -0
  55. metadata +10 -5
@@ -5,7 +5,13 @@ RSpec.describe IsoDoc do
5
5
  input = <<~INPUT
6
6
  <iso-standard xmlns="http://riboseinc.com/isoxml">
7
7
  <bibdata>
8
+ <status>
9
+ <stage abbreviation='IS' language=''>60</stage>
10
+ </status>
8
11
  <language>en</language>
12
+ <ext>
13
+ <doctype language=''>international-standard</doctype>
14
+ </ext>
9
15
  </bibdata>
10
16
  <preface>
11
17
  <foreword obligation="informative">
@@ -85,8 +91,16 @@ RSpec.describe IsoDoc do
85
91
  presxml = <<~OUTPUT
86
92
  <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
87
93
  <bibdata>
88
- <language current="true">en</language>
89
- </bibdata>
94
+ <status>
95
+ <stage abbreviation='IS' language=''>60</stage>
96
+ <stage abbreviation='IS' language='en'>International standard</stage>
97
+ </status>
98
+ <language current='true'>en</language>
99
+ <ext>
100
+ <doctype language=''>international-standard</doctype>
101
+ <doctype language='en'>International Standard</doctype>
102
+ </ext>
103
+ </bibdata>
90
104
  <preface>
91
105
  <foreword obligation="informative" displayorder='1'>
92
106
  <title>Foreword</title>
@@ -263,7 +277,13 @@ RSpec.describe IsoDoc do
263
277
  .convert("test", <<~"INPUT", true)
264
278
  <iso-standard xmlns="http://riboseinc.com/isoxml">
265
279
  <bibdata>
280
+ <status>
281
+ <stage abbreviation='IS' language=''>60</stage>
282
+ </status>
266
283
  <language>tlh</language>
284
+ <ext>
285
+ <doctype language=''>international-standard</doctype>
286
+ </ext>
267
287
  </bibdata>
268
288
  <preface>
269
289
  <foreword obligation="informative">
@@ -344,8 +364,16 @@ RSpec.describe IsoDoc do
344
364
  .to be_equivalent_to xmlpp(<<~"OUTPUT")
345
365
  <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
346
366
  <bibdata>
347
- <language current="true">tlh</language>
348
- </bibdata>
367
+ <status>
368
+ <stage abbreviation='IS' language=''>60</stage>
369
+ <stage abbreviation='IS' language='tlh'>International standard</stage>
370
+ </status>
371
+ <language current='true'>tlh</language>
372
+ <ext>
373
+ <doctype language=''>international-standard</doctype>
374
+ <doctype language='tlh'>International Standard</doctype>
375
+ </ext>
376
+ </bibdata>
349
377
  <preface>
350
378
  <foreword obligation="informative" displayorder='1'>
351
379
  <title>Foreword</title>
@@ -438,7 +466,13 @@ RSpec.describe IsoDoc do
438
466
  input = <<~INPUT
439
467
  <iso-standard xmlns="http://riboseinc.com/isoxml">
440
468
  <bibdata>
469
+ <status>
470
+ <stage abbreviation='IS' language=''>60</stage>
471
+ </status>
441
472
  <language>fr</language>
473
+ <ext>
474
+ <doctype language=''>international-standard</doctype>
475
+ </ext>
442
476
  </bibdata>
443
477
  <preface>
444
478
  <foreword obligation="informative">
@@ -518,8 +552,16 @@ RSpec.describe IsoDoc do
518
552
  presxml = <<~OUTPUT
519
553
  <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
520
554
  <bibdata>
521
- <language current="true">fr</language>
522
- </bibdata>
555
+ <status>
556
+ <stage abbreviation='IS' language=''>60</stage>
557
+ <stage abbreviation='IS' language='fr'>Norme internationale</stage>
558
+ </status>
559
+ <language current='true'>fr</language>
560
+ <ext>
561
+ <doctype language=''>international-standard</doctype>
562
+ <doctype language='fr'>Norme internationale</doctype>
563
+ </ext>
564
+ </bibdata>
523
565
  <preface>
524
566
  <foreword obligation="informative" displayorder='1'>
525
567
  <title>Foreword</title>
@@ -701,12 +743,303 @@ RSpec.describe IsoDoc do
701
743
  .to be_equivalent_to xmlpp(html)
702
744
  end
703
745
 
746
+ it "processes Russian" do
747
+ input = <<~INPUT
748
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
749
+ <bibdata>
750
+ <status>
751
+ <stage abbreviation='IS' language=''>60</stage>
752
+ </status>
753
+ <language>ru</language>
754
+ <ext>
755
+ <doctype language=''>international-standard</doctype>
756
+ </ext>
757
+ </bibdata>
758
+ <preface>
759
+ <foreword obligation="informative">
760
+ <title>Foreword</title>
761
+ <p id="A">This is a preamble</p>
762
+ </foreword>
763
+ <introduction id="B" obligation="informative">
764
+ <title>Introduction</title>
765
+ <clause id="C" inline-header="false" obligation="informative">
766
+ <title>Introduction Subsection</title>
767
+ </clause>
768
+ <p>This is patent boilerplate</p>
769
+ </introduction>
770
+ </preface>
771
+ <sections>
772
+ <clause id="D" obligation="normative" type="scope">
773
+ <title>Scope</title>
774
+ <p id="E">Text</p>
775
+ </clause>
776
+ <clause id="H" obligation="normative">
777
+ <title>Terms, definitions, symbols and abbreviated terms</title>
778
+ <terms id="I" obligation="normative">
779
+ <title>Normal Terms</title>
780
+ <term id="J">
781
+ <preferred><expression><name>Term2</name></expression></preferred>
782
+ </term>
783
+ </terms>
784
+ <definitions id="K">
785
+ <dl>
786
+ <dt>Symbol</dt>
787
+ <dd>Definition</dd>
788
+ </dl>
789
+ </definitions>
790
+ </clause>
791
+ <definitions id="L">
792
+ <dl>
793
+ <dt>Symbol</dt>
794
+ <dd>Definition</dd>
795
+ </dl>
796
+ </definitions>
797
+ <clause id="M" inline-header="false" obligation="normative">
798
+ <title>Clause 4</title>
799
+ <clause id="N" inline-header="false" obligation="normative">
800
+ <title>Introduction</title>
801
+ </clause>
802
+ <clause id="O" inline-header="false" obligation="normative">
803
+ <title>Clause 4.2</title>
804
+ </clause>
805
+ </clause>
806
+ </sections>
807
+ <annex id="P" inline-header="false" obligation="normative">
808
+ <title>Annex</title>
809
+ <clause id="Q" inline-header="false" obligation="normative">
810
+ <title>Annex A.1</title>
811
+ <clause id="Q1" inline-header="false" obligation="normative">
812
+ <title>Annex A.1a</title>
813
+ </clause>
814
+ </clause>
815
+ <appendix id="Q2" inline-header="false" obligation="normative">
816
+ <title>An Appendix</title>
817
+ </appendix>
818
+ </annex>
819
+ <bibliography>
820
+ <references id="R" normative="true" obligation="informative">
821
+ <title>Normative References</title>
822
+ </references>
823
+ <clause id="S" obligation="informative">
824
+ <title>Bibliography</title>
825
+ <references id="T" normative="false" obligation="informative">
826
+ <title>Bibliography Subsection</title>
827
+ </references>
828
+ </clause>
829
+ </bibliography>
830
+ </iso-standard>
831
+ INPUT
832
+
833
+ presxml = <<~OUTPUT
834
+ <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
835
+ <bibdata>
836
+ <status>
837
+ <stage abbreviation='IS' language=''>60</stage>
838
+ <stage abbreviation='IS' language='ru'>
839
+ &#x41C;&#x435;&#x436;&#x434;&#x443;&#x43D;&#x430;&#x440;&#x43E;&#x434;&#x43D;&#x44B;&#x439; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;
840
+ </stage>
841
+ </status>
842
+ <language current='true'>ru</language>
843
+ <ext>
844
+ <doctype language=''>international-standard</doctype>
845
+ <doctype language='ru'>
846
+ &#x41C;&#x435;&#x436;&#x434;&#x443;&#x43D;&#x430;&#x440;&#x43E;&#x434;&#x43D;&#x44B;&#x439; &#x421;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;
847
+ </doctype>
848
+ </ext>
849
+ </bibdata>
850
+ <preface>
851
+ <foreword obligation="informative" displayorder='1'>
852
+ <title>Foreword</title>
853
+ <p id="A">This is a preamble</p>
854
+ </foreword>
855
+ <introduction id="B" obligation="informative" displayorder='2'>
856
+ <title depth="1">0<tab/>Introduction</title>
857
+ <clause id="C" inline-header="false" obligation="informative">
858
+ <title depth="2">0.1<tab/>Introduction Subsection</title>
859
+ </clause>
860
+ <p>This is patent boilerplate</p>
861
+ </introduction>
862
+ </preface>
863
+ <sections>
864
+ <clause id="D" obligation="normative" type="scope" displayorder='3'>
865
+ <title depth="1">1<tab/>Scope</title>
866
+ <p id="E">Text</p>
867
+ </clause>
868
+ <clause id="H" obligation="normative" displayorder='5'>
869
+ <title depth="1">3<tab/>Terms, definitions, symbols and abbreviated terms</title>
870
+ <terms id="I" obligation="normative">
871
+ <title depth="2">3.1<tab/>Normal Terms</title>
872
+ <term id="J">
873
+ <name>3.1.1</name>
874
+ <preferred><strong>Term2</strong></preferred>
875
+ </term>
876
+ </terms>
877
+ <definitions id="K" inline-header="true">
878
+ <title>3.2</title>
879
+ <dl>
880
+ <dt>Symbol</dt>
881
+ <dd>Definition</dd>
882
+ </dl>
883
+ </definitions>
884
+ </clause>
885
+ <definitions id="L" displayorder='6'>
886
+ <title>4</title>
887
+ <dl>
888
+ <dt>Symbol</dt>
889
+ <dd>Definition</dd>
890
+ </dl>
891
+ </definitions>
892
+ <clause id="M" inline-header="false" obligation="normative" displayorder='7'>
893
+ <title depth="1">5<tab/>Clause 4</title>
894
+ <clause id="N" inline-header="false" obligation="normative">
895
+ <title depth="2">5.1<tab/>Introduction</title>
896
+ </clause>
897
+ <clause id="O" inline-header="false" obligation="normative">
898
+ <title depth="2">5.2<tab/>Clause 4.2</title>
899
+ </clause>
900
+ </clause>
901
+ </sections>
902
+ <annex id="P" inline-header="false" obligation="normative" displayorder='8'>
903
+ <title>
904
+ <strong>&#x414;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x435;&#x43D;&#x438;&#x435; A</strong>
905
+ <br/>(&#x43D;&#x43E;&#x440;&#x43C;&#x430;&#x442;&#x438;&#x432;&#x43D;&#x43E;&#x435;)
906
+ <br/>
907
+ <br/>
908
+ <strong>Annex</strong></title>
909
+ <clause id="Q" inline-header="false" obligation="normative">
910
+ <title depth="2">A.1<tab/>Annex A.1</title>
911
+ <clause id="Q1" inline-header="false" obligation="normative">
912
+ <title depth="3">A.1.1<tab/>Annex A.1a</title>
913
+ </clause>
914
+ </clause>
915
+ <appendix id="Q2" inline-header="false" obligation="normative">
916
+ <title depth="2"> &#x41F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; 1<tab/>An Appendix</title>
917
+ </appendix>
918
+ </annex>
919
+ <bibliography>
920
+ <references id="R" normative="true" obligation="informative" displayorder='4'>
921
+ <title depth="1">2<tab/>Normative References</title>
922
+ </references>
923
+ <clause id="S" obligation="informative" displayorder='9'>
924
+ <title depth="1">Bibliography</title>
925
+ <references id="T" normative="false" obligation="informative">
926
+ <title depth="2">Bibliography Subsection</title>
927
+ </references>
928
+ </clause>
929
+ </bibliography>
930
+ </iso-standard>
931
+ OUTPUT
932
+
933
+ html = <<~OUTPUT
934
+ #{HTML_HDR.gsub(/"en"/, '"ru"')}
935
+ <br/>
936
+ <div>
937
+ <h1 class="ForewordTitle">Foreword</h1>
938
+ <p id="A">This is a preamble</p>
939
+ </div>
940
+ <br/>
941
+ <div class="Section3" id="B">
942
+ <h1 class="IntroTitle">0&#160; Introduction</h1>
943
+ <div id="C">
944
+ <h2>0.1&#160; Introduction Subsection</h2>
945
+ </div>
946
+ <p>This is patent boilerplate</p>
947
+ </div>
948
+ <p class="zzSTDTitle1"/>
949
+ <div id="D">
950
+ <h1>1&#160; Scope</h1>
951
+ <p id="E">Text</p>
952
+ </div>
953
+ <div>
954
+ <h1>2&#160; Normative References</h1>
955
+ </div>
956
+ <div id="H">
957
+ <h1>3&#160; Terms, definitions, symbols and abbreviated terms</h1>
958
+ <div id="I">
959
+ <h2>3.1&#160; Normal Terms</h2>
960
+ <p class="TermNum" id="J">3.1.1</p>
961
+ <p class="Terms" style="text-align:left;"><b>Term2</b></p>
962
+ </div>
963
+ <div id="K">
964
+ <span class="zzMoveToFollowing">
965
+ <b>3.2&#160; </b>
966
+ </span>
967
+ <dl>
968
+ <dt>
969
+ <p>Symbol</p>
970
+ </dt>
971
+ <dd>Definition</dd>
972
+ </dl>
973
+ </div>
974
+ </div>
975
+ <div class="Symbols" id="L">
976
+ <h1>4</h1>
977
+ <dl>
978
+ <dt>
979
+ <p>Symbol</p>
980
+ </dt>
981
+ <dd>Definition</dd>
982
+ </dl>
983
+ </div>
984
+ <div id="M">
985
+ <h1>5&#160; Clause 4</h1>
986
+ <div id="N">
987
+ <h2>5.1&#160; Introduction</h2>
988
+ </div>
989
+ <div id="O">
990
+ <h2>5.2&#160; Clause 4.2</h2>
991
+ </div>
992
+ </div>
993
+ <br/>
994
+ <div class="Section3" id="P">
995
+ <h1 class="Annex">
996
+ <b>&#1044;&#1086;&#1087;&#1086;&#1083;&#1085;&#1077;&#1085;&#1080;&#1077; A</b>
997
+ <br/>(&#1085;&#1086;&#1088;&#1084;&#1072;&#1090;&#1080;&#1074;&#1085;&#1086;&#1077;)
998
+ <br/>
999
+ <br/>
1000
+ <b>Annex</b></h1>
1001
+ <div id="Q">
1002
+ <h2>A.1&#160; Annex A.1</h2>
1003
+ <div id="Q1">
1004
+ <h3>A.1.1&#160; Annex A.1a</h3>
1005
+ </div>
1006
+ </div>
1007
+ <div id="Q2">
1008
+ <h2>&#1055;&#1088;&#1080;&#1083;&#1086;&#1078;&#1077;&#1085;&#1080;&#1077; 1&#160; An Appendix</h2>
1009
+ </div>
1010
+ </div>
1011
+ <br/>
1012
+ <div>
1013
+ <h1 class="Section3">Bibliography</h1>
1014
+ <div>
1015
+ <h2 class="Section3">Bibliography Subsection</h2>
1016
+ </div>
1017
+ </div>
1018
+ </div>
1019
+ </body>
1020
+ </html>
1021
+ OUTPUT
1022
+ expect(xmlpp(IsoDoc::Iso::PresentationXMLConvert.new({})
1023
+ .convert("test", input, true))
1024
+ .sub(%r{<localized-strings>.*</localized-strings>}m, ""))
1025
+ .to be_equivalent_to xmlpp(presxml)
1026
+ expect(xmlpp(IsoDoc::Iso::HtmlConvert.new({})
1027
+ .convert("test", presxml, true)))
1028
+ .to be_equivalent_to xmlpp(html)
1029
+ end
1030
+
704
1031
  it "processes Simplified Chinese" do
705
1032
  input = <<~INPUT
706
1033
  <iso-standard xmlns="http://riboseinc.com/isoxml">
707
1034
  <bibdata>
1035
+ <status>
1036
+ <stage abbreviation='IS' language=''>60</stage>
1037
+ </status>
708
1038
  <language>zh</language>
709
1039
  <script>Hans</script>
1040
+ <ext>
1041
+ <doctype language=''>international-standard</doctype>
1042
+ </ext>
710
1043
  </bibdata>
711
1044
  <preface>
712
1045
  <foreword obligation="informative">
@@ -802,9 +1135,17 @@ RSpec.describe IsoDoc do
802
1135
  presxml = <<~OUTPUT
803
1136
  <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
804
1137
  <bibdata>
805
- <language current="true">zh</language>
806
- <script current="true">Hans</script>
807
- </bibdata>
1138
+ <status>
1139
+ <stage abbreviation='IS' language=''>60</stage>
1140
+ <stage abbreviation='IS' language='zh'>&#x56FD;&#x9645;&#x6807;&#x51C6;</stage>
1141
+ </status>
1142
+ <language current='true'>zh</language>
1143
+ <script current='true'>Hans</script>
1144
+ <ext>
1145
+ <doctype language=''>international-standard</doctype>
1146
+ <doctype language='zh'>&#x56FD;&#x9645;&#x6807;&#x51C6;</doctype>
1147
+ </ext>
1148
+ </bibdata>
808
1149
  <preface>
809
1150
  <foreword obligation="informative" displayorder='1'>
810
1151
  <title>Foreword</title>
@@ -437,12 +437,12 @@ RSpec.describe IsoDoc do
437
437
  <li><concept><refterm>term6</refterm>
438
438
  <renderterm>word</renderterm>
439
439
  <eref bibitemid="ISO712" type="inline" citeas="ISO 712">
440
- <localityStack>
440
+ <localityStack connective="and">
441
441
  <locality type='clause'>
442
442
  <referenceFrom>3.1</referenceFrom>
443
443
  </locality>
444
444
  </localityStack>
445
- <localityStack>
445
+ <localityStack connective="and">
446
446
  <locality type='figure'>
447
447
  <referenceFrom>b</referenceFrom>
448
448
  </locality>
@@ -452,12 +452,12 @@ RSpec.describe IsoDoc do
452
452
  <li><concept><refterm>term7</refterm>
453
453
  <renderterm>word</renderterm>
454
454
  <eref bibitemid="ISO712" type="inline" citeas="ISO 712">
455
- <localityStack>
455
+ <localityStack connective="and">
456
456
  <locality type='clause'>
457
457
  <referenceFrom>3.1</referenceFrom>
458
458
  </locality>
459
459
  </localityStack>
460
- <localityStack>
460
+ <localityStack connective="and">
461
461
  <locality type='figure'>
462
462
  <referenceFrom>b</referenceFrom>
463
463
  </locality>
@@ -537,25 +537,25 @@ RSpec.describe IsoDoc do
537
537
  </li>
538
538
  <li>
539
539
  <em>word</em>
540
- (<eref bibitemid="ISO712" type="inline" citeas="ISO 712"><localityStack>
540
+ (<eref bibitemid="ISO712" type="inline" citeas="ISO 712"><localityStack connective="and">
541
541
  <locality type="clause">
542
542
  <referenceFrom>3.1</referenceFrom>
543
543
  </locality>
544
- </localityStack><localityStack>
544
+ </localityStack><localityStack connective="and">
545
545
  <locality type="figure">
546
546
  <referenceFrom>b</referenceFrom>
547
547
  </locality>
548
- </localityStack>ISO 712, 3.1; Figure b</eref>)
548
+ </localityStack>ISO 712, 3.1 and Figure b</eref>)
549
549
  </li>
550
550
  <li>
551
551
  <em>word</em>
552
552
  (<eref bibitemid="ISO712" type="inline" citeas="ISO 712">
553
- <localityStack>
553
+ <localityStack connective="and">
554
554
  <locality type="clause">
555
555
  <referenceFrom>3.1</referenceFrom>
556
556
  </locality>
557
557
  </localityStack>
558
- <localityStack>
558
+ <localityStack connective="and">
559
559
  <locality type="figure">
560
560
  <referenceFrom>b</referenceFrom>
561
561
  </locality>
@@ -658,7 +658,7 @@ RSpec.describe IsoDoc do
658
658
  <li>
659
659
  <i>word</i>
660
660
  (
661
- <a href='#ISO712'>ISO 712, 3.1; Figure b</a>
661
+ <a href='#ISO712'>ISO 712, 3.1 and Figure b</a>
662
662
  )
663
663
  </li>
664
664
  <li>
@@ -947,4 +947,121 @@ RSpec.describe IsoDoc do
947
947
  expect(xmlpp(IsoDoc::Iso::HtmlConvert.new({})
948
948
  .convert("test", presxml, true))).to be_equivalent_to xmlpp(output)
949
949
  end
950
+
951
+ it "combines locality stacks with connectives, omitting subclauses" do
952
+ input = <<~INPUT
953
+ <itu-standard xmlns="https://www.calconnect.org/standards/itu">
954
+ <p id='_'>
955
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
956
+ <localityStack connective='from'>
957
+ <locality type='clause'>
958
+ <referenceFrom>3</referenceFrom>
959
+ </locality>
960
+ </localityStack>
961
+ <localityStack connective='to'>
962
+ <locality type='clause'>
963
+ <referenceFrom>5</referenceFrom>
964
+ </locality>
965
+ </localityStack>
966
+ </eref>
967
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
968
+ <localityStack connective='from'>
969
+ <locality type='clause'>
970
+ <referenceFrom>3.1</referenceFrom>
971
+ </locality>
972
+ </localityStack>
973
+ <localityStack connective='to'>
974
+ <locality type='clause'>
975
+ <referenceFrom>5.1</referenceFrom>
976
+ </locality>
977
+ </localityStack>
978
+ </eref>
979
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
980
+ <localityStack connective='from'>
981
+ <locality type='clause'>
982
+ <referenceFrom>3.1</referenceFrom>
983
+ </locality>
984
+ </localityStack>
985
+ <localityStack connective='to'>
986
+ <locality type='clause'>
987
+ <referenceFrom>5</referenceFrom>
988
+ </locality>
989
+ </localityStack>
990
+ </eref>
991
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
992
+ <localityStack connective='from'>
993
+ <locality type='clause'>
994
+ <referenceFrom>3.1</referenceFrom>
995
+ </locality>
996
+ </localityStack>
997
+ <localityStack connective='to'>
998
+ <locality type='table'>
999
+ <referenceFrom>5</referenceFrom>
1000
+ </locality>
1001
+ </localityStack>
1002
+ </eref>
1003
+ </p>
1004
+ </itu-standard>
1005
+ INPUT
1006
+ output = <<~OUTPUT
1007
+ <itu-standard xmlns='https://www.calconnect.org/standards/itu' type='presentation'>
1008
+ <p id='_'>
1009
+ <eref type='inline' bibitemid='ref1' citeas='XYZ' droploc=''>
1010
+ <localityStack connective='from'>
1011
+ <locality type='clause'>
1012
+ <referenceFrom>3</referenceFrom>
1013
+ </locality>
1014
+ </localityStack>
1015
+ <localityStack connective='to'>
1016
+ <locality type='clause'>
1017
+ <referenceFrom>5</referenceFrom>
1018
+ </locality>
1019
+ </localityStack>
1020
+ XYZ, Clause 3 to 5
1021
+ </eref>
1022
+ <eref type='inline' bibitemid='ref1' citeas='XYZ' droploc=''>
1023
+ <localityStack connective='from'>
1024
+ <locality type='clause'>
1025
+ <referenceFrom>3.1</referenceFrom>
1026
+ </locality>
1027
+ </localityStack>
1028
+ <localityStack connective='to'>
1029
+ <locality type='clause'>
1030
+ <referenceFrom>5.1</referenceFrom>
1031
+ </locality>
1032
+ </localityStack>
1033
+ XYZ, 3.1 to 5.1
1034
+ </eref>
1035
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
1036
+ <localityStack connective='from'>
1037
+ <locality type='clause'>
1038
+ <referenceFrom>3.1</referenceFrom>
1039
+ </locality>
1040
+ </localityStack>
1041
+ <localityStack connective='to'>
1042
+ <locality type='clause'>
1043
+ <referenceFrom>5</referenceFrom>
1044
+ </locality>
1045
+ </localityStack>
1046
+ XYZ, 3.1 to Clause 5
1047
+ </eref>
1048
+ <eref type='inline' bibitemid='ref1' citeas='XYZ'>
1049
+ <localityStack connective='from'>
1050
+ <locality type='clause'>
1051
+ <referenceFrom>3.1</referenceFrom>
1052
+ </locality>
1053
+ </localityStack>
1054
+ <localityStack connective='to'>
1055
+ <locality type='table'>
1056
+ <referenceFrom>5</referenceFrom>
1057
+ </locality>
1058
+ </localityStack>
1059
+ XYZ, 3.1 to Table 5
1060
+ </eref>
1061
+ </p>
1062
+ </itu-standard>
1063
+ OUTPUT
1064
+ expect(xmlpp(IsoDoc::Iso::PresentationXMLConvert.new({})
1065
+ .convert("test", input, true))).to be_equivalent_to xmlpp(output)
1066
+ end
950
1067
  end