isodoc 1.0.26 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +12 -8
  3. data/.github/workflows/ubuntu.yml +26 -16
  4. data/.github/workflows/windows.yml +12 -8
  5. data/isodoc.gemspec +2 -2
  6. data/lib/isodoc.rb +2 -0
  7. data/lib/isodoc/common.rb +0 -4
  8. data/lib/isodoc/convert.rb +18 -8
  9. data/lib/isodoc/function/blocks.rb +43 -54
  10. data/lib/isodoc/function/blocks_example_note.rb +108 -0
  11. data/lib/isodoc/function/cleanup.rb +14 -2
  12. data/lib/isodoc/function/i18n.rb +1 -0
  13. data/lib/isodoc/function/inline.rb +76 -82
  14. data/lib/isodoc/function/inline_simple.rb +72 -0
  15. data/lib/isodoc/function/lists.rb +12 -6
  16. data/lib/isodoc/function/references.rb +65 -57
  17. data/lib/isodoc/function/reqt.rb +14 -5
  18. data/lib/isodoc/function/section.rb +8 -11
  19. data/lib/isodoc/function/table.rb +4 -5
  20. data/lib/isodoc/function/terms.rb +3 -3
  21. data/lib/isodoc/function/to_word_html.rb +22 -13
  22. data/lib/isodoc/function/utils.rb +9 -3
  23. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  24. data/lib/isodoc/html_convert.rb +2 -1
  25. data/lib/isodoc/html_function/footnotes.rb +1 -1
  26. data/lib/isodoc/html_function/html.rb +16 -1
  27. data/lib/isodoc/html_function/postprocess.rb +6 -5
  28. data/lib/isodoc/metadata.rb +6 -0
  29. data/lib/isodoc/pdf_convert.rb +8 -6
  30. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  31. data/lib/isodoc/version.rb +1 -1
  32. data/lib/isodoc/word_convert.rb +2 -1
  33. data/lib/isodoc/word_function/body.rb +14 -48
  34. data/lib/isodoc/word_function/footnotes.rb +1 -1
  35. data/lib/isodoc/word_function/inline.rb +75 -0
  36. data/lib/isodoc/word_function/postprocess.rb +1 -0
  37. data/lib/isodoc/word_function/table.rb +3 -3
  38. data/lib/isodoc/xref.rb +59 -0
  39. data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
  40. data/lib/isodoc/xref/xref_counter.rb +74 -0
  41. data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
  42. data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
  43. data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
  44. data/lib/isodoc/xslfo_convert.rb +16 -4
  45. data/spec/assets/i18n.yaml +4 -1
  46. data/spec/assets/odf.emf +0 -0
  47. data/spec/assets/odf.svg +4 -0
  48. data/spec/assets/odf1.svg +4 -0
  49. data/spec/isodoc/blocks_spec.rb +240 -59
  50. data/spec/isodoc/cleanup_spec.rb +139 -17
  51. data/spec/isodoc/footnotes_spec.rb +20 -5
  52. data/spec/isodoc/inline_spec.rb +296 -1
  53. data/spec/isodoc/lists_spec.rb +8 -8
  54. data/spec/isodoc/metadata_spec.rb +110 -3
  55. data/spec/isodoc/postproc_spec.rb +10 -14
  56. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  57. data/spec/isodoc/ref_spec.rb +119 -50
  58. data/spec/isodoc/section_spec.rb +84 -18
  59. data/spec/isodoc/table_spec.rb +28 -28
  60. data/spec/isodoc/terms_spec.rb +7 -7
  61. data/spec/isodoc/xref_spec.rb +177 -57
  62. metadata +24 -17
  63. data/lib/isodoc/function/blocks_example.rb +0 -53
  64. data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -1,18 +1,16 @@
1
- module IsoDoc::Function
2
- module XrefSectGen
1
+ module IsoDoc::XrefGen
2
+ module Sections
3
3
  def back_anchor_names(docxml)
4
4
  docxml.xpath(ns("//annex")).each_with_index do |c, i|
5
5
  annex_names(c, (65 + i).chr.to_s)
6
6
  end
7
7
  docxml.xpath(
8
- ns("//bibliography/clause[.//references[@normative = 'false']] | "\
9
- "//bibliography/references[@normative = 'false']"
10
- )).each do |b|
11
- preface_names(b)
12
- end
13
- docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |ref|
14
- reference_names(ref)
15
- end
8
+ ns(@klass.bibliography_xpath)).each do |b|
9
+ preface_names(b)
10
+ end
11
+ docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |ref|
12
+ reference_names(ref)
13
+ end
16
14
  end
17
15
 
18
16
  def initial_anchor_names(d)
@@ -20,9 +18,7 @@ module IsoDoc::Function
20
18
  # potentially overridden in middle_section_asset_names()
21
19
  sequential_asset_names(d.xpath(ns("//preface/*")))
22
20
  n = section_names(d.at(ns("//clause[title = 'Scope']")), 0, 1)
23
- n = section_names(d.at(ns(
24
- "//bibliography/clause[.//references[@normative = 'true']] | "\
25
- "//bibliography/references[@normative = 'true']")), n, 1)
21
+ n = section_names(d.at(ns(@klass.norm_ref_xpath)), n, 1)
26
22
  n = section_names(d.at(ns("//sections/terms | "\
27
23
  "//sections/clause[descendant::terms]")), n, 1)
28
24
  n = section_names(d.at(ns("//sections/definitions")), n, 1)
@@ -65,15 +61,14 @@ module IsoDoc::Function
65
61
 
66
62
  def middle_section_asset_names(d)
67
63
  middle_sections = "//clause[title = 'Scope'] | "\
68
- "//references[@normative = 'true'] | "\
64
+ "#{@klass.norm_ref_xpath} | "\
69
65
  "//sections/terms | //preface/* | "\
70
66
  "//sections/definitions | //clause[parent::sections]"
71
67
  sequential_asset_names(d.xpath(ns(middle_sections)))
72
68
  end
73
69
 
74
70
  def clause_names(docxml, sect_num)
75
- q = self.class::MIDDLE_CLAUSE
76
- docxml.xpath(ns(q)).each_with_index do |c, i|
71
+ docxml.xpath(ns(@klass.middle_clause)).each_with_index do |c, i|
77
72
  section_names(c, (i + sect_num), 1)
78
73
  end
79
74
  end
@@ -82,7 +77,7 @@ module IsoDoc::Function
82
77
  return num if clause.nil?
83
78
  num = num + 1
84
79
  @anchors[clause["id"]] =
85
- { label: num.to_s, xref: l10n("#{@clause_lbl} #{num}"), level: lvl,
80
+ { label: num.to_s, xref: l10n("#{@labels["clause"]} #{num}"), level: lvl,
86
81
  type: "clause" }
87
82
  clause.xpath(ns(SUBCLAUSES)).
88
83
  each_with_index do |c, i|
@@ -93,7 +88,7 @@ module IsoDoc::Function
93
88
 
94
89
  def section_names1(clause, num, level)
95
90
  @anchors[clause["id"]] =
96
- { label: num, level: level, xref: l10n("#{@clause_lbl} #{num}"),
91
+ { label: num, level: level, xref: l10n("#{@labels["clause"]} #{num}"),
97
92
  type: "clause" }
98
93
  clause.xpath(ns(SUBCLAUSES)).
99
94
  each_with_index do |c, i|
@@ -102,9 +97,9 @@ module IsoDoc::Function
102
97
  end
103
98
 
104
99
  def annex_name_lbl(clause, num)
105
- obl = l10n("(#{@inform_annex_lbl})")
106
- obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
107
- l10n("<b>#{@annex_lbl} #{num}</b><br/>#{obl}")
100
+ obl = l10n("(#{@labels["inform_annex"]})")
101
+ obl = l10n("(#{@labels["norm_annex"]})") if clause["obligation"] == "normative"
102
+ l10n("<b>#{@labels["annex"]} #{num}</b><br/>#{obl}")
108
103
  end
109
104
 
110
105
  def single_annex_special_section(clause)
@@ -119,7 +114,7 @@ module IsoDoc::Function
119
114
  def annex_names(clause, num)
120
115
  @anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
121
116
  type: "clause",
122
- xref: "#{@annex_lbl} #{num}", level: 1 }
117
+ xref: "#{@labels["annex"]} #{num}", level: 1 }
123
118
  if a = single_annex_special_section(clause)
124
119
  annex_names1(a, "#{num}", 1)
125
120
  else
@@ -131,11 +126,26 @@ module IsoDoc::Function
131
126
  end
132
127
 
133
128
  def annex_names1(clause, num, level)
134
- @anchors[clause["id"]] = { label: num, xref: "#{@annex_lbl} #{num}",
129
+ @anchors[clause["id"]] = { label: num, xref: "#{@labels["annex"]} #{num}",
135
130
  level: level, type: "clause" }
136
131
  clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
137
132
  annex_names1(c, "#{num}.#{i + 1}", level + 1)
138
133
  end
139
134
  end
135
+
136
+ ISO_PUBLISHER_XPATH =
137
+ "./contributor[xmlns:role/@type = 'publisher']/"\
138
+ "organization[abbreviation = 'ISO' or xmlns:abbreviation = 'IEC' or "\
139
+ "xmlns:name = 'International Organization for Standardization' or "\
140
+ "xmlns:name = 'International Electrotechnical Commission']".freeze
141
+
142
+ def reference_names(ref)
143
+ isopub = ref.at(ns(ISO_PUBLISHER_XPATH))
144
+ ids = @klass.bibitem_ref_code(ref)
145
+ identifiers = @klass.render_identifier(ids)
146
+ date = ref.at(ns("./date[@type = 'published']"))
147
+ reference = @klass.docid_l10n(identifiers[0] || identifiers[1])
148
+ @anchors[ref["id"]] = { xref: reference }
149
+ end
140
150
  end
141
151
  end
@@ -15,14 +15,26 @@ module IsoDoc
15
15
 
16
16
  def initialize(options)
17
17
  @format = :pdf
18
+ @suffix = "pdf"
18
19
  super
19
20
  end
20
21
 
21
- def convert(filename, file = nil, debug = false)
22
- file = File.read(filename, encoding: "utf-8") if file.nil?
23
- docxml, outname_html, dir = convert_init(file, filename, debug)
22
+ def pdf_stylesheet(docxml)
23
+ nil
24
+ end
25
+
26
+ def convert(input_filename, file = nil, debug = false, output_filename = nil)
27
+ file = File.read(input_filename, encoding: "utf-8") if file.nil?
28
+ docxml, filename, dir = convert_init(file, input_filename, debug)
29
+ /\.xml$/.match(input_filename) or
30
+ input_filename = Tempfile.open([filename, ".xml"], encoding: "utf-8") do |f|
31
+ f.write file
32
+ f.path
33
+ end
24
34
  FileUtils.rm_rf dir
25
- ::Metanorma::Output::XslfoPdf.new.convert(filename, outname_html + ".pdf", nil)
35
+ ::Metanorma::Output::XslfoPdf.new.convert(input_filename,
36
+ output_filename || "#{filename}.#{@suffix}",
37
+ File.join(@libdir, pdf_stylesheet(docxml)))
26
38
  end
27
39
 
28
40
  def xref_parse(node, out)
@@ -1,2 +1,5 @@
1
1
  foreword: Enkonduko
2
-
2
+ clause: klaŭzo
3
+ table: Tabelo
4
+ source: SOURCE
5
+ modified: modified
Binary file
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <circle fill="#009" r="45" cx="50" cy="50"/>
3
+ <path d="M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z" fill="#FFF"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <circle fill="#009" r="45" cx="50" cy="50"/>
3
+ <path d="M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z" fill="#FFF"/>
4
+ </svg>
@@ -5,7 +5,7 @@ RSpec.describe IsoDoc do
5
5
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
6
6
  <iso-standard xmlns="http://riboseinc.com/isoxml">
7
7
  <preface><foreword>
8
- <note>
8
+ <note id="A" keep-with-next="true" keep-lines-together="true">
9
9
  <p id="_f06fd0d1-a203-4f3d-a515-0bdba0f8d83f">These results are based on a study carried out on three different types of kernel.</p>
10
10
  </note>
11
11
  </foreword></preface>
@@ -15,7 +15,7 @@ RSpec.describe IsoDoc do
15
15
  <br/>
16
16
  <div>
17
17
  <h1 class="ForewordTitle">Foreword</h1>
18
- <div id="" class="Note">
18
+ <div id="A" class="Note" style="page-break-after: avoid;page-break-inside: avoid;">
19
19
  <p><span class="note_label">NOTE</span>&#160; These results are based on a study carried out on three different types of kernel.</p>
20
20
  </div>
21
21
  </div>
@@ -30,7 +30,7 @@ RSpec.describe IsoDoc do
30
30
  expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
31
31
  <iso-standard xmlns="http://riboseinc.com/isoxml">
32
32
  <preface><foreword>
33
- <note>
33
+ <note id="A">
34
34
  <p id="_f06fd0d1-a203-4f3d-a515-0bdba0f8d83f">These results are based on a study carried out on three different types of kernel.</p>
35
35
  </note>
36
36
  </foreword></preface>
@@ -47,7 +47,7 @@ RSpec.describe IsoDoc do
47
47
  <p><br clear="all" style="mso-special-character:line-break;page-break-before:always"/></p>
48
48
  <div>
49
49
  <h1 class="ForewordTitle">Foreword</h1>
50
- <div id="" class="Note">
50
+ <div id="A" class="Note">
51
51
  <p class="Note"><span class="note_label">NOTE</span><span style="mso-tab-count:1">&#160; </span>These results are based on a study carried out on three different types of kernel.</p>
52
52
  </div>
53
53
  </div>
@@ -134,7 +134,7 @@ INPUT
134
134
  <br/>
135
135
  <div>
136
136
  <h1 class="ForewordTitle">Foreword</h1>
137
- <div id="" class="Note">
137
+ <div class="Note">
138
138
  <p><span class="note_label">NOTE</span>&#160; These results are based on a study carried out on three different types of kernel.</p>
139
139
  <p id="_f06fd0d1-a203-4f3d-a515-0bdba0f8d83a">These results are based on a study carried out on three different types of kernel.</p>
140
140
  </div>
@@ -150,7 +150,7 @@ INPUT
150
150
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
151
151
  <iso-standard xmlns="http://riboseinc.com/isoxml">
152
152
  <preface><foreword>
153
- <note>
153
+ <note id="A">
154
154
  <dl>
155
155
  <dt>A</dt>
156
156
  <dd><p>B</p></dd>
@@ -165,7 +165,7 @@ INPUT
165
165
  <br/>
166
166
  <div>
167
167
  <h1 class="ForewordTitle">Foreword</h1>
168
- <div id="" class="Note"><p><span class="note_label">NOTE</span>&#160; </p>
168
+ <div id="A" class="Note"><p><span class="note_label">NOTE</span>&#160; </p>
169
169
  <dl><dt><p>A</p></dt><dd><p>B</p></dd></dl>
170
170
  <ul>
171
171
  <li>C</li></ul>
@@ -183,7 +183,7 @@ INPUT
183
183
  expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
184
184
  <iso-standard xmlns="http://riboseinc.com/isoxml">
185
185
  <preface><foreword>
186
- <note>
186
+ <note id="A">
187
187
  <dl>
188
188
  <dt>A</dt>
189
189
  <dd><p>B</p></dd>
@@ -205,7 +205,7 @@ INPUT
205
205
  <p><br clear="all" style="mso-special-character:line-break;page-break-before:always"/></p>
206
206
  <div>
207
207
  <h1 class="ForewordTitle">Foreword</h1>
208
- <div id="" class="Note"><p class="Note"><span class="note_label">NOTE</span><span style="mso-tab-count:1">&#160; </span></p>
208
+ <div id="A" class="Note"><p class="Note"><span class="note_label">NOTE</span><span style="mso-tab-count:1">&#160; </span></p>
209
209
  <table class="dl"><tr><td valign="top" align="left"><p align="left" style="margin-left:0pt;text-align:left;">A</p></td><td valign="top"><p class="Note">B</p></td></tr></table>
210
210
  <ul>
211
211
  <li>C</li></ul>
@@ -317,7 +317,7 @@ OUTPUT
317
317
  expect(xmlpp(strip_guid(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
318
318
  <iso-standard xmlns="http://riboseinc.com/isoxml">
319
319
  <preface><foreword>
320
- <figure id="figureA-1">
320
+ <figure id="figureA-1" keep-with-next="true" keep-lines-together="true">
321
321
  <name>Split-it-right <em>sample</em> divider<fn reference="1"><p>X</p></fn></name>
322
322
  <image src="rice_images/rice_image1.png" height="20" width="30" id="_8357ede4-6d44-4672-bac4-9a85e82ab7f0" mimetype="image/png" alt="alttext" title="titletxt"/>
323
323
  <image src="rice_images/rice_image1.png" height="20" width="auto" id="_8357ede4-6d44-4672-bac4-9a85e82ab7f1" mimetype="image/png"/>
@@ -345,7 +345,7 @@ B
345
345
  <br/>
346
346
  <div>
347
347
  <h1 class="ForewordTitle">Foreword</h1>
348
- <div id="figureA-1" class="figure">
348
+ <div id="figureA-1" class="figure" style='page-break-after: avoid;page-break-inside: avoid;'>
349
349
 
350
350
  <img src="rice_images/rice_image1.png" height="20" width="30" alt="alttext" title="titletxt"/>
351
351
  <img src="rice_images/rice_image1.png" height="20" width="auto"/>
@@ -355,7 +355,7 @@ B
355
355
  </div></aside>
356
356
  <p style='page-break-after:avoid;'><b>Key</b></p><dl><dt><p>A</p></dt><dd><p>B</p></dd></dl>
357
357
  <p class="FigureTitle" style="text-align:center;">Figure 1&#160;&#8212; Split-it-right <i>sample</i> divider
358
- <a rel='footnote' href='#fn:1' epub:type='footnote'>
358
+ <a class='FootnoteRef' href='#fn:1'>
359
359
  <sup>1</sup>
360
360
  </a>
361
361
  </p></div>
@@ -380,6 +380,7 @@ B
380
380
  end
381
381
 
382
382
  it "processes figures (Word)" do
383
+ FileUtils.rm_rf "spec/assets/odf1.emf"
383
384
  expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true).sub(/['"][^'".]+\.gif['"]/, "'_.gif'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(<<~"OUTPUT")
384
385
  <iso-standard xmlns="http://riboseinc.com/isoxml">
385
386
  <preface><foreword>
@@ -426,7 +427,7 @@ B
426
427
  <p class='FigureTitle' style='text-align:center;'>
427
428
  Figure 1&#160;&#8212; Split-it-right sample divider
428
429
  <span style='mso-bookmark:_Ref'>
429
- <a href='#ftn1' epub:type='footnote'>
430
+ <a href='#ftn1' epub:type='footnote' class='FootnoteRef'>
430
431
  <sup>1</sup>
431
432
  </a>
432
433
  </span>
@@ -452,11 +453,122 @@ B
452
453
  OUTPUT
453
454
  end
454
455
 
456
+ it "converts SVG (Word)" do
457
+ FileUtils.rm_rf "spec/assets/odf1.emf"
458
+ expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(<<~"OUTPUT")
459
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
460
+ <preface><foreword>
461
+ <figure id="figureA-1">
462
+ <image src="spec/assets/odf.svg" mimetype="image/svg+xml"/>
463
+ <image src="spec/assets/odf1.svg" mimetype="image/svg+xml"/>
464
+ <image src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICA8Y2lyY2xlIGZpbGw9IiMwMDkiIHI9IjQ1IiBjeD0iNTAiIGN5PSI1MCIvPgogIDxwYXRoIGQ9Ik0zMywyNkg3OEEzNywzNywwLDAsMSwzMyw4M1Y1N0g1OVY0M0gzM1oiIGZpbGw9IiNGRkYiLz4KPC9zdmc+Cg==" id="_d3731866-1a07-435a-a6c2-1acd41023a4e" mimetype="image/svg+xml" height="auto" width="auto"/>
465
+ </figure>
466
+ </foreword></preface>
467
+ </iso-standard>
468
+ INPUT
469
+ <html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
470
+ <head>
471
+ <style>
472
+ </style>
473
+ </head>
474
+ <body lang='EN-US' link='blue' vlink='#954F72'>
475
+ <div class='WordSection1'>
476
+ <p>&#160;</p>
477
+ </div>
478
+ <p>
479
+ <br clear='all' class='section'/>
480
+ </p>
481
+ <div class='WordSection2'>
482
+ <p>
483
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
484
+ </p>
485
+ <div>
486
+ <h1 class='ForewordTitle'>Foreword</h1>
487
+ <div id='figureA-1' class='figure'>
488
+ <img src='spec/assets/odf.emf'/>
489
+ <img src='spec/assets/odf1.emf'/>
490
+ <img src='_.emf' height='auto' width='auto'/>
491
+ <p class='FigureTitle' style='text-align:center;'>Figure 1</p>
492
+ </div>
493
+ </div>
494
+ <p>&#160;</p>
495
+ </div>
496
+ <p>
497
+ <br clear='all' class='section'/>
498
+ </p>
499
+ <div class='WordSection3'>
500
+ <p class='zzSTDTitle1'/>
501
+ </div>
502
+ </body>
503
+ </html>
504
+
505
+ OUTPUT
506
+ end
507
+
508
+ context "disable inkscape" do
509
+
510
+ it "converts SVG (Word) with inkscape disabled" do
511
+ FileUtils.rm_rf "spec/assets/odf1.emf"
512
+ allow(IsoDoc::WordFunction::Body).to receive(:inkscape_installed?).and_return(nil)
513
+ allow_any_instance_of(IsoDoc::WordFunction::Body).to receive(:inkscape_installed?)
514
+
515
+ expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.svg['"]/, "'_.svg'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(<<~"OUTPUT")
516
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
517
+ <preface><foreword>
518
+ <figure id="figureA-1">
519
+ <image src="spec/assets/odf.svg" mimetype="image/svg+xml"/>
520
+ <image src="spec/assets/odf1.svg" mimetype="image/svg+xml"/>
521
+ <image src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICA8Y2lyY2xlIGZpbGw9IiMwMDkiIHI9IjQ1IiBjeD0iNTAiIGN5PSI1MCIvPgogIDxwYXRoIGQ9Ik0zMywyNkg3OEEzNywzNywwLDAsMSwzMyw4M1Y1N0g1OVY0M0gzM1oiIGZpbGw9IiNGRkYiLz4KPC9zdmc+Cg==" id="_d3731866-1a07-435a-a6c2-1acd41023a4e" mimetype="image/svg+xml" height="auto" width="auto"/>
522
+ </figure>
523
+ </foreword></preface>
524
+ </iso-standard>
525
+ INPUT
526
+ <html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
527
+ <head>
528
+ <style>
529
+ </style>
530
+ </head>
531
+ <body lang='EN-US' link='blue' vlink='#954F72'>
532
+ <div class='WordSection1'>
533
+ <p>&#160;</p>
534
+ </div>
535
+ <p>
536
+ <br clear='all' class='section'/>
537
+ </p>
538
+ <div class='WordSection2'>
539
+ <p>
540
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
541
+ </p>
542
+ <div>
543
+ <h1 class='ForewordTitle'>Foreword</h1>
544
+ <div id='figureA-1' class='figure'>
545
+ <img src='spec/assets/odf.emf'/>
546
+ <img src='spec/assets/odf1.svg'/>
547
+ <img src='_.svg' height='auto' width='auto'/>
548
+ <p class='FigureTitle' style='text-align:center;'>Figure 1</p>
549
+ </div>
550
+ </div>
551
+ <p>&#160;</p>
552
+ </div>
553
+ <p>
554
+ <br clear='all' class='section'/>
555
+ </p>
556
+ <div class='WordSection3'>
557
+ <p class='zzSTDTitle1'/>
558
+ </div>
559
+ </body>
560
+ </html>
561
+
562
+ OUTPUT
563
+ end
564
+ end
565
+
566
+
455
567
  it "processes examples" do
456
568
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
457
569
  <iso-standard xmlns="http://riboseinc.com/isoxml">
458
570
  <preface><foreword>
459
- <example id="samplecode">
571
+ <example id="samplecode" keep-with-next="true" keep-lines-together="true">
460
572
  <name>Title</name>
461
573
  <p>Hello</p>
462
574
  <sourcecode id="X">
@@ -470,7 +582,7 @@ B
470
582
  <br/>
471
583
  <div>
472
584
  <h1 class="ForewordTitle">Foreword</h1>
473
- <div id="samplecode" class="example">
585
+ <div id="samplecode" class="example" style="page-break-after: avoid;page-break-inside: avoid;">
474
586
  <p class="example-title">EXAMPLE&#160;&#8212; Title</p>
475
587
  <p>Hello</p>
476
588
  <pre id='X' class='prettyprint '>
@@ -489,6 +601,60 @@ B
489
601
  OUTPUT
490
602
  end
491
603
 
604
+ it "processes examples (Word)" do
605
+ expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
606
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
607
+ <preface><foreword>
608
+ <example id="samplecode" keep-with-next="true" keep-lines-together="true">
609
+ <name>Title</name>
610
+ <p>Hello</p>
611
+ <sourcecode id="X">
612
+ <name>Sample</name>
613
+ </sourcecode>
614
+ </example>
615
+ </foreword></preface>
616
+ </iso-standard>
617
+ INPUT
618
+ <html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'><head><style>
619
+ </style>
620
+ </head>
621
+ <body lang='EN-US' link='blue' vlink='#954F72'>
622
+ <div class='WordSection1'>
623
+ <p>&#160;</p>
624
+ </div>
625
+ <p>
626
+ <br clear='all' class='section'/>
627
+ </p>
628
+ <div class='WordSection2'>
629
+ <p>
630
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
631
+ </p>
632
+ <div>
633
+ <h1 class='ForewordTitle'>Foreword</h1>
634
+ <div id='samplecode' class='example' style='page-break-after: avoid;page-break-inside: avoid;'>
635
+ <p class='example-title'>EXAMPLE&#160;&#8212; Title</p>
636
+ <p>Hello</p>
637
+ <p id='X' class='Sourcecode'>
638
+ <br/>
639
+ &#160;
640
+ <br/>
641
+ &#160;
642
+ </p>
643
+ <p class='SourceTitle' style='text-align:center;'>Sample</p>
644
+ </div>
645
+ </div>
646
+ <p>&#160;</p>
647
+ </div>
648
+ <p>
649
+ <br clear='all' class='section'/>
650
+ </p>
651
+ <div class='WordSection3'>
652
+ <p class='zzSTDTitle1'/>
653
+ </div>
654
+ </body>
655
+ </html>
656
+ OUTPUT
657
+ end
492
658
 
493
659
  it "processes sequences of examples" do
494
660
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
@@ -671,7 +837,7 @@ Que?
671
837
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
672
838
  <iso-standard xmlns="http://riboseinc.com/isoxml">
673
839
  <preface><foreword>
674
- <admonition id="_70234f78-64e5-4dfc-8b6f-f3f037348b6a" type="caution">
840
+ <admonition id="_70234f78-64e5-4dfc-8b6f-f3f037348b6a" type="caution" keep-with-next="true" keep-lines-together="true">
675
841
  <p id="_e94663cc-2473-4ccc-9a72-983a74d989f2">Only use paddy or parboiled rice for the determination of husked rice yield.</p>
676
842
  </admonition>
677
843
  </foreword></preface>
@@ -681,7 +847,7 @@ Que?
681
847
  <br/>
682
848
  <div>
683
849
  <h1 class="ForewordTitle">Foreword</h1>
684
- <div class="Admonition"><p class="AdmonitionTitle" style="text-align:center;">CAUTION</p>
850
+ <div class="Admonition" id='_70234f78-64e5-4dfc-8b6f-f3f037348b6a' style='page-break-after: avoid;page-break-inside: avoid;'><p class="AdmonitionTitle" style="text-align:center;">CAUTION</p>
685
851
  <p id="_e94663cc-2473-4ccc-9a72-983a74d989f2">Only use paddy or parboiled rice for the determination of husked rice yield.</p>
686
852
  </div>
687
853
  </div>
@@ -707,7 +873,7 @@ Que?
707
873
  <br/>
708
874
  <div>
709
875
  <h1 class="ForewordTitle">Foreword</h1>
710
- <div class="Admonition"><p class="AdmonitionTitle" style="text-align:center;">Title</p>
876
+ <div class="Admonition" id="_70234f78-64e5-4dfc-8b6f-f3f037348b6a"><p class="AdmonitionTitle" style="text-align:center;">Title</p>
711
877
  <p id="_e94663cc-2473-4ccc-9a72-983a74d989f2">Only use paddy or parboiled rice for the determination of husked rice yield.</p>
712
878
  </div>
713
879
  </div>
@@ -723,7 +889,7 @@ Que?
723
889
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
724
890
  <iso-standard xmlns="http://riboseinc.com/isoxml">
725
891
  <preface><foreword>
726
- <formula id="_be9158af-7e93-4ee2-90c5-26d31c181934" unnumbered="true">
892
+ <formula id="_be9158af-7e93-4ee2-90c5-26d31c181934" unnumbered="true" keep-with-next="true" keep-lines-together="true">
727
893
  <stem type="AsciiMath">r = 1 %</stem>
728
894
  <dl id="_e4fe94fe-1cde-49d9-b1ad-743293b7e21d">
729
895
  <dt>
@@ -747,16 +913,16 @@ Que?
747
913
  <br/>
748
914
  <div>
749
915
  <h1 class="ForewordTitle">Foreword</h1>
750
- <div id="_be9158af-7e93-4ee2-90c5-26d31c181934" class="formula"><p><span class="stem">(#(r = 1 %)#)</span></p></div><p style='page-break-after:avoid;'>where</p><dl id="_e4fe94fe-1cde-49d9-b1ad-743293b7e21d" class="formula_dl"><dt>
916
+ <div id="_be9158af-7e93-4ee2-90c5-26d31c181934" style='page-break-after: avoid;page-break-inside: avoid;'><div class="formula"><p><span class="stem">(#(r = 1 %)#)</span></p></div><p style='page-break-after:avoid;'>where</p><dl id="_e4fe94fe-1cde-49d9-b1ad-743293b7e21d" class="formula_dl"><dt>
751
917
  <span class="stem">(#(r)#)</span>
752
918
  </dt><dd>
753
919
  <p id="_1b99995d-ff03-40f5-8f2e-ab9665a69b77">is the repeatability limit.</p>
754
920
  </dd></dl>
755
921
 
756
922
 
757
- <div id="_83083c7a-6c85-43db-a9fa-4d8edd0c9fc0" class="Note"><p><span class="note_label">NOTE</span>&#160; [durationUnits] is essentially a duration statement without the "P" prefix. "P" is unnecessary because between "G" and "U" duration is always expressed.</p></div>
923
+ <div id="_83083c7a-6c85-43db-a9fa-4d8edd0c9fc0" class="Note"><p><span class="note_label">NOTE</span>&#160; [durationUnits] is essentially a duration statement without the "P" prefix. "P" is unnecessary because between "G" and "U" duration is always expressed.</p></div></div>
758
924
 
759
- <div id="_be9158af-7e93-4ee2-90c5-26d31c181935" class="formula"><p><span class="stem">(#(r = 1 %)#)</span>&#160; (1)</p></div>
925
+ <div id="_be9158af-7e93-4ee2-90c5-26d31c181935"><div class="formula"><p><span class="stem">(#(r = 1 %)#)</span>&#160; (1)</p></div></div>
760
926
  </div>
761
927
  <p class="zzSTDTitle1"/>
762
928
  </div>
@@ -769,7 +935,7 @@ Que?
769
935
  expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
770
936
  <iso-standard xmlns="http://riboseinc.com/isoxml">
771
937
  <preface><foreword>
772
- <formula id="_be9158af-7e93-4ee2-90c5-26d31c181934" unnumbered="true">
938
+ <formula id="_be9158af-7e93-4ee2-90c5-26d31c181934" unnumbered="true" keep-with-next="true" keep-lines-together="true">
773
939
  <stem type="AsciiMath">r = 1 %</stem>
774
940
  <dl id="_e4fe94fe-1cde-49d9-b1ad-743293b7e21d">
775
941
  <dt>
@@ -807,7 +973,7 @@ Que?
807
973
  </p>
808
974
  <div>
809
975
  <h1 class='ForewordTitle'>Foreword</h1>
810
- <div id='_be9158af-7e93-4ee2-90c5-26d31c181934' class='formula'>
976
+ <div id='_be9158af-7e93-4ee2-90c5-26d31c181934' style='page-break-after: avoid;page-break-inside: avoid;'><div class='formula'>
811
977
  <p>
812
978
  <span class='stem'>(#(r = 1 %)#)</span>
813
979
  </p>
@@ -834,12 +1000,14 @@ Que?
834
1000
  always expressed.
835
1001
  </p>
836
1002
  </div>
837
- <div id='_be9158af-7e93-4ee2-90c5-26d31c181935' class='formula'>
1003
+ </div>
1004
+ <div id='_be9158af-7e93-4ee2-90c5-26d31c181935'><div class='formula'>
838
1005
  <p>
839
1006
  <span class='stem'>(#(r = 1 %)#)</span>
840
1007
  <span style='mso-tab-count:1'>&#160; </span>
841
1008
  (1)
842
1009
  </p>
1010
+ </div>
843
1011
  </div>
844
1012
  </div>
845
1013
  <p>&#160;</p>
@@ -855,14 +1023,14 @@ Que?
855
1023
  OUTPUT
856
1024
  end
857
1025
 
858
- it "processes paragraph alignments" do
1026
+ it "processes paragraph attributes" do
859
1027
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
860
1028
  <iso-standard xmlns="http://riboseinc.com/isoxml">
861
1029
  <preface><foreword>
862
1030
  <p align="left" id="_08bfe952-d57f-4150-9c95-5d52098cc2a8">Vache Equipment<br/>
863
1031
  Fictitious<br/>
864
1032
  World</p>
865
- <p align="justify">Justify</p>
1033
+ <p align="justify" keep-with-next="true" keep-lines-together="true">Justify</p>
866
1034
  </foreword></preface>
867
1035
  </iso-standard>
868
1036
  INPUT
@@ -874,7 +1042,7 @@ World

874
1042
  Fictitious<br/>
875
1043
  World
876
1044
  </p>
877
- <p style="text-align:justify;">Justify</p>
1045
+ <p style="text-align:justify;page-break-after: avoid;page-break-inside: avoid;">Justify</p>
878
1046
  </div>
879
1047
  <p class="zzSTDTitle1"/>
880
1048
  </div>
@@ -883,14 +1051,14 @@ World

883
1051
  OUTPUT
884
1052
  end
885
1053
 
886
- it "processes paragraph alignments (Word)" do
1054
+ it "processes paragraph attributes (Word)" do
887
1055
  expect(xmlpp(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
888
1056
  <iso-standard xmlns="http://riboseinc.com/isoxml">
889
1057
  <preface><foreword>
890
1058
  <p align="left" id="_08bfe952-d57f-4150-9c95-5d52098cc2a8">Vache Equipment<br/>
891
1059
  Fictitious<br/>
892
1060
  World</p>
893
- <p align="justify">Justify</p>
1061
+ <p align="justify" keep-with-next="true" keep-lines-together="true">Justify</p>
894
1062
  </foreword></preface>
895
1063
  </iso-standard>
896
1064
  INPUT
@@ -905,11 +1073,11 @@ World

905
1073
  <p><br clear="all" style="mso-special-character:line-break;page-break-before:always"/></p>
906
1074
  <div>
907
1075
  <h1 class="ForewordTitle">Foreword</h1>
908
- <p id="_08bfe952-d57f-4150-9c95-5d52098cc2a8" align="left" style="text-align:left">Vache Equipment<br/>
1076
+ <p id="_08bfe952-d57f-4150-9c95-5d52098cc2a8" align="left" style="text-align:left;">Vache Equipment<br/>
909
1077
  Fictitious<br/>
910
1078
  World
911
1079
  </p>
912
- <p style="text-align:justify">Justify</p>
1080
+ <p style="text-align:justify;page-break-after: avoid;page-break-inside: avoid;">Justify</p>
913
1081
  </div>
914
1082
  <p>&#160;</p>
915
1083
  </div>
@@ -984,7 +1152,7 @@ World

984
1152
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
985
1153
  <iso-standard xmlns="http://riboseinc.com/isoxml">
986
1154
  <preface><foreword>
987
- <permission id="_">
1155
+ <permission id="_" keep-with-next="true" keep-lines-together="true">
988
1156
  <label>/ogc/recommendation/wfs/2</label>
989
1157
  <inherit>/ss/584/2015/level/1</inherit>
990
1158
  <inherit><eref type="inline" bibitemid="rfc2616" citeas="RFC 2616">RFC 2616 (HTTP/1.1)</eref></inherit>
@@ -1042,7 +1210,8 @@ World

1042
1210
  <br/>
1043
1211
  <div>
1044
1212
  <h1 class="ForewordTitle">Foreword</h1>
1045
- <div class="permission"><p class="RecommendationTitle">Permission 1:<br/>/ogc/recommendation/wfs/2</p>
1213
+ <div class="permission" id='_' style='page-break-after: avoid;page-break-inside: avoid;'>
1214
+ <p class="RecommendationTitle">Permission 1:<br/>/ogc/recommendation/wfs/2</p>
1046
1215
  <p><i>Subject: user<br/>
1047
1216
  Inherits: /ss/584/2015/level/1
1048
1217
  <br/>
@@ -1058,7 +1227,7 @@ Inherits: RFC 2616 (HTTP/1.1)
1058
1227
  </div>
1059
1228
  <div class="requirement-measurement-target">
1060
1229
  <p id="_">The measurement target shall be measured as:</p>
1061
- <div id="_" class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div>
1230
+ <div id="_"><div class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div></div>
1062
1231
 
1063
1232
 
1064
1233
  </div>
@@ -1088,7 +1257,7 @@ Inherits: RFC 2616 (HTTP/1.1)
1088
1257
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1089
1258
  <iso-standard xmlns="http://riboseinc.com/isoxml">
1090
1259
  <preface><foreword>
1091
- <requirement id="A" unnumbered="true">
1260
+ <requirement id="A" unnumbered="true" keep-with-next="true" keep-lines-together="true">
1092
1261
  <title>A New Requirement</title>
1093
1262
  <label>/ogc/recommendation/wfs/2</label>
1094
1263
  <inherit>/ss/584/2015/level/1</inherit>
@@ -1114,7 +1283,7 @@ Inherits: RFC 2616 (HTTP/1.1)
1114
1283
  <description>
1115
1284
  <p id="_">As for the measurement targets,</p>
1116
1285
  </description>
1117
- <measurement-target exclude="false">
1286
+ <measurement-target exclude="false" keep-with-next="true" keep-lines-together="true">
1118
1287
  <p id="_">The measurement target shall be measured as:</p>
1119
1288
  <formula id="B">
1120
1289
  <stem type="AsciiMath">r/1 = 0</stem>
@@ -1139,7 +1308,8 @@ Inherits: RFC 2616 (HTTP/1.1)
1139
1308
  <br/>
1140
1309
  <div>
1141
1310
  <h1 class="ForewordTitle">Foreword</h1>
1142
- <div class="require"><p class="RecommendationTitle">Requirement:<br/>/ogc/recommendation/wfs/2. A New Requirement</p><p><i>Subject: user<br/>Inherits: /ss/584/2015/level/1</i></p>
1311
+ <div class="require" id='A' style='page-break-after: avoid;page-break-inside: avoid;'>
1312
+ <p class="RecommendationTitle">Requirement:<br/>/ogc/recommendation/wfs/2. A New Requirement</p><p><i>Subject: user<br/>Inherits: /ss/584/2015/level/1</i></p>
1143
1313
 
1144
1314
  <div class="requirement-description">
1145
1315
  <p id="_">I recommend <i>this</i>.</p>
@@ -1148,9 +1318,9 @@ Inherits: RFC 2616 (HTTP/1.1)
1148
1318
  <div class="requirement-description">
1149
1319
  <p id="_">As for the measurement targets,</p>
1150
1320
  </div>
1151
- <div class="requirement-measurement-target">
1321
+ <div class="requirement-measurement-target" style='page-break-after: avoid;page-break-inside: avoid;'>
1152
1322
  <p id="_">The measurement target shall be measured as:</p>
1153
- <div id="B" class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div>
1323
+ <div id="B"><div class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div></div>
1154
1324
 
1155
1325
 
1156
1326
  </div>
@@ -1227,7 +1397,7 @@ Inherits: RFC 2616 (HTTP/1.1)
1227
1397
  <br/>
1228
1398
  <div>
1229
1399
  <h1 class='ForewordTitle'>Avant-propos</h1>
1230
- <div class='require'>
1400
+ <div class='require' id="A">
1231
1401
  <p class='RecommendationTitle'>
1232
1402
  Exigence:
1233
1403
  <br/>
@@ -1252,11 +1422,12 @@ Inherits: RFC 2616 (HTTP/1.1)
1252
1422
  </div>
1253
1423
  <div class='requirement-measurement-target'>
1254
1424
  <p id='_'>The measurement target shall be measured as:</p>
1255
- <div id='B' class='formula'>
1425
+ <div id='B'><div class='formula'>
1256
1426
  <p>
1257
1427
  <span class='stem'>(#(r/1 = 0)#)</span>
1258
1428
  &#160; (1)
1259
1429
  </p>
1430
+ </div>
1260
1431
  </div>
1261
1432
  </div>
1262
1433
  <div class='requirement-verification'>
@@ -1287,7 +1458,7 @@ end
1287
1458
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1288
1459
  <iso-standard xmlns="http://riboseinc.com/isoxml">
1289
1460
  <preface><foreword>
1290
- <recommendation id="_" obligation="shall,could">
1461
+ <recommendation id="_" obligation="shall,could" keep-with-next="true" keep-lines-together="true">
1291
1462
  <label>/ogc/recommendation/wfs/2</label>
1292
1463
  <inherit>/ss/584/2015/level/1</inherit>
1293
1464
  <classification><tag>type</tag><value>text</value></classification>
@@ -1339,7 +1510,8 @@ end
1339
1510
  <br/>
1340
1511
  <div>
1341
1512
  <h1 class="ForewordTitle">Foreword</h1>
1342
- <div class="recommend"><p class="RecommendationTitle">Recommendation 1:<br/>/ogc/recommendation/wfs/2</p><p><i>Obligation: shall,could<br/>Subject: user<br/>Inherits: /ss/584/2015/level/1<br/>Type: text<br/>Language: BASIC</i></p>
1513
+ <div class="recommend" id='_' style='page-break-after: avoid;page-break-inside: avoid;'>
1514
+ <p class="RecommendationTitle">Recommendation 1:<br/>/ogc/recommendation/wfs/2</p><p><i>Obligation: shall,could<br/>Subject: user<br/>Inherits: /ss/584/2015/level/1<br/>Type: text<br/>Language: BASIC</i></p>
1343
1515
  <div class="requirement-description">
1344
1516
  <p id="_">I recommend <i>this</i>.</p>
1345
1517
  </div>
@@ -1349,7 +1521,7 @@ end
1349
1521
  </div>
1350
1522
  <div class="requirement-measurement-target">
1351
1523
  <p id="_">The measurement target shall be measured as:</p>
1352
- <div id="_" class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div>
1524
+ <div id="_"><div class="formula"><p><span class="stem">(#(r/1 = 0)#)</span>&#160; (1)</p></div></div>
1353
1525
 
1354
1526
 
1355
1527
  </div>
@@ -1374,7 +1546,7 @@ end
1374
1546
  <language>en</language>
1375
1547
  </bibdata>
1376
1548
  <preface><foreword>
1377
- <figure id="_" class="pseudocode"><name>Label</name><p id="_">  <strong>A</strong><br/>
1549
+ <figure id="_" class="pseudocode" keep-with-next="true" keep-lines-together="true"><name>Label</name><p id="_">  <strong>A</strong><br/>
1378
1550
          <smallcap>B</smallcap></p>
1379
1551
  <p id="_">  <em>C</em></p></figure>
1380
1552
  </preface></itu-standard>
@@ -1383,7 +1555,7 @@ INPUT
1383
1555
  <br/>
1384
1556
  <div>
1385
1557
  <h1 class="ForewordTitle">Foreword</h1>
1386
- <div id="_" class="pseudocode"><p id="_">&#160;&#160;<b>A</b><br/>
1558
+ <div id="_" class="pseudocode" style='page-break-after: avoid;page-break-inside: avoid;'><p id="_">&#160;&#160;<b>A</b><br/>
1387
1559
  &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="font-variant:small-caps;">B</span></p>
1388
1560
  <p id="_">&#160;&#160;<i>C</i></p><p class="SourceTitle" style="text-align:center;">Figure 1&#xA0;&#x2014; Label</p></div>
1389
1561
  </div>
@@ -1463,26 +1635,35 @@ INPUT
1463
1635
  end
1464
1636
 
1465
1637
  it "processes passthrough with compatible format" do
1466
- expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1638
+ FileUtils.rm_f "test.html"
1639
+ IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", false)
1467
1640
  <iso-standard xmlns="http://riboseinc.com/isoxml">
1468
1641
  <preface><foreword>
1469
- <passthrough format="html,rfc">&lt;A&gt;</passthrough>
1642
+ <passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em><passthrough format="html,rfc">&lt;/A&gt;</passthrough>
1470
1643
  </foreword></preface>
1471
1644
  </iso-standard>
1472
1645
  INPUT
1473
- #{HTML_HDR}
1474
- <br/>
1475
- <div>
1476
- <h1 class='ForewordTitle'>Foreword</h1>
1477
- <a/>
1478
- </div>
1479
- <p class='zzSTDTitle1'/>
1480
- </div>
1481
- </body>
1482
- </html>
1646
+ expect(( File.read("test.html").gsub(%r{^.*<h1 class="ForewordTitle">Foreword</h1>}m, "").gsub(%r{</div>.*}m, ""))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1647
+ <A><i>Hello</i></A>
1483
1648
  OUTPUT
1484
1649
  end
1485
1650
 
1651
+ it "aborts if passthrough results in malformed XML" do
1652
+ FileUtils.rm_f "test.html"
1653
+ FileUtils.rm_f "test.html.err"
1654
+ begin
1655
+ expect { IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", false) }.to raise_error(SystemExit)
1656
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1657
+ <preface><foreword>
1658
+ <passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em>
1659
+ </foreword></preface>
1660
+ </iso-standard>
1661
+ INPUT
1662
+ rescue SystemExit
1663
+ end
1664
+ expect(File.exist?("test.html.err")).to be true
1665
+ end
1666
+
1486
1667
  it "ignore passthrough with incompatible format" do
1487
1668
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1488
1669
  <iso-standard xmlns="http://riboseinc.com/isoxml">