isodoc 1.0.28 → 1.0.29

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