isodoc 1.7.5 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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'>