isodoc 1.3.0 → 1.3.1

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