isodoc 1.0.27 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +4 -8
  3. data/.github/workflows/ubuntu.yml +18 -16
  4. data/.github/workflows/windows.yml +4 -8
  5. data/Rakefile +3 -1
  6. data/isodoc.gemspec +2 -2
  7. data/lib/isodoc.rb +2 -0
  8. data/lib/isodoc/base_style/metanorma_word.scss +0 -1
  9. data/lib/isodoc/base_style/reset.scss +3 -3
  10. data/lib/isodoc/common.rb +0 -4
  11. data/lib/isodoc/convert.rb +121 -58
  12. data/lib/isodoc/function/blocks.rb +42 -53
  13. data/lib/isodoc/function/blocks_example_note.rb +108 -0
  14. data/lib/isodoc/function/cleanup.rb +8 -4
  15. data/lib/isodoc/function/i18n.rb +1 -0
  16. data/lib/isodoc/function/inline.rb +70 -90
  17. data/lib/isodoc/function/inline_simple.rb +72 -0
  18. data/lib/isodoc/function/lists.rb +12 -6
  19. data/lib/isodoc/function/references.rb +33 -38
  20. data/lib/isodoc/function/reqt.rb +14 -5
  21. data/lib/isodoc/function/section.rb +8 -11
  22. data/lib/isodoc/function/table.rb +4 -4
  23. data/lib/isodoc/function/terms.rb +3 -3
  24. data/lib/isodoc/function/to_word_html.rb +21 -13
  25. data/lib/isodoc/function/utils.rb +57 -50
  26. data/lib/isodoc/gem_tasks.rb +104 -0
  27. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  28. data/lib/isodoc/html_convert.rb +2 -1
  29. data/lib/isodoc/html_function/footnotes.rb +1 -1
  30. data/lib/isodoc/html_function/html.rb +13 -1
  31. data/lib/isodoc/html_function/postprocess.rb +4 -4
  32. data/lib/isodoc/metadata.rb +74 -62
  33. data/lib/isodoc/pdf_convert.rb +8 -6
  34. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  35. data/lib/isodoc/sassc_importer.rb +11 -0
  36. data/lib/isodoc/version.rb +1 -1
  37. data/lib/isodoc/word_convert.rb +2 -1
  38. data/lib/isodoc/word_function/body.rb +14 -48
  39. data/lib/isodoc/word_function/footnotes.rb +1 -1
  40. data/lib/isodoc/word_function/inline.rb +75 -0
  41. data/lib/isodoc/word_function/postprocess.rb +1 -0
  42. data/lib/isodoc/word_function/table.rb +3 -3
  43. data/lib/isodoc/xref.rb +59 -0
  44. data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
  45. data/lib/isodoc/xref/xref_counter.rb +74 -0
  46. data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
  47. data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
  48. data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
  49. data/lib/isodoc/xslfo_convert.rb +16 -4
  50. data/spec/assets/{html.css → html.scss} +0 -0
  51. data/spec/assets/i18n.yaml +4 -1
  52. data/spec/assets/odf.emf +0 -0
  53. data/spec/assets/odf.svg +4 -0
  54. data/spec/assets/odf1.svg +4 -0
  55. data/spec/isodoc/blocks_spec.rb +219 -47
  56. data/spec/isodoc/cleanup_spec.rb +135 -6
  57. data/spec/isodoc/footnotes_spec.rb +22 -7
  58. data/spec/isodoc/inline_spec.rb +262 -2
  59. data/spec/isodoc/lists_spec.rb +8 -8
  60. data/spec/isodoc/metadata_spec.rb +110 -3
  61. data/spec/isodoc/postproc_spec.rb +1321 -1351
  62. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  63. data/spec/isodoc/ref_spec.rb +119 -50
  64. data/spec/isodoc/section_spec.rb +84 -18
  65. data/spec/isodoc/table_spec.rb +6 -6
  66. data/spec/isodoc/terms_spec.rb +7 -7
  67. data/spec/isodoc/xref_spec.rb +165 -45
  68. metadata +36 -27
  69. data/lib/isodoc/function/blocks_example.rb +0 -53
  70. data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -1,11 +1,9 @@
1
- require_relative "xref_counter"
2
- require_relative "xref_anchor"
3
- require_relative "xref_gen_seq"
1
+ require_relative "xref_gen_seq.rb"
4
2
 
5
- module IsoDoc::Function
6
- module XrefGen
3
+ module IsoDoc::XrefGen
4
+ module Blocks
7
5
  def termnote_label(n)
8
- @termnote_lbl.gsub(/%/, n.to_s)
6
+ @labels["termnote"].gsub(/%/, n.to_s)
9
7
  end
10
8
 
11
9
  def termnote_anchor_names(docxml)
@@ -17,7 +15,7 @@ module IsoDoc::Function
17
15
  @anchors[n["id"]] =
18
16
  { label: termnote_label(c.print), type: "termnote",
19
17
  xref: l10n("#{anchor(t['id'], :xref)}, "\
20
- "#{@note_xref_lbl} #{c.print}") }
18
+ "#{@labels["note_xref"]} #{c.print}") }
21
19
  end
22
20
  end
23
21
  end
@@ -33,7 +31,7 @@ module IsoDoc::Function
33
31
  @anchors[n["id"]] = {
34
32
  type: "termexample", label: idx,
35
33
  xref: l10n("#{anchor(t['id'], :xref)}, "\
36
- "#{@example_xref_lbl} #{c.print}") }
34
+ "#{@labels["example_xref"]} #{c.print}") }
37
35
  end
38
36
  end
39
37
  end
@@ -57,7 +55,7 @@ module IsoDoc::Function
57
55
  notes.each do |n|
58
56
  next if @anchors[n["id"]] || n["id"].nil? || n["id"].empty?
59
57
  idx = notes.size == 1 ? "" : " #{c.increment(n).print}"
60
- @anchors[n["id"]] = anchor_struct(idx, n, @note_xref_lbl,
58
+ @anchors[n["id"]] = anchor_struct(idx, n, @labels["note_xref"],
61
59
  "note", false)
62
60
  end
63
61
  note_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
@@ -79,7 +77,7 @@ module IsoDoc::Function
79
77
  next if @anchors[n["id"]]
80
78
  next if n["id"].nil? || n["id"].empty?
81
79
  idx = notes.size == 1 ? "" : " #{c.increment(n).print}"
82
- @anchors[n["id"]] = anchor_struct(idx, n, @example_xref_lbl,
80
+ @anchors[n["id"]] = anchor_struct(idx, n, @labels["example_xref"],
83
81
  "example", n["unnumbered"])
84
82
  end
85
83
  example_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
@@ -94,7 +92,7 @@ module IsoDoc::Function
94
92
  notes.each do |n|
95
93
  next if n["id"].nil? || n["id"].empty?
96
94
  idx = notes.size == 1 ? "" : " #{c.increment(n).print}"
97
- @anchors[n["id"]] = anchor_struct(idx, n, @list_lbl, "list", false)
95
+ @anchors[n["id"]] = anchor_struct(idx, n, @labels["list"], "list", false)
98
96
  list_item_anchor_names(n, @anchors[n["id"]], 1, "", notes.size != 1)
99
97
  end
100
98
  list_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
@@ -115,16 +113,5 @@ module IsoDoc::Function
115
113
  end
116
114
  end
117
115
  end
118
-
119
- # extract names for all anchors, xref and label
120
- def anchor_names(docxml)
121
- initial_anchor_names(docxml)
122
- back_anchor_names(docxml)
123
- # preempt clause notes with all other types of note (ISO default)
124
- note_anchor_names(docxml.xpath(ns("//table | //figure")))
125
- note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
126
- example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
127
- list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
128
- end
129
116
  end
130
117
  end
@@ -1,19 +1,32 @@
1
- module IsoDoc::Function
2
- module XrefGen
1
+ module IsoDoc::XrefGen
2
+ module Blocks
3
+ def hiersep
4
+ "."
5
+ end
6
+
7
+ def hierfigsep
8
+ "-"
9
+ end
10
+
11
+ def subfigure_increment(j, c, t)
12
+ if t.parent.name == "figure" then j += 1
13
+ else
14
+ j = 0
15
+ c.increment(t)
16
+ end
17
+ j
18
+ end
19
+
3
20
  def sequential_figure_names(clause)
4
21
  c = Counter.new
5
22
  j = 0
6
23
  clause.xpath(ns(".//figure | .//sourcecode[not(ancestor::example)]")).
7
24
  each do |t|
8
- if t.parent.name == "figure" then j += 1
9
- else
10
- j = 0
11
- c.increment(t)
12
- end
25
+ j = subfigure_increment(j, c, t)
13
26
  label = c.print + (j.zero? ? "" : "-#{j}")
14
27
  next if t["id"].nil? || t["id"].empty?
15
28
  @anchors[t["id"]] =
16
- anchor_struct(label, nil, @figure_lbl, "figure", t["unnumbered"])
29
+ anchor_struct(label, nil, @labels["figure"], "figure", t["unnumbered"])
17
30
  end
18
31
  end
19
32
 
@@ -22,7 +35,7 @@ module IsoDoc::Function
22
35
  clause.xpath(ns(".//table")).each do |t|
23
36
  next if t["id"].nil? || t["id"].empty?
24
37
  @anchors[t["id"]] = anchor_struct(c.increment(t).print, nil,
25
- @table_lbl, "table", t["unnumbered"])
38
+ @labels["table"], "table", t["unnumbered"])
26
39
  end
27
40
  end
28
41
 
@@ -32,7 +45,7 @@ module IsoDoc::Function
32
45
  next if t["id"].nil? || t["id"].empty?
33
46
  @anchors[t["id"]] =
34
47
  anchor_struct(c.increment(t).print, t,
35
- t["inequality"] ? @inequality_lbl : @formula_lbl,
48
+ t["inequality"] ? @labels["inequality"] : @labels["formula"],
36
49
  "formula", t["unnumbered"])
37
50
  end
38
51
  end
@@ -51,9 +64,9 @@ module IsoDoc::Function
51
64
  end
52
65
 
53
66
  def sequential_permission_names2(t, id)
54
- sequential_permission_names1(t, id, "permission", @permission_lbl)
55
- sequential_permission_names1(t, id, "requirement", @requirement_lbl)
56
- sequential_permission_names1(t, id, "recommendation", @recommendation_lbl)
67
+ sequential_permission_names1(t, id, "permission", @labels["permission"])
68
+ sequential_permission_names1(t, id, "requirement", @labels["requirement"])
69
+ sequential_permission_names1(t, id, "recommendation", @labels["recommendation"])
57
70
  end
58
71
 
59
72
  def sequential_permission_names1(block, lbl, klass, label)
@@ -70,9 +83,9 @@ module IsoDoc::Function
70
83
  sequential_table_names(clause)
71
84
  sequential_figure_names(clause)
72
85
  sequential_formula_names(clause)
73
- sequential_permission_names(clause, "permission", @permission_lbl)
74
- sequential_permission_names(clause, "requirement", @requirement_lbl)
75
- sequential_permission_names(clause, "recommendation", @recommendation_lbl)
86
+ sequential_permission_names(clause, "permission", @labels["permission"])
87
+ sequential_permission_names(clause, "requirement", @labels["requirement"])
88
+ sequential_permission_names(clause, "recommendation", @labels["recommendation"])
76
89
  end
77
90
 
78
91
  def hierarchical_figure_names(clause, num)
@@ -80,15 +93,11 @@ module IsoDoc::Function
80
93
  j = 0
81
94
  clause.xpath(ns(".//figure | .//sourcecode[not(ancestor::example)]")).
82
95
  each do |t|
83
- if t.parent.name == "figure" then j += 1
84
- else
85
- j = 0
86
- c.increment(t)
87
- end
96
+ j = subfigure_increment(j, c, t)
88
97
  label = "#{num}#{hiersep}#{c.print}" +
89
98
  (j.zero? ? "" : "#{hierfigsep}#{j}")
90
99
  next if t["id"].nil? || t["id"].empty?
91
- @anchors[t["id"]] = anchor_struct(label, nil, @figure_lbl, "figure",
100
+ @anchors[t["id"]] = anchor_struct(label, nil, @labels["figure"], "figure",
92
101
  t["unnumbered"])
93
102
  end
94
103
  end
@@ -99,7 +108,7 @@ module IsoDoc::Function
99
108
  next if t["id"].nil? || t["id"].empty?
100
109
  @anchors[t["id"]] =
101
110
  anchor_struct("#{num}#{hiersep}#{c.increment(t).print}",
102
- nil, @table_lbl, "table", t["unnumbered"])
111
+ nil, @labels["table"], "table", t["unnumbered"])
103
112
  end
104
113
  end
105
114
 
@@ -107,11 +116,11 @@ module IsoDoc::Function
107
116
  hierarchical_table_names(clause, num)
108
117
  hierarchical_figure_names(clause, num)
109
118
  hierarchical_formula_names(clause, num)
110
- hierarchical_permission_names(clause, num, "permission", @permission_lbl)
119
+ hierarchical_permission_names(clause, num, "permission", @labels["permission"])
111
120
  hierarchical_permission_names(clause, num, "requirement",
112
- @requirement_lbl)
121
+ @labels["requirement"])
113
122
  hierarchical_permission_names(clause, num, "recommendation",
114
- @recommendation_lbl)
123
+ @labels["recommendation"])
115
124
  end
116
125
 
117
126
  def hierarchical_formula_names(clause, num)
@@ -120,7 +129,7 @@ module IsoDoc::Function
120
129
  next if t["id"].nil? || t["id"].empty?
121
130
  @anchors[t["id"]] =
122
131
  anchor_struct("#{num}#{hiersep}#{c.increment(t).print}", nil,
123
- t["inequality"] ? @inequality_lbl : @formula_lbl,
132
+ t["inequality"] ? @labels["inequality"] : @labels["formula"],
124
133
  "formula", t["unnumbered"])
125
134
  end
126
135
  end
@@ -135,13 +144,13 @@ module IsoDoc::Function
135
144
  end
136
145
  end
137
146
 
138
- def hierarchical_permission_names2(t, id)
139
- hierarchical_permission_names1(t, id, "permission", @permission_lbl)
140
- hierarchical_permission_names1(t, id, "requirement", @requirement_lbl)
141
- hierarchical_permission_names1(t, id, "recommendation", @recommendation_lbl)
147
+ def hierarchical_permission_names2(t, id)
148
+ hierarchical_permission_names1(t, id, "permission", @labels["permission"])
149
+ hierarchical_permission_names1(t, id, "requirement", @labels["requirement"])
150
+ hierarchical_permission_names1(t, id, "recommendation", @labels["recommendation"])
142
151
  end
143
152
 
144
- def hierarchical_permission_names1(block, lbl, klass, label)
153
+ def hierarchical_permission_names1(block, lbl, klass, label)
145
154
  c = Counter.new
146
155
  block.xpath(ns("./#{klass}")).each do |t|
147
156
  next if t["id"].nil? || t["id"].empty?
@@ -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)
File without changes
@@ -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>