isodoc 1.0.28 → 1.0.29

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.
@@ -44,12 +44,12 @@ module IsoDoc::Function
44
44
  end
45
45
  end
46
46
 
47
- def make_table_attr(node)
47
+ def table_attrs(node)
48
48
  width = node["width"] ? "width:#{node['width']};" : nil
49
49
  attr_code(
50
50
  id: node["id"],
51
51
  class: "MsoISOTable",
52
- style: "border-width:1px;border-spacing:0;#{width}",
52
+ style: "border-width:1px;border-spacing:0;#{width}#{keep_style(node)}",
53
53
  title: node["alt"]
54
54
  )
55
55
  end
@@ -66,7 +66,7 @@ module IsoDoc::Function
66
66
  def table_parse(node, out)
67
67
  @in_table = true
68
68
  table_title_parse(node, out)
69
- out.table **make_table_attr(node) do |t|
69
+ out.table **table_attrs(node) do |t|
70
70
  tcaption(node, t)
71
71
  thead_parse(node, t)
72
72
  tbody_parse(node, t)
@@ -40,7 +40,7 @@ module IsoDoc::Function
40
40
  end
41
41
 
42
42
  def termnote_parse(node, out)
43
- out.div **{ class: "Note" } do |div|
43
+ out.div **note_attrs(node) do |div|
44
44
  first = node.first_element_child
45
45
  div.p do |p|
46
46
  p << "#{anchor(node['id'], :label) || '???'}: "
@@ -147,7 +147,7 @@ module IsoDoc::Function
147
147
  end
148
148
 
149
149
  def populate_template(docxml, _format = nil)
150
- meta = @meta.get.merge(@labels || {})
150
+ meta = @meta.get.merge(@labels || {}).merge(@meta.labels || {})
151
151
  template = liquid(docxml)
152
152
  template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h).
153
153
  gsub('&lt;', '&#x3c;').gsub('&gt;', '&#x3e;').gsub('&amp;', '&#x26;')
@@ -155,6 +155,7 @@ module IsoDoc::Function
155
155
 
156
156
  def save_dataimage(uri, relative_dir = true)
157
157
  %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
158
+ imgtype.sub!(/\+[a-z0-9]+$/, "") # svg+xml
158
159
  imgtype = "png" unless /^[a-z0-9]+$/.match imgtype
159
160
  Tempfile.open(["image", ".#{imgtype}"]) do |f|
160
161
  f.binmode
@@ -15,26 +15,60 @@ module IsoDoc::Function
15
15
  @num = 0
16
16
  @letter = ""
17
17
  @subseq = ""
18
+ @letter_override = nil
19
+ @number_override = nil
20
+ end
21
+
22
+ def new_subseq_increment(node)
23
+ @subseq = node["subsequence"]
24
+ @num += 1
25
+ @letter = node["subsequence"] ? "a" : ""
26
+ if node["number"]
27
+ /^(?<n>\d*)(?<a>[a-z]*)$/ =~ node["number"]
28
+ if n || a
29
+ @letter_override = @letter = a if a
30
+ @number_override = @num = n.to_i if n
31
+ else
32
+ @letter_override = node["number"]
33
+ @letter = @letter_override if /^[a-z]$/.match(@letter_override)
34
+ end
35
+ end
36
+ end
37
+
38
+ def sequence_increment(node)
39
+ if node["number"]
40
+ @number_override = node["number"]
41
+ @num = @number_override.to_i if /^\d+$/.match(@number_override)
42
+ else
43
+ @num += 1
44
+ end
45
+ end
46
+
47
+ def subsequence_increment(node)
48
+ if node["number"]
49
+ @letter_override = node["number"]
50
+ @letter = @letter_override if /^[a-z]$/.match(@letter_override)
51
+ else
52
+ @letter = (@letter.ord + 1).chr.to_s
53
+ end
18
54
  end
19
55
 
20
56
  def increment(node)
21
57
  return self if node["unnumbered"]
58
+ @letter_override = nil
59
+ @number_override = nil
22
60
  if node["subsequence"] != @subseq
23
- @subseq = node["subsequence"]
24
- @num += 1
25
- @letter = node["subsequence"] ? "a" : ""
61
+ new_subseq_increment(node)
62
+ elsif @letter.empty?
63
+ sequence_increment(node)
26
64
  else
27
- if @letter.empty?
28
- @num += 1
29
- else
30
- @letter = (@letter.ord + 1).chr.to_s
31
- end
65
+ subsequence_increment(node)
32
66
  end
33
67
  self
34
68
  end
35
69
 
36
70
  def print
37
- "#{@num}#{@letter}"
71
+ "#{@number_override || @num}#{@letter_override || @letter}"
38
72
  end
39
73
 
40
74
  def listlabel(depth)
@@ -1,15 +1,20 @@
1
1
  module IsoDoc::Function
2
2
  module XrefGen
3
+ def subfigure_increment(j, c, t)
4
+ if t.parent.name == "figure" then j += 1
5
+ else
6
+ j = 0
7
+ c.increment(t)
8
+ end
9
+ j
10
+ end
11
+
3
12
  def sequential_figure_names(clause)
4
13
  c = Counter.new
5
14
  j = 0
6
15
  clause.xpath(ns(".//figure | .//sourcecode[not(ancestor::example)]")).
7
16
  each do |t|
8
- if t.parent.name == "figure" then j += 1
9
- else
10
- j = 0
11
- c.increment(t)
12
- end
17
+ j = subfigure_increment(j, c, t)
13
18
  label = c.print + (j.zero? ? "" : "-#{j}")
14
19
  next if t["id"].nil? || t["id"].empty?
15
20
  @anchors[t["id"]] =
@@ -80,11 +85,7 @@ module IsoDoc::Function
80
85
  j = 0
81
86
  clause.xpath(ns(".//figure | .//sourcecode[not(ancestor::example)]")).
82
87
  each do |t|
83
- if t.parent.name == "figure" then j += 1
84
- else
85
- j = 0
86
- c.increment(t)
87
- end
88
+ j = subfigure_increment(j, c, t)
88
89
  label = "#{num}#{hiersep}#{c.print}" +
89
90
  (j.zero? ? "" : "#{hierfigsep}#{j}")
90
91
  next if t["id"].nil? || t["id"].empty?
@@ -102,7 +102,7 @@ module IsoDoc::HtmlFunction
102
102
  def sourcecode_parse(node, out)
103
103
  name = node.at(ns("./name"))
104
104
  class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
105
- out.pre **attr_code(id: node["id"], class: class1) do |div|
105
+ out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
106
106
  @sourcecode = true
107
107
  node.children.each { |n| parse(n, div) unless n.name == "name" }
108
108
  @sourcecode = false
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.0.28".freeze
2
+ VERSION = "1.0.29".freeze
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require_relative "./table.rb"
2
+ require_relative "./inline.rb"
2
3
 
3
4
  module IsoDoc::WordFunction
4
5
  module Body
@@ -69,28 +70,6 @@ module IsoDoc::WordFunction
69
70
  node.xpath(ns("./note")).each { |n| parse(n, out) }
70
71
  end
71
72
 
72
- def section_break(body)
73
- body.p do |p|
74
- p.br **{ clear: "all", class: "section" }
75
- end
76
- end
77
-
78
- def page_break(out)
79
- out.p do |p|
80
- p.br **{ clear: "all",
81
- style: "mso-special-character:line-break;"\
82
- "page-break-before:always" }
83
- end
84
- end
85
-
86
- def pagebreak_parse(node, out)
87
- return page_break(out) if node["orientation"].nil?
88
- out.p do |p|
89
- p.br **{clear: "all", class: "section",
90
- orientation: node["orientation"] }
91
- end
92
- end
93
-
94
73
  WORD_DT_ATTRS = {class: @note ? "Note" : nil, align: "left",
95
74
  style: "margin-left:0pt;text-align:left;"}.freeze
96
75
 
@@ -174,7 +153,7 @@ module IsoDoc::WordFunction
174
153
  end
175
154
 
176
155
  def termnote_parse(node, out)
177
- out.div **{ class: "Note" } do |div|
156
+ out.div **note_attrs(node) do |div|
178
157
  first = node.first_element_child
179
158
  div.p **{ class: "Note" } do |p|
180
159
  anchor = get_anchors[node['id']]
@@ -185,41 +164,23 @@ module IsoDoc::WordFunction
185
164
  end
186
165
 
187
166
  def para_attrs(node)
188
- attrs = { class: para_class(node), id: node["id"] }
167
+ attrs = { class: para_class(node), id: node["id"], style: "" }
189
168
  unless node["align"].nil?
190
169
  attrs[:align] = node["align"] unless node["align"] == "justify"
191
- attrs[:style] = "text-align:#{node['align']}"
170
+ attrs[:style] += "text-align:#{node['align']};"
192
171
  end
172
+ attrs[:style] += "#{keep_style(node)}"
173
+ attrs[:style] = nil if attrs[:style].empty?
193
174
  attrs
194
175
  end
195
176
 
196
- def imgsrc(uri)
197
- return uri unless %r{^data:image/}.match uri
198
- save_dataimage(uri)
199
- end
200
-
201
- def image_parse(node, out, caption)
202
- attrs = { src: imgsrc(node["src"]),
203
- height: node["height"],
204
- alt: node["alt"],
205
- title: node["title"],
206
- width: node["width"] }
207
- out.img **attr_code(attrs)
208
- image_title_parse(out, caption)
209
- end
210
-
211
- def xref_parse(node, out)
212
- target = /#/.match(node["target"]) ? node["target"].sub(/#/, ".doc#") :
213
- "##{node["target"]}"
214
- out.a(**{ "href": target }) { |l| l << get_linkend(node) }
215
- end
216
-
217
177
  def example_table_attr(node)
218
178
  super.merge({
219
179
  style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
220
180
  "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
221
181
  "mso-table-anchor-horizontal:column;"\
222
- "mso-table-overlap:never;border-collapse:collapse;"
182
+ "mso-table-overlap:never;border-collapse:collapse;"\
183
+ "#{keep_style(node)}"
223
184
  })
224
185
  end
225
186
 
@@ -240,5 +201,10 @@ module IsoDoc::WordFunction
240
201
  node.children.each { |n| parse(n, li) }
241
202
  end
242
203
  end
204
+
205
+ def suffix_url(url)
206
+ return url if %r{^http[s]?://}.match(url)
207
+ url.sub(/#{File.extname(url)}$/, ".doc")
208
+ end
243
209
  end
244
210
  end
@@ -0,0 +1,75 @@
1
+ module IsoDoc::WordFunction
2
+ module Body
3
+ def section_break(body)
4
+ body.p do |p|
5
+ p.br **{ clear: "all", class: "section" }
6
+ end
7
+ end
8
+
9
+ def page_break(out)
10
+ out.p do |p|
11
+ p.br **{ clear: "all",
12
+ style: "mso-special-character:line-break;"\
13
+ "page-break-before:always" }
14
+ end
15
+ end
16
+
17
+ def pagebreak_parse(node, out)
18
+ return page_break(out) if node["orientation"].nil?
19
+ out.p do |p|
20
+ p.br **{clear: "all", class: "section",
21
+ orientation: node["orientation"] }
22
+ end
23
+ end
24
+
25
+ def imgsrc(node)
26
+ ret = svg_to_emf(node) and return ret
27
+ return node["src"] unless %r{^data:image/}.match node["src"]
28
+ save_dataimage(node["src"])
29
+ end
30
+
31
+ def image_parse(node, out, caption)
32
+ attrs = { src: imgsrc(node),
33
+ height: node["height"],
34
+ alt: node["alt"],
35
+ title: node["title"],
36
+ width: node["width"] }
37
+ out.img **attr_code(attrs)
38
+ image_title_parse(out, caption)
39
+ end
40
+
41
+ def svg_to_emf_filename(uri)
42
+ File.join(File.dirname(uri), File.basename(uri, ".*")) + ".emf"
43
+ end
44
+
45
+ def svg_to_emf(node)
46
+ return unless node["mimetype"] == "image/svg+xml"
47
+ uri = node["src"]
48
+ %r{^data:image/}.match(uri) and uri = save_dataimage(uri)
49
+ ret = svg_to_emf_filename(uri)
50
+ File.exists?(ret) and return ret
51
+ exe = inkscape_installed? or return nil
52
+ system %(#{exe} --export-type="emf" #{uri}) and
53
+ return ret
54
+ nil
55
+ end
56
+
57
+ def inkscape_installed?
58
+ cmd = "inkscape"
59
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
60
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
61
+ exts.each do |ext|
62
+ exe = File.join(path, "#{cmd}#{ext}")
63
+ return exe if File.executable?(exe) && !File.directory?(exe)
64
+ end
65
+ end
66
+ nil
67
+ end
68
+
69
+ def xref_parse(node, out)
70
+ target = /#/.match(node["target"]) ? node["target"].sub(/#/, ".doc#") :
71
+ "##{node["target"]}"
72
+ out.a(**{ "href": target }) { |l| l << get_linkend(node) }
73
+ end
74
+ end
75
+ end
@@ -33,12 +33,12 @@ module IsoDoc::WordFunction
33
33
  align: td["align"], style: style.gsub(/\n/, "") }
34
34
  end
35
35
 
36
- def make_table_attr(node)
36
+ def table_attrs(node)
37
37
  super.merge(attr_code({
38
38
  summary: node["summary"],
39
39
  width: node["width"],
40
40
  style: "mso-table-anchor-horizontal:column;"\
41
- "mso-table-overlap:never;border-spacing:0;border-width:1px;"
41
+ "mso-table-overlap:never;border-spacing:0;border-width:1px;#{keep_style(node)}"
42
42
  }))
43
43
  end
44
44
 
@@ -46,7 +46,7 @@ module IsoDoc::WordFunction
46
46
  @in_table = true
47
47
  table_title_parse(node, out)
48
48
  out.div **{ align: "center", class: "table_container" } do |div|
49
- div.table **make_table_attr(node) do |t|
49
+ div.table **table_attrs(node) do |t|
50
50
  thead_parse(node, t)
51
51
  tbody_parse(node, t)
52
52
  tfoot_parse(node, t)
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"/>
@@ -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>
@@ -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" id='_70234f78-64e5-4dfc-8b6f-f3f037348b6a'><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>
@@ -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>