isodoc 1.3.0 → 1.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1edc88536663d06a4d23249a6ec1909148185456f84a427fe2299da8e138ab4
4
- data.tar.gz: fd6099657296706882b03eb557f59b242c733415b9d49fe8bf4e3aa73bd67eb8
3
+ metadata.gz: 29fb94d37c013e802491e2c1266e8b39d607ea3050f272f1a7bcd398e57c0283
4
+ data.tar.gz: 85ea530071d54477f462d34a5b18dbf9ba500b71a4d5ea858b62530757a6b795
5
5
  SHA512:
6
- metadata.gz: 4112c5b84d25a09e9d701b9735d80e01e9f4bf294288c097524c83e31689dc90c1dd9168e9f70061868d41c032d2b864a96b76b19f0926584a2549a1f5309a63
7
- data.tar.gz: b002124056e50a37732ad78fa9e959658b0f07c9f5af9d248f69c0d282cc74804471124fc4b7f150ba19935e3aa904df0d54222fb201e279d6325ebfffe9def8
6
+ metadata.gz: 9539cdc3d0fac50a04aa3cdf93581016306b660f1d0681a8a1e06255ed839ac9362c887b9a6f0ef7480711122c5275e0936fab640efff76c84aaa5ad84831f84
7
+ data.tar.gz: b05012f1f7189becfa14871de424ae5713a8791a9c0b520cdcca591d3f733d996c776d2f37d2c1ff23fdff6b2c146b6e09d2f9c5b97dcbeec43edafd9785dfcb
@@ -23,7 +23,10 @@ module IsoDoc::Function
23
23
  def index_parse(node, out)
24
24
  end
25
25
 
26
- def bookmark_parse(node, out)
26
+ def index_xref_parse(node, out)
27
+ end
28
+
29
+ def bookmark_parse(node, out)
27
30
  out.a **attr_code(id: node["id"])
28
31
  end
29
32
 
@@ -58,11 +58,21 @@ module IsoDoc::Function
58
58
  end
59
59
  end
60
60
 
61
+ def colgroup(node, t)
62
+ colgroup = node.at(ns("./colgroup")) or return
63
+ t.colgroup do |cg|
64
+ colgroup.xpath(ns("./col")).each do |c|
65
+ cg.col **{ style: "width: #{c['width']};" }
66
+ end
67
+ end
68
+ end
69
+
61
70
  def table_parse(node, out)
62
71
  @in_table = true
63
72
  table_title_parse(node, out)
64
73
  out.table **table_attrs(node) do |t|
65
74
  tcaption(node, t)
75
+ colgroup(node, t)
66
76
  thead_parse(node, t)
67
77
  tbody_parse(node, t)
68
78
  tfoot_parse(node, t)
@@ -215,6 +215,7 @@ module IsoDoc::Function
215
215
  when "verification" then requirement_component_parse(node, out)
216
216
  when "import" then requirement_component_parse(node, out)
217
217
  when "index" then index_parse(node, out)
218
+ when "index-xref" then index_xref_parse(node, out)
218
219
  when "termref" then termrefelem_parse(node, out)
219
220
  when "copyright-statement" then copyright_parse(node, out)
220
221
  when "license-statement" then license_parse(node, out)
@@ -97,6 +97,10 @@ module IsoDoc
97
97
  $bodyfont: '{{bodyfont}}';
98
98
  $headerfont: '{{headerfont}}';
99
99
  $monospacefont: '{{monospacefont}}';
100
+ $normalfontsize: '{{normalfontsize}}';
101
+ $smallerfontsize: '{{smallerfontsize}}';
102
+ $footnotefontsize: '{{footnotefontsize}}';
103
+ $monospacefontsize: '{{monospacefontsize}}';
100
104
  TEXT
101
105
  end
102
106
 
@@ -60,6 +60,7 @@ module IsoDoc::HtmlFunction
60
60
  <script type="text/javascript">#{toclevel}</script>
61
61
 
62
62
  <!--Google fonts-->
63
+ <link rel="preconnect" href="https://fonts.gstatic.com">
63
64
  #{googlefonts}
64
65
  <!--Font awesome import for the link icon-->
65
66
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
@@ -42,5 +42,11 @@ module IsoDoc
42
42
  lbl = @xrefs.get[f["id"]][:label] or return
43
43
  prefix_name(f, "", "#{lbl}#{clausedelim}", "name")
44
44
  end
45
+
46
+ def index(docxml)
47
+ docxml.xpath(ns("//index | //index-xref")).each do |f|
48
+ f.remove
49
+ end
50
+ end
45
51
  end
46
52
  end
@@ -30,6 +30,7 @@ module IsoDoc
30
30
  clause docxml
31
31
  annex docxml
32
32
  term docxml
33
+ index docxml
33
34
  end
34
35
 
35
36
  def block(docxml)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.3.0".freeze
2
+ VERSION = "1.3.1".freeze
3
3
  end
@@ -5,11 +5,9 @@ module IsoDoc::WordFunction
5
5
  module Postprocess
6
6
  # add namespaces for Word fragments
7
7
  WORD_NOKOHEAD = <<~HERE.freeze
8
- <!DOCTYPE html SYSTEM
9
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
8
+ <!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
10
9
  <html xmlns="http://www.w3.org/1999/xhtml"
11
- xmlns:v="urn:schemas-microsoft-com:vml"
12
- xmlns:o="urn:schemas-microsoft-com:office:office"
10
+ xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"
13
11
  xmlns:w="urn:schemas-microsoft-com:office:word"
14
12
  xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
15
13
  <head> <title></title> <meta charset="UTF-8" /> </head>
@@ -18,15 +16,13 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
18
16
 
19
17
  def to_word_xhtml_fragment(xml)
20
18
  doc = ::Nokogiri::XML.parse(WORD_NOKOHEAD)
21
- fragment = ::Nokogiri::XML::DocumentFragment.new(doc, xml, doc.root)
22
- fragment
19
+ ::Nokogiri::XML::DocumentFragment.new(doc, xml, doc.root)
23
20
  end
24
21
 
25
22
  def table_note_cleanup(docxml)
26
23
  super
27
24
  # preempt html2doc putting MsoNormal there
28
- docxml.xpath("//p[not(self::*[@class])]"\
29
- "[ancestor::*[@class = 'Note']]").each do |p|
25
+ docxml.xpath("//p[not(self::*[@class])][ancestor::*[@class = 'Note']]").each do |p|
30
26
  p["class"] = "Note"
31
27
  end
32
28
  end
@@ -56,8 +52,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
56
52
 
57
53
  def word_admonition_images(docxml)
58
54
  docxml.xpath("//div[@class = 'Admonition']//img").each do |i|
59
- i["width"], i["height"] =
60
- Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
55
+ i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
61
56
  end
62
57
  end
63
58
 
@@ -65,6 +60,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
65
60
  word_annex_cleanup(docxml)
66
61
  word_preface(docxml)
67
62
  word_nested_tables(docxml)
63
+ word_colgroup(docxml)
68
64
  word_table_align(docxml)
69
65
  word_table_separator(docxml)
70
66
  word_admonition_images(docxml)
@@ -78,28 +74,44 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
78
74
  docxml
79
75
  end
80
76
 
81
- def word_nested_tables(docxml)
82
- docxml.xpath("//table").each do |t|
83
- t.xpath(".//table").reverse.each do |tt|
84
- t.next = tt.remove
77
+ def word_colgroup(docxml)
78
+ cells2d = {}
79
+ docxml.xpath("//table[colgroup]").each do |t|
80
+ w = colgroup_widths(t)
81
+ t.xpath(".//tr").each_with_index { |tr, r| cells2d[r] = {} }
82
+ t.xpath(".//tr").each_with_index do |tr, r|
83
+ tr.xpath("./td | ./th").each_with_index do |td, i|
84
+ x = 0
85
+ rs = td&.attr("rowspan")&.to_i || 1
86
+ cs = td&.attr("colspan")&.to_i || 1
87
+ while cells2d[r][x] do
88
+ x += 1
89
+ end
90
+ for y2 in r..(r + rs - 1)
91
+ for x2 in x..(x + cs - 1)
92
+ cells2d[y2][x2] = 1
93
+ end
94
+ end
95
+ width = (x..(x+cs-1)).each_with_object({width: 0}) { |z, m| m[:width] += w[z] }
96
+ td["width"] = "#{width[:width]}%"
97
+ x += cs
98
+ end
85
99
  end
86
100
  end
87
101
  end
88
102
 
89
- def authority_cleanup1(docxml, klass)
90
- dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
91
- auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
92
- auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each { |h| h.remove }
93
- auth&.xpath(".//h1 | .//h2")&.each do |h|
94
- h.name = "p"
95
- h["class"] = "TitlePageSubhead"
103
+ # assume percentages
104
+ def colgroup_widths(t)
105
+ t.xpath("./colgroup/col").each_with_object([]) do |c, m|
106
+ m << c["width"].sub(/%$/, "").to_f
96
107
  end
97
- dest and auth and dest.replace(auth.remove)
98
108
  end
99
109
 
100
- def authority_cleanup(docxml)
101
- %w(copyright license legal feedback).each do |t|
102
- authority_cleanup1(docxml, t)
110
+ def word_nested_tables(docxml)
111
+ docxml.xpath("//table").each do |t|
112
+ t.xpath(".//table").reverse.each do |tt|
113
+ t.next = tt.remove
114
+ end
103
115
  end
104
116
  end
105
117
 
@@ -144,19 +156,6 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
144
156
  end
145
157
  end
146
158
 
147
- =begin
148
- EMPTY_PARA = "<p style='margin-top:0cm;margin-right:0cm;"\
149
- "margin-bottom:0cm;margin-left:0.0pt;margin-bottom:.0001pt;"\
150
- "line-height:1.0pt;mso-line-height-rule:exactly'>"\
151
- "<span lang=EN-GB style='display:none;mso-hide:all'>&nbsp;</span></p>"
152
-
153
- def table_after_table(docxml)
154
- docxml.xpath("//table[following-sibling::*[1]/self::table]").each do |t|
155
- t.add_next_sibling(EMPTY_PARA)
156
- end
157
- end
158
- =end
159
-
160
159
  def word_table_separator(docxml)
161
160
  docxml.xpath("//p[@class = 'TableTitle']").each do |t|
162
161
  next unless t.children.empty?
@@ -180,46 +179,6 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
180
179
  end
181
180
  end
182
181
 
183
- def generate_header(filename, _dir)
184
- return nil unless @header
185
- template = IsoDoc::Common.liquid(File.read(@header, encoding: "UTF-8"))
186
- meta = @meta.get.merge(@labels || {}).merge(@meta.labels || {})
187
- meta[:filename] = filename
188
- params = meta.map { |k, v| [k.to_s, v] }.to_h
189
- Tempfile.open(%w(header html), :encoding => "utf-8") do |f|
190
- f.write(template.render(params))
191
- f
192
- end
193
- end
194
-
195
- def word_section_breaks(docxml)
196
- @landscapestyle = ""
197
- word_section_breaks1(docxml, "WordSection2")
198
- word_section_breaks1(docxml, "WordSection3")
199
- word_remove_pb_before_annex(docxml)
200
- docxml.xpath("//br[@orientation]").each { |br| br.delete("orientation") }
201
- end
202
-
203
- def word_section_breaks1(docxml, sect)
204
- docxml.xpath("//div[@class = '#{sect}']//br[@orientation]").reverse.
205
- each_with_index do |br, i|
206
- @landscapestyle += "\ndiv.#{sect}_#{i} {page:#{sect}"\
207
- "#{br["orientation"] == "landscape" ? "L" : "P"};}\n"
208
- split_at_section_break(docxml, sect, br, i)
209
- end
210
- end
211
-
212
- def split_at_section_break(docxml, sect, br, i)
213
- move = br.parent.xpath("following::node()") &
214
- br.document.xpath("//div[@class = '#{sect}']//*")
215
- ins = docxml.at("//div[@class = '#{sect}']").
216
- after("<div class='#{sect}_#{i}'/>").next_element
217
- move.each do |m|
218
- next if m.at("./ancestor::div[@class = '#{sect}_#{i}']")
219
- ins << m.remove
220
- end
221
- end
222
-
223
182
  # applies for <div class="WordSectionN_M"><p><pagebreak/></p>...
224
183
  def word_remove_pb_before_annex(docxml)
225
184
  docxml.xpath("//div[p/br]").each do |d|
@@ -237,8 +196,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
237
196
  docxml.xpath("//a[@epub:type = 'footnote']").each do |x|
238
197
  footnote_reference_format(x)
239
198
  end
240
- docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
241
- "//span[@class = 'TableFootnoteRef']").each do |x|
199
+ docxml.xpath("//a[@class = 'TableFootnoteRef'] | //span[@class = 'TableFootnoteRef']").each do |x|
242
200
  table_footnote_reference_format(x)
243
201
  end
244
202
  docxml
@@ -75,5 +75,60 @@ module IsoDoc::WordFunction
75
75
  toc.sub(/(<p class="MsoToc1">)/,
76
76
  %{\\1#{word_toc_preface(level)}}) + WORD_TOC_SUFFIX1
77
77
  end
78
+
79
+ def authority_cleanup1(docxml, klass)
80
+ dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
81
+ auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or @class = 'boilerplate-#{klass}']")
82
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each { |h| h.remove }
83
+ auth&.xpath(".//h1 | .//h2")&.each do |h|
84
+ h.name = "p"
85
+ h["class"] = "TitlePageSubhead"
86
+ end
87
+ dest and auth and dest.replace(auth.remove)
88
+ end
89
+
90
+ def authority_cleanup(docxml)
91
+ %w(copyright license legal feedback).each do |t|
92
+ authority_cleanup1(docxml, t)
93
+ end
94
+ end
95
+
96
+ def generate_header(filename, _dir)
97
+ return nil unless @header
98
+ template = IsoDoc::Common.liquid(File.read(@header, encoding: "UTF-8"))
99
+ meta = @meta.get.merge(@labels || {}).merge(@meta.labels || {})
100
+ meta[:filename] = filename
101
+ params = meta.map { |k, v| [k.to_s, v] }.to_h
102
+ Tempfile.open(%w(header html), :encoding => "utf-8") do |f|
103
+ f.write(template.render(params))
104
+ f
105
+ end
106
+ end
107
+
108
+ def word_section_breaks(docxml)
109
+ @landscapestyle = ""
110
+ word_section_breaks1(docxml, "WordSection2")
111
+ word_section_breaks1(docxml, "WordSection3")
112
+ word_remove_pb_before_annex(docxml)
113
+ docxml.xpath("//br[@orientation]").each { |br| br.delete("orientation") }
114
+ end
115
+
116
+ def word_section_breaks1(docxml, sect)
117
+ docxml.xpath("//div[@class = '#{sect}']//br[@orientation]").reverse.
118
+ each_with_index do |br, i|
119
+ @landscapestyle += "\ndiv.#{sect}_#{i} {page:#{sect}#{br["orientation"] == "landscape" ? "L" : "P"};}\n"
120
+ split_at_section_break(docxml, sect, br, i)
121
+ end
122
+ end
123
+
124
+ def split_at_section_break(docxml, sect, br, i)
125
+ move = br.parent.xpath("following::node()") &
126
+ br.document.xpath("//div[@class = '#{sect}']//*")
127
+ ins = docxml.at("//div[@class = '#{sect}']").after("<div class='#{sect}_#{i}'/>").next_element
128
+ move.each do |m|
129
+ next if m.at("./ancestor::div[@class = '#{sect}_#{i}']")
130
+ ins << m.remove
131
+ end
132
+ end
78
133
  end
79
134
  end
@@ -43,11 +43,21 @@ module IsoDoc::WordFunction
43
43
  }))
44
44
  end
45
45
 
46
+ def colgroup(node, t)
47
+ colgroup = node.at(ns("./colgroup")) or return
48
+ t.colgroup do |cg|
49
+ colgroup.xpath(ns("./col")).each do |c|
50
+ cg.col **{ width: c["width"] }
51
+ end
52
+ end
53
+ end
54
+
46
55
  def table_parse(node, out)
47
56
  @in_table = true
48
57
  table_title_parse(node, out)
49
58
  out.div **{ align: "center", class: "table_container" } do |div|
50
59
  div.table **table_attrs(node) do |t|
60
+ colgroup(node, t)
51
61
  thead_parse(node, t)
52
62
  tbody_parse(node, t)
53
63
  tfoot_parse(node, t)
@@ -49,6 +49,7 @@ module IsoDoc
49
49
  note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
50
50
  example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
51
51
  list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
52
+ bookmark_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
52
53
  end
53
54
 
54
55
  def ns(xpath)
@@ -66,6 +66,10 @@ module IsoDoc::XrefGen
66
66
  "//sections/clause | //sections/definitions | "\
67
67
  "//bibliography/references | //bibliography/clause".freeze
68
68
 
69
+ def sections_xpath
70
+ SECTIONS_XPATH
71
+ end
72
+
69
73
  CHILD_NOTES_XPATH =
70
74
  "./*[not(self::xmlns:clause) and not(self::xmlns:appendix) and "\
71
75
  "not(self::xmlns:terms) and not(self::xmlns:definitions)]//xmlns:note | "\
@@ -136,5 +140,19 @@ module IsoDoc::XrefGen
136
140
  end
137
141
  end
138
142
  end
143
+
144
+ def bookmark_anchor_names(sections)
145
+ sections.each do |s|
146
+ notes = s.xpath(ns(".//bookmark")) - s.xpath(ns(".//clause//bookmark")) -
147
+ s.xpath(ns(".//appendix//bookmark"))
148
+ notes.each do |n|
149
+ next if n["id"].nil? || n["id"].empty?
150
+ @anchors[n["id"]] = {
151
+ type: "bookmark", label: nil, value: nil,
152
+ xref: @anchors[s["id"]][:xref] }
153
+ end
154
+ bookmark_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
155
+ end
156
+ end
139
157
  end
140
158
  end
@@ -1186,5 +1186,4 @@ modified &mdash; with adjustments]
1186
1186
  </html>
1187
1187
  OUTPUT
1188
1188
  end
1189
-
1190
1189
  end
@@ -117,7 +117,7 @@ OUTPUT
117
117
  end
118
118
 
119
119
  it "ignores index entries" do
120
- expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
120
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
121
121
  <iso-standard xmlns="http://riboseinc.com/isoxml">
122
122
  <preface><foreword>
123
123
  <p><index primary="A" secondary="B" tertiary="C"/></p>
@@ -125,16 +125,14 @@ OUTPUT
125
125
  <sections>
126
126
  </iso-standard>
127
127
  INPUT
128
- #{HTML_HDR}
129
- <br/>
130
- <div>
131
- <h1 class='ForewordTitle'>Foreword</h1>
132
- <p/>
133
- </div>
134
- <p class='zzSTDTitle1'/>
135
- </div>
136
- </body>
137
- </html>
128
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
129
+ <preface>
130
+ <foreword>
131
+ <p/>
132
+ </foreword>
133
+ </preface>
134
+ <sections> </sections>
135
+ </iso-standard>
138
136
  OUTPUT
139
137
  end
140
138
 
@@ -1594,4 +1594,277 @@ OUTPUT
1594
1594
  OUTPUT
1595
1595
  end
1596
1596
 
1597
+
1598
+ it "allocate widths to tables (Word)" do
1599
+ expect(xmlpp(IsoDoc::WordConvert.new({wordstylesheet: "spec/assets/word.css", htmlstylesheet: "spec/assets/html.scss", filename: "test"}).word_cleanup(Nokogiri::XML(<<~INPUT)).to_xml).sub(/^.*<main/m, "<main").sub(%r{</main>.*$}m, "</main>")).to be_equivalent_to xmlpp(<<~"OUTPUT")
1600
+ <html xmlns:epub="http://www.idpf.org/2007/ops" lang="en">
1601
+ <head><style/></head>
1602
+ <body lang='EN-US' link='blue' vlink='#954F72'>
1603
+ <div class='WordSection1'>
1604
+ <p>&#160;</p>
1605
+ </div>
1606
+ <p>
1607
+ <br clear='all' class='section'/>
1608
+ </p>
1609
+ <div class='WordSection2'>
1610
+ <p>
1611
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
1612
+ </p>
1613
+ <div>
1614
+ <h1 class='ForewordTitle'>Foreword</h1>
1615
+ <p class='TableTitle' style='text-align:center;'>
1616
+ Table 1&#160;&#8212; Repeatability and reproducibility of
1617
+ <i>husked</i>
1618
+ rice yield
1619
+ <span style='mso-bookmark:_Ref'>
1620
+ <a class='FootnoteRef' href='#ftn1' epub:type='footnote'>
1621
+ <sup>1</sup>
1622
+ </a>
1623
+ </span>
1624
+ </p>
1625
+ <div align='center' class='table_container'>
1626
+ <table id='tableD-1' class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;page-break-after: avoid;page-break-inside: avoid;' title='tool tip' summary='long desc' width='70%'>
1627
+ <colgroup>
1628
+ <col width='30%'/>
1629
+ <col width='20%'/>
1630
+ <col width='20%'/>
1631
+ <col width='20%'/>
1632
+ <col width='10%'/>
1633
+ </colgroup>
1634
+ <thead>
1635
+ <tr>
1636
+ <td rowspan='2' align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>Description</td>
1637
+ <td colspan='4' align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>Rice sample</td>
1638
+ </tr>
1639
+ <tr>
1640
+ <td align='left' valign="top" style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>Arborio</td>
1641
+ <td align='center' valign="middle" style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
1642
+ Drago
1643
+ <a href='#tableD-1a' class='TableFootnoteRef'>a</a>
1644
+ <aside>
1645
+ <div id='ftntableD-1a'>
1646
+ <span>
1647
+ <span id='tableD-1a' class='TableFootnoteRef'>a</span>
1648
+ <span style='mso-tab-count:1'>&#160; </span>
1649
+ </span>
1650
+ <p id='_0fe65e9a-5531-408e-8295-eeff35f41a55'>Parboiled rice.</p>
1651
+ </div>
1652
+ </aside>
1653
+ </td>
1654
+ <td align='center' valign="bottom" style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
1655
+ Balilla
1656
+ <a href='#tableD-1a' class='TableFootnoteRef'>a</a>
1657
+ </td>
1658
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>Thaibonnet</td>
1659
+ </tr>
1660
+ </thead>
1661
+ <tbody>
1662
+ <tr>
1663
+ <th align='left' style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>Number of laboratories retained after eliminating outliers</th>
1664
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>13</td>
1665
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>11</td>
1666
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>13</td>
1667
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;'>13</td>
1668
+ </tr>
1669
+ <tr>
1670
+ <td align='left' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>Mean value, g/100 g</td>
1671
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>81,2</td>
1672
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>82,0</td>
1673
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>81,8</td>
1674
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>77,7</td>
1675
+ </tr>
1676
+ </tbody>
1677
+ <tfoot>
1678
+ <tr>
1679
+ <td align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
1680
+ Reproducibility limit,
1681
+ <span class='stem'>(#(R)#)</span>
1682
+ (= 2,83
1683
+ <span class='stem'>(#(s_R)#)</span>
1684
+ )
1685
+ </td>
1686
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>2,89</td>
1687
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>0,57</td>
1688
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>2,26</td>
1689
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>6,06</td>
1690
+ </tr>
1691
+ </tfoot>
1692
+ <table class='dl'>
1693
+ <tr>
1694
+ <td valign='top' align='left'>
1695
+ <p align='left' style='margin-left:0pt;text-align:left;'>Drago</p>
1696
+ </td>
1697
+ <td valign='top'>A type of rice</td>
1698
+ </tr>
1699
+ </table>
1700
+ <div class='Note'>
1701
+ <p class='Note'>
1702
+ <span class='note_label'>NOTE</span>
1703
+ <span style='mso-tab-count:1'>&#160; </span>
1704
+ This is a table about rice
1705
+ </p>
1706
+ </div>
1707
+ </table>
1708
+ </div>
1709
+ <div align='center' class='table_container'>
1710
+ <table id='tableD-2' class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;'>
1711
+ <tbody>
1712
+ <tr>
1713
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>A</td>
1714
+ </tr>
1715
+ </tbody>
1716
+ </table>
1717
+ </div>
1718
+ </div>
1719
+ <p>&#160;</p>
1720
+ </div>
1721
+ <p>
1722
+ <br clear='all' class='section'/>
1723
+ </p>
1724
+ <div class='WordSection3'>
1725
+ <p class='zzSTDTitle1'/>
1726
+ <aside id='ftn1'>
1727
+ <p>X</p>
1728
+ </aside>
1729
+ </div>
1730
+ </body>
1731
+ </html>
1732
+ INPUT
1733
+ <html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
1734
+ <head>
1735
+ <style/>
1736
+ </head>
1737
+ <body lang='EN-US' link='blue' vlink='#954F72'>
1738
+ <div class='WordSection1'>
1739
+ <p>&#xA0;</p>
1740
+ </div>
1741
+ <p>
1742
+ <br clear='all' class='section'/>
1743
+ </p>
1744
+ <div class='WordSection2'>
1745
+ <p>
1746
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
1747
+ </p>
1748
+ <div>
1749
+ <h1 class='ForewordTitle'>Foreword</h1>
1750
+ <p class='TableTitle' style='text-align:center;'>
1751
+ Table 1&#xA0;&#x2014; Repeatability and reproducibility of
1752
+ <i>husked</i>
1753
+ rice yield
1754
+ <span style='mso-bookmark:_Ref'>
1755
+ <a class='FootnoteRef' href='#ftn1' epub:type='footnote'>
1756
+ <sup>1</sup>
1757
+ </a>
1758
+ </span>
1759
+ </p>
1760
+ <div align='center' class='table_container'>
1761
+ <table id='tableD-1' class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;page-break-after: avoid;page-break-inside: avoid;' title='tool tip' summary='long desc' width='70%'>
1762
+ <colgroup>
1763
+ <col width='30%'/>
1764
+ <col width='20%'/>
1765
+ <col width='20%'/>
1766
+ <col width='20%'/>
1767
+ <col width='10%'/>
1768
+ </colgroup>
1769
+ <thead>
1770
+ <tr>
1771
+ <td rowspan='2' align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='30.0%'>Description</td>
1772
+ <td colspan='4' align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='70.0%'>Rice sample</td>
1773
+ </tr>
1774
+ <tr>
1775
+ <td align='left' valign='top' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>Arborio</td>
1776
+ <td align='center' valign='middle' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>
1777
+ Drago
1778
+ <a href='#tableD-1a' class='TableFootnoteRef'>a</a>
1779
+ <aside>
1780
+ <div id='ftntableD-1a'>
1781
+ <span>
1782
+ <span id='tableD-1a' class='TableFootnoteRef'>a</span>
1783
+ <span style='mso-tab-count:1'>&#xA0; </span>
1784
+ </span>
1785
+ <p id='_0fe65e9a-5531-408e-8295-eeff35f41a55'>Parboiled rice.</p>
1786
+ </div>
1787
+ </aside>
1788
+ </td>
1789
+ <td align='center' valign='bottom' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>
1790
+ Balilla
1791
+ <a href='#tableD-1a' class='TableFootnoteRef'>a</a>
1792
+ </td>
1793
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='10.0%'>Thaibonnet</td>
1794
+ </tr>
1795
+ </thead>
1796
+ <tbody>
1797
+ <tr>
1798
+ <th align='left' style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='30.0%'>Number of laboratories retained after eliminating outliers</th>
1799
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='20.0%'>13</td>
1800
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='20.0%'>11</td>
1801
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='20.0%'>13</td>
1802
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.0pt;mso-border-bottom-alt:solid windowtext 1.0pt;' width='10.0%'>13</td>
1803
+ </tr>
1804
+ <tr>
1805
+ <td align='left' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='30.0%'>Mean value, g/100 g</td>
1806
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>81,2</td>
1807
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>82,0</td>
1808
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>81,8</td>
1809
+ <td align='center' style='border-top:none;mso-border-top-alt:none;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='10.0%'>77,7</td>
1810
+ </tr>
1811
+ </tbody>
1812
+ <tfoot>
1813
+ <tr>
1814
+ <td align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='30.0%'>
1815
+ Reproducibility limit,
1816
+ <span class='stem'>(#(R)#)</span>
1817
+ (= 2,83
1818
+ <span class='stem'>(#(s_R)#)</span>
1819
+ )
1820
+ </td>
1821
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>2,89</td>
1822
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>0,57</td>
1823
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='20.0%'>2,26</td>
1824
+ <td align='center' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' width='10.0%'>6,06</td>
1825
+ </tr>
1826
+ </tfoot>
1827
+ <div class='Note'>
1828
+ <p class='Note'>
1829
+ <span class='note_label'>NOTE</span>
1830
+ <span style='mso-tab-count:1'>&#xA0; </span>
1831
+ This is a table about rice
1832
+ </p>
1833
+ </div>
1834
+ </table>
1835
+ <table class='dl'>
1836
+ <tr>
1837
+ <td valign='top' align='left'>
1838
+ <p align='left' style='margin-left:0pt;text-align:left;'>Drago</p>
1839
+ </td>
1840
+ <td valign='top'>A type of rice</td>
1841
+ </tr>
1842
+ </table>
1843
+ </div>
1844
+ <div align='center' class='table_container'>
1845
+ <table id='tableD-2' class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;'>
1846
+ <tbody>
1847
+ <tr>
1848
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>A</td>
1849
+ </tr>
1850
+ </tbody>
1851
+ </table>
1852
+ </div>
1853
+ </div>
1854
+ <p>&#xA0;</p>
1855
+ </div>
1856
+ <p>
1857
+ <br clear='all' class='section'/>
1858
+ </p>
1859
+ <div class='WordSection3'>
1860
+ <p class='zzSTDTitle1'/>
1861
+ <aside id='ftn1'>
1862
+ <p>X</p>
1863
+ </aside>
1864
+ </div>
1865
+ </body>
1866
+ </html>
1867
+ OUTPUT
1868
+ end
1869
+
1597
1870
  end
@@ -8,6 +8,13 @@ RSpec.describe IsoDoc do
8
8
  <foreword>
9
9
  <table id="tableD-1" alt="tool tip" summary="long desc" width="70%" keep-with-next="true" keep-lines-together="true">
10
10
  <name>Repeatability and reproducibility of <em>husked</em> rice yield<fn reference="1"><p>X</p></fn></name>
11
+ <colgroup>
12
+ <col width="30%"/>
13
+ <col width="20%"/>
14
+ <col width="20%"/>
15
+ <col width="20%"/>
16
+ <col width="10%"/>
17
+ </colgroup>
11
18
  <thead>
12
19
  <tr>
13
20
  <td rowspan="2" align="left">Description</td>
@@ -77,6 +84,13 @@ RSpec.describe IsoDoc do
77
84
  <p>X</p>
78
85
  </fn>
79
86
  </name>
87
+ <colgroup>
88
+ <col width='30%'/>
89
+ <col width='20%'/>
90
+ <col width='20%'/>
91
+ <col width='20%'/>
92
+ <col width='10%'/>
93
+ </colgroup>
80
94
  <thead>
81
95
  <tr>
82
96
  <td rowspan='2' align='left'>Description</td>
@@ -165,6 +179,13 @@ html = <<~OUTPUT
165
179
  <caption>
166
180
  <span style="display:none">long desc</span>
167
181
  </caption>
182
+ <colgroup>
183
+ <col style='width: 30%;'/>
184
+ <col style='width: 20%;'/>
185
+ <col style='width: 20%;'/>
186
+ <col style='width: 20%;'/>
187
+ <col style='width: 10%;'/>
188
+ </colgroup>
168
189
  <thead>
169
190
  <tr>
170
191
  <td rowspan="2" style="text-align:left;border-top:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;" scope="col">Description</td>
@@ -259,6 +280,13 @@ html = <<~OUTPUT
259
280
  </p>
260
281
  <div align='center' class='table_container'>
261
282
  <table id='tableD-1' class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;page-break-after: avoid;page-break-inside: avoid;' title='tool tip' summary='long desc' width='70%'>
283
+ <colgroup>
284
+ <col width='30%'/>
285
+ <col width='20%'/>
286
+ <col width='20%'/>
287
+ <col width='20%'/>
288
+ <col width='10%'/>
289
+ </colgroup>
262
290
  <thead>
263
291
  <tr>
264
292
  <td rowspan='2' align='left' style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>Description</td>
@@ -2547,6 +2547,151 @@ OUTPUT
2547
2547
  OUTPUT
2548
2548
  end
2549
2549
 
2550
+ it "cross-references bookmarks" do
2551
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
2552
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
2553
+ <preface>
2554
+ <foreword>
2555
+ <p>
2556
+ <xref target="N1"/>
2557
+ <xref target="N2"/>
2558
+ <xref target="N"/>
2559
+ <xref target="note1"/>
2560
+ <xref target="note2"/>
2561
+ <xref target="AN"/>
2562
+ <xref target="Anote1"/>
2563
+ <xref target="Anote2"/>
2564
+ </p>
2565
+ </foreword>
2566
+ <introduction id="intro">
2567
+ <p id="N01">
2568
+ <bookmark id="N1"/>
2569
+ </p>
2570
+ <clause id="xyz"><title>Preparatory</title>
2571
+ <p id="N02" type="arabic">
2572
+ <bookmark id="N2"/>
2573
+ </p>
2574
+ </clause>
2575
+ </introduction>
2576
+ </preface>
2577
+ <sections>
2578
+ <clause id="scope" type="scope"><title>Scope</title>
2579
+ <p id="N0" type="roman">
2580
+ <bookmark id="N"/>
2581
+ </p>
2582
+ </clause>
2583
+ <terms id="terms"/>
2584
+ <clause id="widgets"><title>Widgets</title>
2585
+ <clause id="widgets1">
2586
+ <p id="note1l" type="alphabet">
2587
+ <bookmark id="note1"/>
2588
+ </p>
2589
+ <p id="note2l" type="roman_upper">
2590
+ <bookmark id="note2"/>
2591
+ </p>
2592
+ </clause>
2593
+ </clause>
2594
+ </sections>
2595
+ <annex id="annex1">
2596
+ <clause id="annex1a">
2597
+ <p id="ANl" type="alphabet_upper">
2598
+ <bookmark id="AN"/>
2599
+ </p>
2600
+ </clause>
2601
+ <clause id="annex1b">
2602
+ <p id="Anote1l" type="roman" start="4">
2603
+ <bookmark id="Anote1"/>
2604
+ </p>
2605
+ <p id="Anote2l">
2606
+ <bookmark id="Anote2"/>
2607
+ </p>
2608
+ </clause>
2609
+ </annex>
2610
+ </iso-standard>
2611
+ INPUT
2612
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
2613
+ <preface>
2614
+ <foreword>
2615
+ <p>
2616
+ <xref target='N1'>Introduction</xref>
2617
+ <xref target='N2'>Preparatory</xref>
2618
+ <xref target='N'>Clause 1</xref>
2619
+ <xref target='note1'>Clause 3.1</xref>
2620
+ <xref target='note2'>Clause 3.1</xref>
2621
+ <xref target='AN'>Annex A.1</xref>
2622
+ <xref target='Anote1'>Annex A.2</xref>
2623
+ <xref target='Anote2'>Annex A.2</xref>
2624
+ </p>
2625
+ </foreword>
2626
+ <introduction id='intro'>
2627
+ <p id='N01'>
2628
+ <bookmark id='N1'/>
2629
+ </p>
2630
+ <clause id='xyz'>
2631
+ <title depth='2'>Preparatory</title>
2632
+ <p id='N02' type='arabic'>
2633
+ <bookmark id='N2'/>
2634
+ </p>
2635
+ </clause>
2636
+ </introduction>
2637
+ </preface>
2638
+ <sections>
2639
+ <clause id='scope' type='scope'>
2640
+ <title depth='1'>
2641
+ 1.
2642
+ <tab/>
2643
+ Scope
2644
+ </title>
2645
+ <p id='N0' type='roman'>
2646
+ <bookmark id='N'/>
2647
+ </p>
2648
+ </clause>
2649
+ <terms id='terms'>
2650
+ <title>2.</title>
2651
+ </terms>
2652
+ <clause id='widgets'>
2653
+ <title depth='1'>
2654
+ 3.
2655
+ <tab/>
2656
+ Widgets
2657
+ </title>
2658
+ <clause id='widgets1'>
2659
+ <title>3.1.</title>
2660
+ <p id='note1l' type='alphabet'>
2661
+ <bookmark id='note1'/>
2662
+ </p>
2663
+ <p id='note2l' type='roman_upper'>
2664
+ <bookmark id='note2'/>
2665
+ </p>
2666
+ </clause>
2667
+ </clause>
2668
+ </sections>
2669
+ <annex id='annex1'>
2670
+ <title>
2671
+ <strong>Annex A</strong>
2672
+ <br/>
2673
+ (informative)
2674
+ </title>
2675
+ <clause id='annex1a'>
2676
+ <title>A.1.</title>
2677
+ <p id='ANl' type='alphabet_upper'>
2678
+ <bookmark id='AN'/>
2679
+ </p>
2680
+ </clause>
2681
+ <clause id='annex1b'>
2682
+ <title>A.2.</title>
2683
+ <p id='Anote1l' type='roman' start='4'>
2684
+ <bookmark id='Anote1'/>
2685
+ </p>
2686
+ <p id='Anote2l'>
2687
+ <bookmark id='Anote2'/>
2688
+ </p>
2689
+ </clause>
2690
+ </annex>
2691
+ </iso-standard>
2692
+ OUTPUT
2693
+ end
2694
+
2550
2695
  it "realises subsequences" do
2551
2696
  expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
2552
2697
  <iso-standard xmlns="http://riboseinc.com/isoxml">
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2020-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciimath