isodoc 1.7.5 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +8 -7
  3. data/lib/isodoc/class_utils.rb +25 -2
  4. data/lib/isodoc/convert.rb +2 -0
  5. data/lib/isodoc/function/cleanup.rb +4 -0
  6. data/lib/isodoc/function/to_word_html.rb +2 -1
  7. data/lib/isodoc/function/utils.rb +34 -14
  8. data/lib/isodoc/html_function/comments.rb +107 -111
  9. data/lib/isodoc/html_function/footnotes.rb +68 -67
  10. data/lib/isodoc/html_function/html.rb +113 -103
  11. data/lib/isodoc/presentation_function/block.rb +1 -69
  12. data/lib/isodoc/presentation_function/image.rb +112 -0
  13. data/lib/isodoc/presentation_function/inline.rb +16 -78
  14. data/lib/isodoc/presentation_function/terms.rb +179 -0
  15. data/lib/isodoc/presentation_xml_convert.rb +11 -4
  16. data/lib/isodoc/version.rb +1 -1
  17. data/lib/isodoc/word_function/body.rb +176 -174
  18. data/lib/isodoc/word_function/comments.rb +117 -112
  19. data/lib/isodoc/word_function/footnotes.rb +88 -86
  20. data/lib/isodoc/word_function/inline.rb +42 -67
  21. data/lib/isodoc/word_function/postprocess.rb +184 -176
  22. data/lib/isodoc/word_function/postprocess_cover.rb +121 -110
  23. data/lib/isodoc/xref/xref_gen.rb +153 -150
  24. data/lib/isodoc/xref/xref_sect_gen.rb +134 -129
  25. data/lib/isodoc/xslfo_convert.rb +11 -7
  26. data/lib/isodoc-yaml/i18n-ar.yaml +22 -0
  27. data/lib/isodoc-yaml/i18n-de.yaml +20 -0
  28. data/lib/isodoc-yaml/i18n-en.yaml +20 -0
  29. data/lib/isodoc-yaml/i18n-es.yaml +20 -0
  30. data/lib/isodoc-yaml/i18n-fr.yaml +20 -0
  31. data/lib/isodoc-yaml/i18n-ru.yaml +21 -1
  32. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +21 -0
  33. data/lib/metanorma/output/xslfo.rb +4 -11
  34. data/spec/assets/i18n.yaml +3 -1
  35. data/spec/assets/odf.svg +1 -4
  36. data/spec/isodoc/blocks_spec.rb +229 -157
  37. data/spec/isodoc/i18n_spec.rb +8 -8
  38. data/spec/isodoc/inline_spec.rb +285 -32
  39. data/spec/isodoc/postproc_spec.rb +38 -0
  40. data/spec/isodoc/presentation_xml_spec.rb +60 -0
  41. data/spec/isodoc/section_spec.rb +11 -10
  42. data/spec/isodoc/terms_spec.rb +354 -34
  43. data/spec/isodoc/xref_spec.rb +4 -4
  44. data/spec/isodoc/xslfo_convert_spec.rb +34 -9
  45. metadata +49 -33
@@ -413,32 +413,32 @@ RSpec.describe IsoDoc do
413
413
 
414
414
  it "processes concept attributes" do
415
415
  input = <<~INPUT
416
- <iso-standard xmlns="http://riboseinc.com/isoxml">
417
- <preface><foreword>
418
- <p>
419
- <ul>
420
- <li><concept ital="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
421
- <li><concept ref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
422
- <li><concept ital="true" ref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
423
- <li><concept ital="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
424
- <li><concept ref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
425
- <li><concept ital="false" ref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
426
- <li><concept ital="true" ref="true" linkmention="true" linkref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
427
- <li><concept ital="true" ref="true" linkmention="true" linkref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
428
- <li><concept ital="true" ref="true" linkmention="false" linkref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
429
- <li><concept ital="true" ref="true" linkmention="false" linkref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
430
- <li><concept ital="true" ref="true" linkmention="true" linkref="true"><strong>error!</strong></concept></li>
431
- <li><concept ital="false" ref="false" linkmention="true">
432
- <refterm>CV_DiscreteCoverage</refterm>
433
- <renderterm>CV_DiscreteCoverage</renderterm>
434
- <xref target="term-cv_discretecoverage"/>
435
- </concept></li>
436
- </ul></p>
437
- </foreword></preface>
438
- <sections>
439
- <clause id="clause1"><title>Clause 1</title></clause>
440
- </sections>
441
- </iso-standard>
416
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
417
+ <preface><foreword>
418
+ <p>
419
+ <ul>
420
+ <li><concept ital="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
421
+ <li><concept ref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
422
+ <li><concept ital="true" ref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
423
+ <li><concept ital="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
424
+ <li><concept ref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
425
+ <li><concept ital="false" ref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
426
+ <li><concept ital="true" ref="true" linkmention="true" linkref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
427
+ <li><concept ital="true" ref="true" linkmention="true" linkref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
428
+ <li><concept ital="true" ref="true" linkmention="false" linkref="true"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
429
+ <li><concept ital="true" ref="true" linkmention="false" linkref="false"><refterm>term</refterm><renderterm>term</renderterm><xref target='clause1'/></concept>,</li>
430
+ <li><concept ital="true" ref="true" linkmention="true" linkref="true"><strong>error!</strong></concept></li>
431
+ <li><concept ital="false" ref="false" linkmention="true">
432
+ <refterm>CV_DiscreteCoverage</refterm>
433
+ <renderterm>CV_DiscreteCoverage</renderterm>
434
+ <xref target="term-cv_discretecoverage"/>
435
+ </concept></li>
436
+ </ul></p>
437
+ </foreword></preface>
438
+ <sections>
439
+ <clause id="clause1"><title>Clause 1</title></clause>
440
+ </sections>
441
+ </iso-standard>
442
442
  INPUT
443
443
  presxml = <<~OUTPUT
444
444
  <iso-standard xmlns="http://riboseinc.com/isoxml" type="presentation">
@@ -625,6 +625,84 @@ RSpec.describe IsoDoc do
625
625
  .convert("test", presxml, true))).to be_equivalent_to xmlpp(output)
626
626
  end
627
627
 
628
+ it "processes related terms" do
629
+ input = <<~INPUT
630
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
631
+ <sections>
632
+ <terms id='A' obligation='normative'>
633
+ <title>Terms and definitions</title>
634
+ <term id='second'>
635
+ <preferred>
636
+ <expression>
637
+ <name>Second Term</name>
638
+ </expression>
639
+ </preferred>
640
+ <usageinfo>
641
+ <p id='B'>Usage Info 1.</p>
642
+ </usageinfo>
643
+ <definition><verbaldefinition>Definition 1</verbaldefinition></definition>
644
+ </term>
645
+ <term id="C">
646
+ <preferred language='fr' script='Latn' type='prefix'>
647
+ <expression>
648
+ <name>First Designation</name>
649
+ </expression></preferred>
650
+ <related type='contrast'>
651
+ <preferred>
652
+ <expression>
653
+ <name>Fifth Designation</name>
654
+ <grammar>
655
+ <gender>neuter</gender>
656
+ </grammar>
657
+ </expression>
658
+ </preferred>
659
+ <xref target='second'/>
660
+ </related>
661
+ <definition><verbaldefinition>Definition 2</verbaldefinition></definition>
662
+ </term>
663
+ </terms>
664
+ </sections>
665
+ </iso-standard>
666
+ INPUT
667
+ output = <<~OUTPUT
668
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
669
+ <sections>
670
+ <terms id='A' obligation='normative' displayorder='1'>
671
+ <title depth='1'>
672
+ 1.
673
+ <tab/>
674
+ Terms and definitions
675
+ </title>
676
+ <term id='second'>
677
+ <name>1.1.</name>
678
+ <preferred>Second Term</preferred>
679
+ <usageinfo>
680
+ <p id='B'>Usage Info 1.</p>
681
+ </usageinfo>
682
+ <definition>Definition 1</definition>
683
+ </term>
684
+ <term id='C'>
685
+ <name>1.2.</name>
686
+ <preferred language='fr' script='Latn' type='prefix'>First Designation</preferred>
687
+ <p>
688
+ <strong>CONTRAST:</strong>
689
+ <em>
690
+ <preferred>Fifth Designation neut</preferred>
691
+ </em>
692
+ (
693
+ <xref target='second'>Clause 1.1</xref>
694
+ )
695
+ </p>
696
+ <definition>Definition 2</definition>
697
+ </term>
698
+ </terms>
699
+ </sections>
700
+ </iso-standard>
701
+ OUTPUT
702
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({})
703
+ .convert("test", input, true))).to be_equivalent_to xmlpp(output)
704
+ end
705
+
628
706
  it "processes embedded inline formatting" do
629
707
  input = <<~INPUT
630
708
  <iso-standard xmlns="http://riboseinc.com/isoxml">
@@ -1388,6 +1466,65 @@ RSpec.describe IsoDoc do
1388
1466
  .convert("test", presxml, true))).to be_equivalent_to xmlpp(word)
1389
1467
  end
1390
1468
 
1469
+ it "processes eref content with Unicode characters" do
1470
+ input = <<~INPUT
1471
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1472
+ <preface><foreword>
1473
+ <p>
1474
+ <eref type="inline" bibitemid="ISO712" citeas="BSI BS EN ISO 19011:2018&#8201;&#8212;&#8201;TC"/>
1475
+ </foreword></preface>
1476
+ <bibliography>
1477
+ <references id='_normative_references' obligation='informative' normative='true' displayorder="2">
1478
+ <title>Normative References</title>
1479
+ <bibitem id='ISO712' type='standard'>
1480
+ <title format='text/plain'>Cereals and cereal products</title>
1481
+ <uri type='citation'>http://www.example.com</uri>
1482
+ <docidentifier>ISO 712</docidentifier>
1483
+ <contributor>
1484
+ <role type='publisher'/>
1485
+ <organization>
1486
+ <abbreviation>ISO</abbreviation>
1487
+ </organization>
1488
+ </contributor>
1489
+ </bibitem>
1490
+ </references></bibliography>
1491
+ </iso-standard>
1492
+ INPUT
1493
+ presxml = <<~OUTPUT
1494
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
1495
+ <preface>
1496
+ <foreword displayorder='1'>
1497
+ <p>
1498
+ <eref type='inline' bibitemid='ISO712' citeas='BSI BS EN ISO 19011:2018&#x2009;&#x2014;&#x2009;TC'>BSI BS EN ISO 19011:2018&#x2009;&#x2014;&#x2009;TC</eref>
1499
+ </p>
1500
+ </foreword>
1501
+ <bibliography displayorder='2'>
1502
+ <references id='_normative_references' obligation='informative' normative='true' displayorder='3'>
1503
+ <title depth='1'>
1504
+ 1.
1505
+ <tab/>
1506
+ Normative References
1507
+ </title>
1508
+ <bibitem id='ISO712' type='standard'>
1509
+ <title format='text/plain'>Cereals and cereal products</title>
1510
+ <uri type='citation'>http://www.example.com</uri>
1511
+ <docidentifier>ISO 712</docidentifier>
1512
+ <contributor>
1513
+ <role type='publisher'/>
1514
+ <organization>
1515
+ <abbreviation>ISO</abbreviation>
1516
+ </organization>
1517
+ </contributor>
1518
+ </bibitem>
1519
+ </references>
1520
+ </bibliography>
1521
+ </preface>
1522
+ </iso-standard>
1523
+ OUTPUT
1524
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({})
1525
+ .convert("test", input, true))).to be_equivalent_to xmlpp(presxml)
1526
+ end
1527
+
1391
1528
  it "processes variant" do
1392
1529
  input = <<~INPUT
1393
1530
  <iso-standard xmlns="http://riboseinc.com/isoxml">
@@ -1446,6 +1583,122 @@ RSpec.describe IsoDoc do
1446
1583
  end
1447
1584
 
1448
1585
  it "cases xrefs" do
1586
+ input = <<~INPUT
1587
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1588
+ <preface>
1589
+ <clause id="CC"><title>Introduction</title></clause>
1590
+ <sections>
1591
+ <clause id="A">
1592
+ <table id="B">
1593
+ </table>
1594
+ <figure id="B1"/>
1595
+ <example id="B2"/>
1596
+ </clause>
1597
+ <clause id="C">
1598
+ <p>This is <xref target="A"/> and <xref target="B"/>.
1599
+ This is <xref target="A" case="capital"/> and <xref target="B" case="lowercase"/>.
1600
+ This is <xref target="A" case="lowercase"/> and <xref target="B" case="capital"/>.
1601
+ Downcasing an xref affects only the first letter: <xref target="B2" case="lowercase"/>.
1602
+ Capitalising an xref affects only the first letter: <xref target="B1" case="capital"/>.
1603
+ <xref target="A"/> is clause <em>initial.</em><br/>
1604
+ <xref target="A"/> is too. </p>
1605
+ <p><xref target="A"/> is also.</p>
1606
+ <p>Annex has formatting, and crossreferences ignore it when determining casing. <xref target="AA"/>.</p>
1607
+ <p>Labels are not subject to casing: <xref target="CC" case="lowercase"/>
1608
+ </clause>
1609
+ <annex id="AA">
1610
+ <clause id="AA1"/>
1611
+ </annex>
1612
+ </sections>
1613
+ </iso-standard>
1614
+ INPUT
1615
+ output = <<~OUTPUT
1616
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
1617
+ <preface>
1618
+ <clause id='CC' displayorder='1'>
1619
+ <title depth='1'>Introduction</title>
1620
+ </clause>
1621
+ <sections displayorder='2'>
1622
+ <clause id='A' displayorder='3'>
1623
+ <title>1.</title>
1624
+ <table id='B'>
1625
+ <name>Tabelo 1</name>
1626
+ </table>
1627
+ <figure id='B1'>
1628
+ <name>Figur-etikedo duvorta 1</name>
1629
+ </figure>
1630
+ <example id='B2'>
1631
+ <name>Ekzempl-etikedo Duvorta</name>
1632
+ </example>
1633
+ </clause>
1634
+ <clause id='C' displayorder='4'>
1635
+ <title>2.</title>
1636
+ <p>
1637
+ This is
1638
+ <xref target='A'>kla&#x16D;zo 1</xref>
1639
+ and
1640
+ <xref target='B'>tabelo 1</xref>
1641
+ . This is
1642
+ <xref target='A' case='capital'>Kla&#x16D;zo 1</xref>
1643
+ and
1644
+ <xref target='B' case='lowercase'>tabelo 1</xref>
1645
+ . This is
1646
+ <xref target='A' case='lowercase'>kla&#x16D;zo 1</xref>
1647
+ and
1648
+ <xref target='B' case='capital'>Tabelo 1</xref>
1649
+ . Downcasing an xref affects only the first letter:
1650
+ <xref target='B2' case='lowercase'>kla&#x16D;zo 1, Example</xref>
1651
+ . Capitalising an xref affects only the first letter:
1652
+ <xref target='B1' case='capital'>Figur-etikedo duvorta 1</xref>
1653
+ .
1654
+ <xref target='A'>Kla&#x16D;zo 1</xref>
1655
+ is clause
1656
+ <em>initial.</em>
1657
+ <br/>
1658
+ <xref target='A'>Kla&#x16D;zo 1</xref>
1659
+ is too.
1660
+ </p>
1661
+ <p>
1662
+ <xref target='A'>Kla&#x16D;zo 1</xref>
1663
+ is also.
1664
+ </p>
1665
+ <p>
1666
+ Annex has formatting, and crossreferences ignore it when determining
1667
+ casing.
1668
+ <xref target='AA'>
1669
+ <strong>Aldono</strong>
1670
+ A
1671
+ </xref>
1672
+ .
1673
+ </p>
1674
+ <p>
1675
+ Labels are not subject to casing:
1676
+ <xref target='CC' case='lowercase'>Introduction</xref>
1677
+ </p>
1678
+ <annex id='AA' displayorder='5'>
1679
+ <title>
1680
+ <strong>
1681
+ <strong>Aldono</strong>
1682
+ A
1683
+ </strong>
1684
+ <br/>
1685
+ (informa)
1686
+ </title>
1687
+ <clause id='AA1'>
1688
+ <title>A.1.</title>
1689
+ </clause>
1690
+ </annex>
1691
+ </clause>
1692
+ </sections>
1693
+ </preface>
1694
+ </iso-standard>
1695
+ OUTPUT
1696
+ expect(xmlpp(IsoDoc::PresentationXMLConvert
1697
+ .new({ i18nyaml: "spec/assets/i18n.yaml" })
1698
+ .convert("test", input, true))).to be_equivalent_to xmlpp(output)
1699
+ end
1700
+
1701
+ it "ignores casing of xrefs in unicameral scripts" do
1449
1702
  input = <<~INPUT
1450
1703
  <iso-standard xmlns="http://riboseinc.com/isoxml">
1451
1704
  <sections>
@@ -1482,23 +1735,23 @@ RSpec.describe IsoDoc do
1482
1735
  and
1483
1736
  <xref target='B'>tabelo 1</xref>
1484
1737
  . This is
1485
- <xref target='A' case='capital'>Kla&#x16D;zo 1</xref>
1738
+ <xref target='A' case='capital'>kla&#x16D;zo 1</xref>
1486
1739
  and
1487
1740
  <xref target='B' case='lowercase'>tabelo 1</xref>
1488
1741
  . This is
1489
1742
  <xref target='A' case='lowercase'>kla&#x16D;zo 1</xref>
1490
1743
  and
1491
- <xref target='B' case='capital'>Tabelo 1</xref>
1744
+ <xref target='B' case='capital'>tabelo 1</xref>
1492
1745
  .
1493
- <xref target='A'>Kla&#x16D;zo 1</xref>
1746
+ <xref target='A'>kla&#x16D;zo 1</xref>
1494
1747
  is clause
1495
1748
  <em>initial.</em>
1496
1749
  <br/>
1497
- <xref target='A'>Kla&#x16D;zo 1</xref>
1750
+ <xref target='A'>kla&#x16D;zo 1</xref>
1498
1751
  is too.
1499
1752
  </p>
1500
1753
  <p>
1501
- <xref target='A'>Kla&#x16D;zo 1</xref>
1754
+ <xref target='A'>kla&#x16D;zo 1</xref>
1502
1755
  is also.
1503
1756
  </p>
1504
1757
  </clause>
@@ -1506,7 +1759,7 @@ RSpec.describe IsoDoc do
1506
1759
  </iso-standard>
1507
1760
  OUTPUT
1508
1761
  expect(xmlpp(IsoDoc::PresentationXMLConvert
1509
- .new({ i18nyaml: "spec/assets/i18n.yaml" })
1762
+ .new({ i18nyaml: "spec/assets/i18n.yaml", script: "Hans" })
1510
1763
  .convert("test", input, true))).to be_equivalent_to xmlpp(output)
1511
1764
  end
1512
1765
 
@@ -807,6 +807,44 @@ RSpec.describe IsoDoc do
807
807
  OUTPUT
808
808
  end
809
809
 
810
+ it "moves images in HTML" do
811
+ FileUtils.rm_f "test.html"
812
+ FileUtils.rm_rf "test_htmlimages"
813
+ IsoDoc::HtmlConvert.new(
814
+ { baseassetpath: "spec/assets",
815
+ wordstylesheet: "word.css",
816
+ htmlstylesheet: "html.scss" },
817
+ ).convert("test", <<~"INPUT", false)
818
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
819
+ <preface><foreword>
820
+ <figure id="_">
821
+ <name>Split-it-right sample divider</name>
822
+ <image src="rice_image1.png" id="_" mimetype="image/png"/>
823
+ </figure>
824
+ </foreword></preface>
825
+ </iso-standard>
826
+ INPUT
827
+ html = File.read("test.html")
828
+ .sub(/^.*<main class="main-section">/m, '<main class="main-section">')
829
+ .sub(%r{</main>.*$}m, "</main>")
830
+ expect(`ls test_htmlimages`).to match(/\.png$/)
831
+ expect(xmlpp(html.gsub(/\/[0-9a-f-]+\.png/, "/_.png")))
832
+ .to be_equivalent_to xmlpp(<<~"OUTPUT")
833
+ <main class='main-section'>
834
+ <button onclick='topFunction()' id='myBtn' title='Go to top'>Top</button>
835
+ <br/>
836
+ <div>
837
+ <h1 class='ForewordTitle'>Foreword</h1>
838
+ <div id='_' class='figure'>
839
+ <img src='test_htmlimages/_.png' height='776' width='922'/>
840
+ <p class='FigureTitle' style='text-align:center;'>Split-it-right sample divider</p>
841
+ </div>
842
+ </div>
843
+ <p class='zzSTDTitle1'/>
844
+ </main>
845
+ OUTPUT
846
+ end
847
+
810
848
  describe "mathvariant to plain" do
811
849
  context "when `mathvariant` attr equal to `script`" do
812
850
  it "converts mathvariant text chars into associated plain chars" do
@@ -762,6 +762,66 @@ RSpec.describe IsoDoc do
762
762
  .to be_equivalent_to xmlpp(output)
763
763
  end
764
764
 
765
+ it "duplicates EMF and SVG files" do
766
+ input = <<~INPUT
767
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
768
+ <bibdata/>
769
+ <sections>
770
+ <clause id='A' inline-header='false' obligation='normative'>
771
+ <title>Clause</title>
772
+ <figure id="B">
773
+ <image src="spec/assets/odf.svg" mimetype="image/svg+xml" alt="1"/>
774
+ <image src="spec/assets/odf.emf" mimetype="image/x-emf" alt="2"/>
775
+ <image src="data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGZpbGw9IiMwMDkiIHI9IjQ1IiBjeD0iNTAiIGN5PSI1MCIvPjxwYXRoIGQ9Ik0zMywyNkg3OEEzNywzNywwLDAsMSwzMyw4M1Y1N0g1OVY0M0gzM1oiIGZpbGw9IiNGRkYiLz48L3N2Zz4=" mimetype="image/svg+xml" alt="3"/>
776
+ <image src="data:application/x-msmetafile;base64,AQAAAMgAAAAAAAAAAAAAAPsEAAD7BAAAAAAAAAAAAACLCgAAiwoAACBFTUYAAAEAJAQAACgAAAACAAAALgAAAGwAAAAAAAAA3ScAAH0zAADYAAAAFwEAAAAAAAAAAAAAAAAAAMBLAwDYQQQASQBuAGsAcwBjAGEAcABlACAAMQAuADAAIAAoADQAMAAzADUAYQA0AGYALAAgADIAMAAyADAALQAwADUALQAwADEAKQAgAAAAbwBkAGYALgBlAG0AZgAAAAAAAAARAAAADAAAAAEAAAAkAAAAJAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAIAAABGAAAALAAAACAAAABTY3JlZW49MTAyMDV4MTMxODFweCwgMjE2eDI3OW1tAEYAAAAwAAAAIwAAAERyYXdpbmc9MTAwLjB4MTAwLjBweCwgMjYuNXgyNi41bW0AABIAAAAMAAAAAQAAABMAAAAMAAAAAgAAABYAAAAMAAAAGAAAABgAAAAMAAAAAAAAABQAAAAMAAAADQAAACcAAAAYAAAAAQAAAAAAAAAAAJkABgAAACUAAAAMAAAAAQAAADsAAAAIAAAAGwAAABAAAACkBAAAcQIAAAUAAAA0AAAAAAAAAAAAAAD//////////wMAAACkBAAAqAMAAKgDAACkBAAAcQIAAKQEAAAFAAAANAAAAAAAAAAAAAAA//////////8DAAAAOgEAAKQEAAA/AAAAqAMAAD8AAABxAgAABQAAADQAAAAAAAAAAAAAAP//////////AwAAAD8AAAA6AQAAOgEAAD8AAABxAgAAPwAAAAUAAAA0AAAAAAAAAAAAAAD//////////wMAAACoAwAAPwAAAKQEAAA6AQAApAQAAHECAAA9AAAACAAAADwAAAAIAAAAPgAAABgAAAAAAAAAAAAAAP//////////JQAAAAwAAAAFAACAKAAAAAwAAAABAAAAJwAAABgAAAABAAAAAAAAAP///wAGAAAAJQAAAAwAAAABAAAAOwAAAAgAAAAbAAAAEAAAAJ0BAABFAQAANgAAABAAAADPAwAARQEAAAUAAAA0AAAAAAAAAAAAAAD//////////wMAAABfBAAA7QEAAGQEAADjAgAA2wMAAJEDAAAFAAAANAAAAAAAAAAAAAAA//////////8DAAAAUgMAAD4EAABhAgAAcwQAAJ0BAAAOBAAANgAAABAAAACdAQAAyQIAADYAAAAQAAAA4gIAAMkCAAA2AAAAEAAAAOICAAAaAgAANgAAABAAAACdAQAAGgIAAD0AAAAIAAAAPAAAAAgAAAA+AAAAGAAAAAAAAAAAAAAA//////////8lAAAADAAAAAUAAIAoAAAADAAAAAEAAAAOAAAAFAAAAAAAAAAAAAAAJAQAAA==" mimetype="image/x-emf" alt="4"/>
777
+ </figure>
778
+ </clause>
779
+ </sections>
780
+ </iso-standard>
781
+ INPUT
782
+ output = <<~OUTPUT
783
+ <?xml version="1.0"?>
784
+ <iso-standard xmlns="http://riboseinc.com/isoxml" type="presentation">
785
+ <bibdata/>
786
+ <sections>
787
+ <clause id="A" inline-header="false" obligation="normative" displayorder="1">
788
+ <title depth="1">1.<tab/>Clause</title>
789
+ <figure id="B"><name>Figure 1</name>
790
+ <image src="spec/assets/odf.svg" mimetype="image/svg+xml" alt="1"><emf src="spec/assets/odf.emf"/></image>
791
+ <image src="" mimetype="image/svg+xml" alt="2">
792
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1275.0000" height="1275.0000">
793
+ <g transform="translate(-0.0000, -0.0000)">
794
+ <g transform="matrix(1.0000 0.0000 0.0000 1.0000 0.0000 0.0000)">
795
+ <path d="M 1188.0000,625.0000 C 1188.0000,936.0000 936.0000,1188.0000 625.0000,1188.0000 C 314.0000,1188.0000 63.0000,936.0000 63.0000,625.0000 C 63.0000,314.0000 314.0000,63.0000 625.0000,63.0000 C 936.0000,63.0000 1188.0000,314.0000 1188.0000,625.0000 Z " fill="#000099" stroke="none"/>
796
+ <path d="M 413.0000,325.0000 L 975.0000,325.0000 C 1119.0000,493.0000 1124.0000,739.0000 987.0000,913.0000 C 850.0000,1086.0000 609.0000,1139.0000 413.0000,1038.0000 L 413.0000,713.0000 L 738.0000,713.0000 L 738.0000,538.0000 L 413.0000,538.0000 Z " fill="#FFFFFF" stroke="none"/>
797
+ </g>
798
+ </g>
799
+ </svg>
800
+ <emf src="data:application/x-msmetafile;base64"/></image>
801
+ <image src="" mimetype="image/svg+xml" alt="3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle fill="#009" r="45" cx="50" cy="50"/><path d="M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z" fill="#FFF"/></svg><emf src="data:application/x-msmetafile;base64"/></image>
802
+ <image src="" mimetype="image/svg+xml" alt="4">
803
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1275.0000" height="1275.0000">
804
+ <g transform="translate(-0.0000, -0.0000)">
805
+ <g transform="matrix(1.0000 0.0000 0.0000 1.0000 0.0000 0.0000)">
806
+ <path d="M 1188.0000,625.0000 C 1188.0000,936.0000 936.0000,1188.0000 625.0000,1188.0000 C 314.0000,1188.0000 63.0000,936.0000 63.0000,625.0000 C 63.0000,314.0000 314.0000,63.0000 625.0000,63.0000 C 936.0000,63.0000 1188.0000,314.0000 1188.0000,625.0000 Z " fill="#000099" stroke="none"/>
807
+ <path d="M 413.0000,325.0000 L 975.0000,325.0000 C 1119.0000,493.0000 1124.0000,739.0000 987.0000,913.0000 C 850.0000,1086.0000 609.0000,1139.0000 413.0000,1038.0000 L 413.0000,713.0000 L 738.0000,713.0000 L 738.0000,538.0000 L 413.0000,538.0000 Z " fill="#FFFFFF" stroke="none"/>
808
+ </g>
809
+ </g>
810
+ </svg>
811
+ <emf src="data:application/x-msmetafile;base64"/></image>
812
+ </figure>
813
+ </clause>
814
+ </sections>
815
+ </iso-standard>
816
+ OUTPUT
817
+ expect(IsoDoc::PresentationXMLConvert.new({})
818
+ .convert("test", input, true)
819
+ .sub(%r{<localized-strings>.*</localized-strings>}m, "")
820
+ .gsub(%r{"data:application/x-msmetafile;base64,[^"]+"},
821
+ '"data:application/x-msmetafile;base64"'))
822
+ .to be_equivalent_to (output)
823
+ end
824
+
765
825
  private
766
826
 
767
827
  def mock_symbols
@@ -209,7 +209,7 @@ RSpec.describe IsoDoc do
209
209
  <clause id="H" obligation="normative"><title>Terms, Definitions, Symbols and Abbreviated Terms</title><terms id="I" obligation="normative">
210
210
  <title>Normal Terms</title>
211
211
  <term id="J">
212
- <preferred>Term2</preferred>
212
+ <preferred><expression><name>Term2</name></expression></preferred>
213
213
  </term>
214
214
  </terms>
215
215
  <definitions id="K">
@@ -745,7 +745,7 @@ RSpec.describe IsoDoc do
745
745
  <title>Normal Terms</title>
746
746
  <variant-title type="sub">Variant 1</variant-title>
747
747
  <term id="J">
748
- <preferred>Term2</preferred>
748
+ <preferred><expression><name>Term2</name></expression></preferred>
749
749
  </term>
750
750
  </terms>
751
751
  <definitions id="K">
@@ -1361,7 +1361,7 @@ RSpec.describe IsoDoc do
1361
1361
  <clause id="H" obligation="normative"><title>Terms, Definitions, Symbols and Abbreviated Terms</title><terms id="I" obligation="normative">
1362
1362
  <title>Normal Terms</title>
1363
1363
  <term id="J">
1364
- <preferred>Term2</preferred>
1364
+ <preferred><expression><name>Term2</name></expression></preferred>
1365
1365
  </term>
1366
1366
  </terms>
1367
1367
  <definitions id="K">
@@ -1515,8 +1515,9 @@ RSpec.describe IsoDoc do
1515
1515
  </preface>
1516
1516
  </iso-standard>
1517
1517
  OUTPUT
1518
- expect(xmlpp(IsoDoc::PresentationXMLConvert.new({ suppressheadingnumbers: true })
1519
- .convert("test", input, true))).to be_equivalent_to xmlpp(output)
1518
+ expect(xmlpp(IsoDoc::PresentationXMLConvert
1519
+ .new({ suppressheadingnumbers: true })
1520
+ .convert("test", input, true))).to be_equivalent_to xmlpp(output)
1520
1521
  end
1521
1522
 
1522
1523
  it "processes simple terms & definitions" do
@@ -1525,7 +1526,7 @@ RSpec.describe IsoDoc do
1525
1526
  <sections>
1526
1527
  <terms id="H" obligation="normative"><title>Terms, Definitions, Symbols and Abbreviated Terms</title>
1527
1528
  <term id="J">
1528
- <preferred>Term2</preferred>
1529
+ <preferred><expression><name>Term2</name></expression></preferred>
1529
1530
  </term>
1530
1531
  </terms>
1531
1532
  </sections>
@@ -1786,7 +1787,7 @@ RSpec.describe IsoDoc do
1786
1787
  <title>Glossary</title>
1787
1788
  <terms id='PP1' obligation='normative'>
1788
1789
  <term id='term-glossary'>
1789
- <preferred>Glossary</preferred>
1790
+ <preferred><expression><name>Glossary</name></expression></preferred>
1790
1791
  </term>
1791
1792
  </terms>
1792
1793
  </annex>
@@ -1795,13 +1796,13 @@ RSpec.describe IsoDoc do
1795
1796
  <terms id='QQ1' obligation='normative'>
1796
1797
  <title>Term Collection</title>
1797
1798
  <term id='term-term-1'>
1798
- <preferred>Term</preferred>
1799
+ <preferred><expression><name>Term</name></expression></preferred>
1799
1800
  </term>
1800
1801
  </terms>
1801
1802
  <terms id='QQ2' obligation='normative'>
1802
1803
  <title>Term Collection 2</title>
1803
1804
  <term id='term-term-2'>
1804
- <preferred>Term</preferred>
1805
+ <preferred><expression><name>Term</name></expression></preferred>
1805
1806
  </term>
1806
1807
  </terms>
1807
1808
  </annex>
@@ -1810,7 +1811,7 @@ RSpec.describe IsoDoc do
1810
1811
  <terms id='RR1' obligation='normative'>
1811
1812
  <title>Term Collection</title>
1812
1813
  <term id='term-term-3'>
1813
- <preferred>Term</preferred>
1814
+ <preferred><expression><name>Term</name></expression></preferred>
1814
1815
  </term>
1815
1816
  </terms>
1816
1817
  <references id='RR2' obligation='normative'>