metanorma-iso 2.0.8.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/html2doc/lists.rb +169 -0
  3. data/lib/isodoc/iso/base_convert.rb +11 -1
  4. data/lib/isodoc/iso/html/html_iso_titlepage.html +7 -0
  5. data/lib/isodoc/iso/html/isodoc-dis.css +407 -427
  6. data/lib/isodoc/iso/html/isodoc-dis.scss +482 -438
  7. data/lib/isodoc/iso/html/isodoc.css +38 -13
  8. data/lib/isodoc/iso/html/isodoc.scss +38 -12
  9. data/lib/isodoc/iso/html/style-human.css +14 -1
  10. data/lib/isodoc/iso/html/style-human.scss +10 -1
  11. data/lib/isodoc/iso/html/style-iso.css +35 -23
  12. data/lib/isodoc/iso/html/style-iso.scss +31 -23
  13. data/lib/isodoc/iso/html/word_iso_intro-dis.html +3 -1
  14. data/lib/isodoc/iso/html/word_iso_titlepage-dis.html +26 -13
  15. data/lib/isodoc/iso/html/word_iso_titlepage-prf.html +58 -0
  16. data/lib/isodoc/iso/html/word_iso_titlepage.html +16 -6
  17. data/lib/isodoc/iso/html/wordstyle-dis.css +168 -48
  18. data/lib/isodoc/iso/html/wordstyle-dis.scss +158 -43
  19. data/lib/isodoc/iso/html_convert.rb +7 -2
  20. data/lib/isodoc/iso/i18n-en.yaml +33 -4
  21. data/lib/isodoc/iso/i18n-fr.yaml +30 -3
  22. data/lib/isodoc/iso/i18n-ru.yaml +33 -4
  23. data/lib/isodoc/iso/i18n-zh-Hans.yaml +33 -3
  24. data/lib/isodoc/iso/i18n.rb +1 -1
  25. data/lib/isodoc/iso/init.rb +17 -1
  26. data/lib/isodoc/iso/iso.amendment.xsl +1711 -367
  27. data/lib/isodoc/iso/iso.international-standard.xsl +1711 -367
  28. data/lib/isodoc/iso/metadata.rb +72 -78
  29. data/lib/isodoc/iso/presentation_bibdata.rb +74 -0
  30. data/lib/isodoc/iso/presentation_xml_convert.rb +52 -100
  31. data/lib/isodoc/iso/presentation_xref.rb +132 -0
  32. data/lib/isodoc/iso/sections.rb +3 -3
  33. data/lib/isodoc/iso/word_cleanup.rb +17 -0
  34. data/lib/isodoc/iso/word_convert.rb +32 -12
  35. data/lib/isodoc/iso/word_dis_cleanup.rb +235 -0
  36. data/lib/isodoc/iso/word_dis_convert.rb +122 -0
  37. data/lib/isodoc/iso/xref.rb +78 -29
  38. data/lib/metanorma/iso/base.rb +20 -1
  39. data/lib/metanorma/iso/biblio.rng +69 -42
  40. data/lib/metanorma/iso/boilerplate-fr.xml +4 -1
  41. data/lib/metanorma/iso/boilerplate-ru.xml +4 -3
  42. data/lib/metanorma/iso/boilerplate.xml +4 -3
  43. data/lib/metanorma/iso/cleanup.rb +29 -1
  44. data/lib/metanorma/iso/front.rb +31 -6
  45. data/lib/metanorma/iso/front_id.rb +2 -0
  46. data/lib/metanorma/iso/isodoc.rng +65 -0
  47. data/lib/metanorma/iso/isostandard.rng +30 -12
  48. data/lib/metanorma/iso/macros.rb +29 -0
  49. data/lib/metanorma/iso/version.rb +1 -1
  50. data/lib/metanorma-iso.rb +1 -0
  51. data/lib/relaton/render/config.yml +4 -0
  52. data/lib/relaton/render/general.rb +13 -0
  53. data/metanorma-iso.gemspec +1 -1
  54. data/spec/isodoc/amd_spec.rb +35 -60
  55. data/spec/isodoc/blocks_spec.rb +783 -179
  56. data/spec/isodoc/i18n_spec.rb +331 -100
  57. data/spec/isodoc/inline_spec.rb +35 -42
  58. data/spec/isodoc/iso_spec.rb +51 -170
  59. data/spec/isodoc/metadata_spec.rb +240 -99
  60. data/spec/isodoc/postproc_spec.rb +68 -7
  61. data/spec/isodoc/ref_spec.rb +66 -69
  62. data/spec/isodoc/section_spec.rb +88 -80
  63. data/spec/isodoc/table_spec.rb +2 -2
  64. data/spec/isodoc/terms_spec.rb +2 -2
  65. data/spec/isodoc/word_dis_spec.rb +1886 -0
  66. data/spec/isodoc/xref_spec.rb +138 -64
  67. data/spec/metanorma/amd_spec.rb +53 -1
  68. data/spec/metanorma/base_spec.rb +195 -20
  69. data/spec/metanorma/blocks_spec.rb +54 -0
  70. data/spec/metanorma/lists_spec.rb +2 -2
  71. data/spec/metanorma/section_spec.rb +2 -2
  72. data/spec/spec_helper.rb +23 -4
  73. data/spec/vcr_cassettes/withdrawn_iso.yml +25 -25
  74. metadata +15 -10
  75. data/docs/asciiiso-syntax.adoc +0 -307
  76. data/docs/guidance.adoc +0 -487
  77. data/docs/navigation.adoc +0 -23
  78. data/docs/quickstart.adoc +0 -179
  79. data/spec/vcr_cassettes/docrels.yml +0 -385
@@ -0,0 +1,1886 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+
4
+ RSpec.describe IsoDoc do
5
+ it "maps styles for DIS" do
6
+ FileUtils.rm_f "test.doc"
7
+ IsoDoc::Iso::WordConvert
8
+ .new({})
9
+ .convert("test", <<~"INPUT", false)
10
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
11
+ <bibdata>
12
+ <status><stage>30</stage></status>
13
+ </bibdata>
14
+ <sections>
15
+ <terms id="A">
16
+ <term id="B">
17
+ <preferred><expression><name>First</name></expression></preferred>
18
+ <admitted><expression><name>Second</name></expression></admitted>
19
+ </term>
20
+ </terms>
21
+ </sections>
22
+ </iso-standard>
23
+ INPUT
24
+ expect(File.exist?("test.doc")).to be true
25
+ html = File.read("test.doc", encoding: "UTF-8")
26
+ expect(html).to include 'class="AltTerms"'
27
+ expect(html).not_to include 'class="AdmittedTerm"'
28
+
29
+ FileUtils.rm_f "test.doc"
30
+ IsoDoc::Iso::WordConvert
31
+ .new({})
32
+ .convert("test", <<~"INPUT", false)
33
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
34
+ <bibdata>
35
+ <status><stage>50</stage></status>
36
+ </bibdata>
37
+ <sections>
38
+ <terms id="A">
39
+ <term id="B">
40
+ <preferred><expression><name>First</name></expression></preferred>
41
+ <admitted><expression><name>Second</name></expression></admitted>
42
+ </term>
43
+ </terms>
44
+ </sections>
45
+ </iso-standard>
46
+ INPUT
47
+ expect(File.exist?("test.doc")).to be true
48
+ html = File.read("test.doc", encoding: "UTF-8")
49
+ expect(html).not_to include 'class="AltTerms"'
50
+ expect(html).to include 'class="AdmittedTerm"'
51
+
52
+ FileUtils.rm_f "test.doc"
53
+ IsoDoc::Iso::WordConvert
54
+ .new({ isowordtemplate: "simple" })
55
+ .convert("test", <<~"INPUT", false)
56
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
57
+ <bibdata>
58
+ <status><stage>50</stage></status>
59
+ </bibdata>
60
+ <sections>
61
+ <terms id="A">
62
+ <term id="B">
63
+ <preferred><expression><name>First</name></expression></preferred>
64
+ <admitted><expression><name>Second</name></expression></admitted>
65
+ </term>
66
+ </terms>
67
+ </sections>
68
+ </iso-standard>
69
+ INPUT
70
+ expect(File.exist?("test.doc")).to be true
71
+ html = File.read("test.doc", encoding: "UTF-8")
72
+ expect(html).to include 'class="AltTerms"'
73
+ expect(html).not_to include 'class="AdmittedTerm"'
74
+
75
+ FileUtils.rm_f "test.doc"
76
+ IsoDoc::Iso::WordConvert
77
+ .new({ isowordtemplate: "dis" })
78
+ .convert("test", <<~"INPUT", false)
79
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
80
+ <bibdata>
81
+ <status><stage>30</stage></status>
82
+ </bibdata>
83
+ <sections>
84
+ <terms id="A">
85
+ <term id="B">
86
+ <preferred><expression><name>First</name></expression></preferred>
87
+ <admitted><expression><name>Second</name></expression></admitted>
88
+ </term>
89
+ </terms>
90
+ </sections>
91
+ </iso-standard>
92
+ INPUT
93
+ expect(File.exist?("test.doc")).to be true
94
+ html = File.read("test.doc", encoding: "UTF-8")
95
+ expect(html).not_to include 'class="AltTerms"'
96
+ expect(html).to include 'class="AdmittedTerm"'
97
+ end
98
+
99
+ it "deals with span" do
100
+ input = <<~INPUT
101
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
102
+ <bibdata>
103
+ <status><stage>30</stage></status>
104
+ </bibdata>
105
+ <sections>
106
+ <clause id="A"><p><span class="C"><em>H</em> I</em></span></p></clause>
107
+ </sections>
108
+ </iso-standard>
109
+ INPUT
110
+ word = <<~OUTPUT
111
+ <div class='WordSection3'>
112
+ <p class='zzSTDTitle1'/>
113
+ <div id='A'>
114
+ <h1/>
115
+ <p>
116
+ <i>H</i>
117
+ I
118
+ </p>
119
+ </div>
120
+ </div>
121
+ OUTPUT
122
+ output = IsoDoc::Iso::WordConvert.new({}).convert("test", input, true)
123
+ expect(xmlpp(Nokogiri::XML(output)
124
+ .at("//div[@class = 'WordSection3']").to_xml))
125
+ .to be_equivalent_to xmlpp(word)
126
+
127
+ input = <<~INPUT
128
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
129
+ <bibdata>
130
+ <status><stage>50</stage></status>
131
+ </bibdata>
132
+ <sections>
133
+ <clause id="A"><p><span class="C"><em>H</em> I</em></span></p></clause>
134
+ </sections>
135
+ </iso-standard>
136
+ INPUT
137
+ word = <<~OUTPUT
138
+ <div class='WordSection3'>
139
+ <p class='zzSTDTitle'/>
140
+ <div id='A'>
141
+ <h1/>
142
+ <p>
143
+ <span class='C'>
144
+ <i>H</i>
145
+ I
146
+ </span>
147
+ </p>
148
+ </div>
149
+ </div>
150
+ OUTPUT
151
+ output = IsoDoc::Iso::WordConvert.new({}).convert("test", input, true)
152
+ expect(xmlpp(Nokogiri::XML(output)
153
+ .at("//div[@class = 'WordSection3']").to_xml))
154
+ .to be_equivalent_to xmlpp(word)
155
+ end
156
+
157
+ it "deals with foreword and intro" do
158
+ input = <<~INPUT
159
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
160
+ <bibdata>
161
+ <status><stage>30</stage></status>
162
+ </bibdata>
163
+ <preface>
164
+ <foreword><title>Foreword</title><p>Para</p></foreword>
165
+ <introduction><title>Foreword</title><p>Para</p></introduction>
166
+ </preface>
167
+ </iso-standard>
168
+ INPUT
169
+ word = <<~OUTPUT
170
+ <div class='WordSection2'>
171
+ <div style='mso-element:para-border-div;border:solid windowtext 1.0pt; border-bottom-alt:solid windowtext .5pt;mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt: solid windowtext .5pt;mso-border-right-alt:solid windowtext .5pt;padding:1.0pt 4.0pt 0cm 4.0pt; margin-left:5.1pt;margin-right:5.1pt'>
172
+ <div>
173
+ <a name='boilerplate-copyright-destination' id='boilerplate-copyright-destination'/>
174
+ </div>
175
+ </div>
176
+ <p class='zzContents' style='margin-top:0cm'>
177
+ <span lang='EN-GB' xml:lang='EN-GB'>Contents</span>
178
+ </p>
179
+ <p class='MsoNormal'>
180
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
181
+ </p>
182
+ <div>
183
+ <p class='ForewordTitle'>Foreword</p>
184
+ <p class='ForewordText'>Para</p>
185
+ </div>
186
+ <p class='MsoNormal'>
187
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
188
+ </p>
189
+ <div class='Section3' id=''>
190
+ <p class='IntroTitle'>Foreword</p>
191
+ <p class='MsoNormal'>Para</p>
192
+ </div>
193
+ <p class='MsoNormal'> </p>
194
+ </div>
195
+ OUTPUT
196
+ FileUtils.rm_f "test.doc"
197
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
198
+ expect(File.exist?("test.doc")).to be true
199
+ output = File.read("test.doc", encoding: "UTF-8")
200
+ .sub(/^.*<html/m, "<html")
201
+ .sub(/<\/html>.*$/m, "</html>")
202
+ doc = Nokogiri::XML(output)
203
+ .xpath("//xmlns:p[@class = 'MsoToc1']").each(&:remove)
204
+ .at("//xmlns:div[@class = 'WordSection2']")
205
+ expect(xmlpp(doc.to_xml))
206
+ .to be_equivalent_to xmlpp(word)
207
+
208
+ input = <<~INPUT
209
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
210
+ <bibdata>
211
+ <status><stage>50</stage></status>
212
+ </bibdata>
213
+ <preface>
214
+ <foreword><title>Foreword</title><p>Para</p></foreword>
215
+ <introduction><title>Foreword</title><p>Para</p></introduction>
216
+ </preface>
217
+ </iso-standard>
218
+ INPUT
219
+ word = <<~OUTPUT
220
+ <div class='WordSection2'>
221
+ <div>
222
+ <a name='boilerplate-copyright-destination' id='boilerplate-copyright-destination'/>
223
+ </div>
224
+ <p class='zzContents'>
225
+ <span lang='EN-GB' xml:lang='EN-GB'>Contents</span>
226
+ </p>
227
+ <p class='MsoBodyText'>
228
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
229
+ </p>
230
+ <div>
231
+ <p class='ForewordTitle'>Foreword</p>
232
+ <p class='ForewordText'>Para</p>
233
+ </div>
234
+ <p class='MsoBodyText'>
235
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
236
+ </p>
237
+ <div class='Section3' id=''>
238
+ <p class='IntroTitle'>Foreword</p>
239
+ <p class='MsoBodyText'>Para</p>
240
+ </div>
241
+ <p class='MsoBodyText'> </p>
242
+ </div>
243
+ OUTPUT
244
+ FileUtils.rm_f "test.doc"
245
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
246
+ expect(File.exist?("test.doc")).to be true
247
+ output = File.read("test.doc", encoding: "UTF-8")
248
+ .sub(/^.*<html/m, "<html")
249
+ .sub(/<\/html>.*$/m, "</html>")
250
+ doc = Nokogiri::XML(output)
251
+ .xpath("//xmlns:p[@class = 'MsoToc1']").each(&:remove)
252
+ .at("//xmlns:div[@class = 'WordSection2']")
253
+ expect(xmlpp(doc.to_xml))
254
+ .to be_equivalent_to xmlpp(word)
255
+ end
256
+
257
+ it "formats references" do
258
+ input = <<~INPUT
259
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
260
+ <bibdata>
261
+ <status><stage>50</stage></status>
262
+ </bibdata>
263
+ <bibliography>
264
+ <references id="_normative_references" normative="true" obligation="informative">
265
+ <title>Normative References</title>
266
+ <p>The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.</p>
267
+ <bibitem id="ISO712" type="standard">
268
+ <formattedref>ALUFFI, Paolo, ed. (2022). <em><span class="std_class">Facets of Algebraic Geometry: A Collection in Honor of William Fulton's 80th Birthday</span></em>, 1st edition. Cambridge, UK: CUP.</formattedref>
269
+ <docidentifier type="ISO">ISO/IEC 712-3:2022</docidentifier>
270
+ </bibitem>
271
+ </references>
272
+ </bibliography>
273
+ </iso-standard>
274
+ INPUT
275
+ word = <<~OUTPUT
276
+ <div class='WordSection3'>
277
+ <p class='zzSTDTitle'/>
278
+ <div>
279
+ <h1>Normative References</h1>
280
+ <p class='MsoBodyText'>
281
+ The following documents are referred to in the text in such a way that
282
+ some or all of their content constitutes requirements of this document.
283
+ For dated references, only the edition cited applies. For undated
284
+ references, the latest edition of the referenced document (including any
285
+ amendments) applies.
286
+ </p>
287
+ <p class='RefNorm'>
288
+ <a name='ISO712' id='ISO712'/>
289
+ <span class='stdpublisher'>ISO/IEC</span> <span class='stddocNumber'>712</span>-<span class='stddocPartNumber'>3</span>:<span class='stdyear'>2022</span>, ALUFFI, Paolo, ed. (2022).
290
+ <i>
291
+ <span class='std_class'>
292
+ Facets of Algebraic Geometry: A Collection in Honor of William
293
+ Fulton's 80th Birthday
294
+ </span>
295
+ </i>
296
+ , 1st edition. Cambridge, UK: CUP.
297
+ </p>
298
+ </div>
299
+ </div>
300
+ OUTPUT
301
+ FileUtils.rm_f "test.doc"
302
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
303
+ expect(File.exist?("test.doc")).to be true
304
+ output = File.read("test.doc", encoding: "UTF-8")
305
+ .sub(/^.*<html/m, "<html")
306
+ .sub(/<\/html>.*$/m, "</html>")
307
+ doc = Nokogiri::XML(output)
308
+ .at("//xmlns:div[@class = 'WordSection3']")
309
+ expect(xmlpp(doc.to_xml))
310
+ .to be_equivalent_to xmlpp(word)
311
+ end
312
+
313
+ it "formats tt" do
314
+ input = <<~INPUT
315
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
316
+ <bibdata>
317
+ <status><stage>50</stage></status>
318
+ </bibdata>
319
+ <preface>
320
+ <foreword>
321
+ <p><tt>A <strong>B</strong> <em>C</em> <strong>D<em>E</em>F</strong> <em>G<strong>H</strong>I</em></tt></p>
322
+ <p><strong>A <tt>B</tt> <em>C<tt>D</tt>E</em></strong></p>
323
+ <p><em>A <tt>B</tt> <strong>C<tt>D</tt>E</strong></em></p>
324
+ </foreword>
325
+ </preface>
326
+ </iso-standard>
327
+ INPUT
328
+ word = <<~OUTPUT
329
+ <div class='WordSection2'>
330
+ <div>
331
+ <a name='boilerplate-copyright-destination' id='boilerplate-copyright-destination'/>
332
+ </div>
333
+ <p class='zzContents'>
334
+ <span lang='EN-GB' xml:lang='EN-GB'>Contents</span>
335
+ </p>
336
+ <p class='MsoBodyText'>
337
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
338
+ </p>
339
+ <div>
340
+ <p class='ForewordTitle'>Foreword</p>
341
+ <p class='ForewordText'>
342
+ <span class='ISOCode'>
343
+ A
344
+ <span class='ISOCodebold'>B</span>
345
+ <span class='ISOCodeitalic'>C</span>
346
+ <span class='ISOCodebold'>
347
+ D
348
+ <span class='ISOCodeitalic'>E</span>
349
+ F
350
+ </span>
351
+ <span class='ISOCodeitalic'>
352
+ G
353
+ <b>H</b>
354
+ I
355
+ </span>
356
+ </span>
357
+ </p>
358
+ <p class='ForewordText'>
359
+ <b>
360
+ A
361
+ <span class='ISOCodebold'>B</span>
362
+ <i>
363
+ C
364
+ <span class='ISOCodeitalic'>D</span>
365
+ E
366
+ </i>
367
+ </b>
368
+ </p>
369
+ <p class='ForewordText'>
370
+ <i>
371
+ A
372
+ <span class='ISOCodeitalic'>B</span>
373
+ <b>
374
+ C
375
+ <span class='ISOCodebold'>D</span>
376
+ E
377
+ </b>
378
+ </i>
379
+ </p>
380
+ </div>
381
+ <p class='MsoBodyText'> </p>
382
+ </div>
383
+ OUTPUT
384
+ FileUtils.rm_f "test.doc"
385
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
386
+ expect(File.exist?("test.doc")).to be true
387
+ output = File.read("test.doc", encoding: "UTF-8")
388
+ .sub(/^.*<html/m, "<html")
389
+ .sub(/<\/html>.*$/m, "</html>")
390
+ doc = Nokogiri::XML(output)
391
+ .xpath("//xmlns:p[@class = 'MsoToc1']").each(&:remove)
392
+ .at("//xmlns:div[@class = 'WordSection2']")
393
+ expect(xmlpp(doc.to_xml))
394
+ .to be_equivalent_to xmlpp(word)
395
+ end
396
+
397
+ it "deals with lists" do
398
+ input = <<~INPUT
399
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
400
+ <bibdata>
401
+ <status><stage>50</stage></status>
402
+ </bibdata>
403
+ <sections>
404
+ <clause id="A"><p>
405
+ <ol>
406
+ <li><p>A</p></li>
407
+ <li><p>B</p></li>
408
+ <li><ol>
409
+ <li>C</li>
410
+ <li>D</li>
411
+ <li><ol>
412
+ <li>E</li>
413
+ <li>F</li>
414
+ <li><ol>
415
+ <li>G</li>
416
+ <li>H</li>
417
+ <li><ol>
418
+ <li>I</li>
419
+ <li>J</li>
420
+ <li><ol>
421
+ <li>K</li>
422
+ <li>L</li>
423
+ <li>M</li>
424
+ </ol></li>
425
+ <li>N</li>
426
+ </ol></li>
427
+ <li>O</li>
428
+ </ol></li>
429
+ <li>P</li>
430
+ </ol></li>
431
+ <li>Q</li>
432
+ </ol></li>
433
+ <li>R</li>
434
+ </ol>
435
+ <ul>
436
+ <li><p>A</p></li>
437
+ <li><p>B</p></li>
438
+ <li><p>B1</p><ul>
439
+ <li>C</li>
440
+ <li>D</li>
441
+ <li><ul>
442
+ <li>E</li>
443
+ <li>F</li>
444
+ <li><ul>
445
+ <li>G</li>
446
+ <li>H</li>
447
+ <li><ul>
448
+ <li>I</li>
449
+ <li>J</li>
450
+ <li><ul>
451
+ <li>K</li>
452
+ <li>L</li>
453
+ <li>M</li>
454
+ </ul></li>
455
+ <li>N</li>
456
+ </ul></li>
457
+ <li>O</li>
458
+ </ul></li>
459
+ <li>P</li>
460
+ </ul></li>
461
+ <li>Q</li>
462
+ </ul></li>
463
+ <li>R</li>
464
+ </ul>
465
+ </p></clause>
466
+ </sections>
467
+ </iso-standard>
468
+ INPUT
469
+ word = <<~OUTPUT
470
+ <div class='WordSection3'>
471
+ <p class='zzSTDTitle'/>
472
+ <div>
473
+ <a name='A' id='A'/>
474
+ <h1>1</h1>
475
+ <p class='ListNumber1'>
476
+ a)
477
+ <span style='mso-tab-count:1'> </span>
478
+ A
479
+ </p>
480
+ <p class='ListNumber1'>
481
+ b)
482
+ <span style='mso-tab-count:1'> </span>
483
+ B
484
+ </p>
485
+ <p class='MsoListNumber2'>
486
+ 1)
487
+ <span style='mso-tab-count:1'> </span>
488
+ C
489
+ </p>
490
+ <p class='MsoListNumber2'>
491
+ 2)
492
+ <span style='mso-tab-count:1'> </span>
493
+ D
494
+ </p>
495
+ <p class='MsoListNumber3'>
496
+ i)
497
+ <span style='mso-tab-count:1'> </span>
498
+ E
499
+ </p>
500
+ <p class='MsoListNumber3'>
501
+ ii)
502
+ <span style='mso-tab-count:1'> </span>
503
+ F
504
+ </p>
505
+ <p class='MsoListNumber4'>
506
+ A)
507
+ <span style='mso-tab-count:1'> </span>
508
+ G
509
+ </p>
510
+ <p class='MsoListNumber4'>
511
+ B)
512
+ <span style='mso-tab-count:1'> </span>
513
+ H
514
+ </p>
515
+ <p class='MsoListNumber5'>
516
+ I)
517
+ <span style='mso-tab-count:1'> </span>
518
+ I
519
+ </p>
520
+ <p class='MsoListNumber5'>
521
+ II)
522
+ <span style='mso-tab-count:1'> </span>
523
+ J
524
+ </p>
525
+ <p class='MsoListNumber5'>
526
+ a)
527
+ <span style='mso-tab-count:1'> </span>
528
+ K
529
+ </p>
530
+ <p class='MsoListNumber5'>
531
+ b)
532
+ <span style='mso-tab-count:1'> </span>
533
+ L
534
+ </p>
535
+ <p class='MsoListNumber5'>
536
+ c)
537
+ <span style='mso-tab-count:1'> </span>
538
+ M
539
+ </p>
540
+ <p class='MsoListNumber5'>
541
+ III)
542
+ <span style='mso-tab-count:1'> </span>
543
+ N
544
+ </p>
545
+ <p class='MsoListNumber4'>
546
+ C)
547
+ <span style='mso-tab-count:1'> </span>
548
+ O
549
+ </p>
550
+ <p class='MsoListNumber3'>
551
+ iii)
552
+ <span style='mso-tab-count:1'> </span>
553
+ P
554
+ </p>
555
+ <p class='MsoListNumber2'>
556
+ 3)
557
+ <span style='mso-tab-count:1'> </span>
558
+ Q
559
+ </p>
560
+ <p class='ListNumber1'>
561
+ c)
562
+ <span style='mso-tab-count:1'> </span>
563
+ R
564
+ </p>
565
+ <p class='ListContinue1'>
566
+
567
+ <span style='mso-tab-count:1'> </span>
568
+ A
569
+ </p>
570
+ <p class='ListContinue1'>
571
+
572
+ <span style='mso-tab-count:1'> </span>
573
+ B
574
+ </p>
575
+ <p class='ListContinue1'>
576
+
577
+ <span style='mso-tab-count:1'> </span>
578
+ B1
579
+ </p>
580
+ <p class='MsoListContinue2'>
581
+
582
+ <span style='mso-tab-count:1'> </span>
583
+ C
584
+ </p>
585
+ <p class='MsoListContinue2'>
586
+
587
+ <span style='mso-tab-count:1'> </span>
588
+ D
589
+ </p>
590
+ <p class='MsoListContinue3'>
591
+
592
+ <span style='mso-tab-count:1'> </span>
593
+ E
594
+ </p>
595
+ <p class='MsoListContinue3'>
596
+
597
+ <span style='mso-tab-count:1'> </span>
598
+ F
599
+ </p>
600
+ <p class='MsoListContinue4'>
601
+
602
+ <span style='mso-tab-count:1'> </span>
603
+ G
604
+ </p>
605
+ <p class='MsoListContinue4'>
606
+
607
+ <span style='mso-tab-count:1'> </span>
608
+ H
609
+ </p>
610
+ <p class='MsoListContinue5'>
611
+
612
+ <span style='mso-tab-count:1'> </span>
613
+ I
614
+ </p>
615
+ <p class='MsoListContinue5'>
616
+
617
+ <span style='mso-tab-count:1'> </span>
618
+ J
619
+ </p>
620
+ <p class='MsoListContinue5'>
621
+
622
+ <span style='mso-tab-count:1'> </span>
623
+ K
624
+ </p>
625
+ <p class='MsoListContinue5'>
626
+
627
+ <span style='mso-tab-count:1'> </span>
628
+ L
629
+ </p>
630
+ <p class='MsoListContinue5'>
631
+
632
+ <span style='mso-tab-count:1'> </span>
633
+ M
634
+ </p>
635
+ <p class='MsoListContinue5'>
636
+
637
+ <span style='mso-tab-count:1'> </span>
638
+ N
639
+ </p>
640
+ <p class='MsoListContinue4'>
641
+
642
+ <span style='mso-tab-count:1'> </span>
643
+ O
644
+ </p>
645
+ <p class='MsoListContinue3'>
646
+
647
+ <span style='mso-tab-count:1'> </span>
648
+ P
649
+ </p>
650
+ <p class='MsoListContinue2'>
651
+
652
+ <span style='mso-tab-count:1'> </span>
653
+ Q
654
+ </p>
655
+ <p class='ListContinue1'>
656
+
657
+ <span style='mso-tab-count:1'> </span>
658
+ R
659
+ </p>
660
+ </div>
661
+ </div>
662
+ OUTPUT
663
+ FileUtils.rm_f "test.doc"
664
+ presxml = IsoDoc::Iso::PresentationXMLConvert.new({})
665
+ .convert("test", input, true)
666
+ IsoDoc::Iso::WordConvert.new({}).convert("test", presxml, false)
667
+ expect(File.exist?("test.doc")).to be true
668
+ output = File.read("test.doc", encoding: "UTF-8")
669
+ .sub(/^.*<html/m, "<html")
670
+ .sub(/<\/html>.*$/m, "</html>")
671
+ expect(xmlpp(Nokogiri::XML(output)
672
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml))
673
+ .to be_equivalent_to xmlpp(word)
674
+ end
675
+
676
+ it "deals with ordered list start" do
677
+ input = <<~INPUT
678
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
679
+ <bibdata>
680
+ <status><stage>50</stage></status>
681
+ </bibdata>
682
+ <sections>
683
+ <clause id="A"><p>
684
+ <ol start="3">
685
+ <li><p>A</p></li>
686
+ <li><p>B</p></li>
687
+ <li><ol start="3">
688
+ <li>C</li>
689
+ <li>D</li>
690
+ <li><ol start="3">
691
+ <li>E</li>
692
+ <li>F</li>
693
+ <li><ol start="3">
694
+ <li>G</li>
695
+ <li>H</li>
696
+ <li><ol start="3">
697
+ <li>I</li>
698
+ <li>J</li>
699
+ <li><ol start="3">
700
+ <li>K</li>
701
+ <li>L</li>
702
+ <li>M</li>
703
+ </ol></li>
704
+ <li>N</li>
705
+ </ol></li>
706
+ <li>O</li>
707
+ </ol></li>
708
+ <li>P</li>
709
+ </ol></li>
710
+ <li>Q</li>
711
+ </ol></li>
712
+ <li>R</li>
713
+ </ol>
714
+ </clause>
715
+ </sections>
716
+ </iso-standard>
717
+ INPUT
718
+ word = <<~OUTPUT
719
+ <div class='WordSection3'>
720
+ <p class='zzSTDTitle'/>
721
+ <div>
722
+ <a name='A' id='A'/>
723
+ <h1>1</h1>
724
+ <p class='ListNumber1'>
725
+ c)
726
+ <span style='mso-tab-count:1'> </span>
727
+ A
728
+ </p>
729
+ <p class='ListNumber1'>
730
+ d)
731
+ <span style='mso-tab-count:1'> </span>
732
+ B
733
+ </p>
734
+ <p class='MsoListNumber2'>
735
+ 3)
736
+ <span style='mso-tab-count:1'> </span>
737
+ C
738
+ </p>
739
+ <p class='MsoListNumber2'>
740
+ 4)
741
+ <span style='mso-tab-count:1'> </span>
742
+ D
743
+ </p>
744
+ <p class='MsoListNumber3'>
745
+ iii)
746
+ <span style='mso-tab-count:1'> </span>
747
+ E
748
+ </p>
749
+ <p class='MsoListNumber3'>
750
+ iv)
751
+ <span style='mso-tab-count:1'> </span>
752
+ F
753
+ </p>
754
+ <p class='MsoListNumber4'>
755
+ C)
756
+ <span style='mso-tab-count:1'> </span>
757
+ G
758
+ </p>
759
+ <p class='MsoListNumber4'>
760
+ D)
761
+ <span style='mso-tab-count:1'> </span>
762
+ H
763
+ </p>
764
+ <p class='MsoListNumber5'>
765
+ III)
766
+ <span style='mso-tab-count:1'> </span>
767
+ I
768
+ </p>
769
+ <p class='MsoListNumber5'>
770
+ IV)
771
+ <span style='mso-tab-count:1'> </span>
772
+ J
773
+ </p>
774
+ <p class='MsoListNumber5'>
775
+ c)
776
+ <span style='mso-tab-count:1'> </span>
777
+ K
778
+ </p>
779
+ <p class='MsoListNumber5'>
780
+ d)
781
+ <span style='mso-tab-count:1'> </span>
782
+ L
783
+ </p>
784
+ <p class='MsoListNumber5'>
785
+ e)
786
+ <span style='mso-tab-count:1'> </span>
787
+ M
788
+ </p>
789
+ <p class='MsoListNumber5'>
790
+ V)
791
+ <span style='mso-tab-count:1'> </span>
792
+ N
793
+ </p>
794
+ <p class='MsoListNumber4'>
795
+ E)
796
+ <span style='mso-tab-count:1'> </span>
797
+ O
798
+ </p>
799
+ <p class='MsoListNumber3'>
800
+ v)
801
+ <span style='mso-tab-count:1'> </span>
802
+ P
803
+ </p>
804
+ <p class='MsoListNumber2'>
805
+ 5)
806
+ <span style='mso-tab-count:1'> </span>
807
+ Q
808
+ </p>
809
+ <p class='ListNumber1'>
810
+ e)
811
+ <span style='mso-tab-count:1'> </span>
812
+ R
813
+ </p>
814
+ </div>
815
+ </div>
816
+ OUTPUT
817
+ FileUtils.rm_f "test.doc"
818
+ presxml = IsoDoc::Iso::PresentationXMLConvert.new({})
819
+ .convert("test", input, true)
820
+ IsoDoc::Iso::WordConvert.new({}).convert("test", presxml, false)
821
+ expect(File.exist?("test.doc")).to be true
822
+ output = File.read("test.doc", encoding: "UTF-8")
823
+ .sub(/^.*<html/m, "<html")
824
+ .sub(/<\/html>.*$/m, "</html>")
825
+ expect(xmlpp(Nokogiri::XML(output)
826
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml))
827
+ .to be_equivalent_to xmlpp(word)
828
+ end
829
+
830
+ it "deals with tables" do
831
+ input = <<~INPUT
832
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
833
+ <bibdata>
834
+ <status><stage>50</stage></status>
835
+ </bibdata>
836
+ <sections>
837
+ <clause id="A">
838
+ <table id="B">
839
+ <name>Table1</name>
840
+ <thead>
841
+ <tr>
842
+ <th>A</th><th><p>B</p></th>
843
+ </tr>
844
+ </thead>
845
+ <tbody>
846
+ <tr>
847
+ <th>C</th><td><p>D</p></td>
848
+ </tr>
849
+ </tbody>
850
+ <tfoot>
851
+ <tr>
852
+ <th>E</th><td><p>F</p></td>
853
+ </tr>
854
+ </tfoot>
855
+ </table>
856
+ </clause>
857
+ </sections>
858
+ </iso-standard>
859
+ INPUT
860
+ word = <<~WORD
861
+ <div class='WordSection3'>
862
+ <p class='zzSTDTitle'/>
863
+ <div>
864
+ <a name='A' id='A'/>
865
+ <h1/>
866
+ <p class='Tabletitle' style='text-align:center;'>Table1</p>
867
+ <div align='center' class='table_container'>
868
+ <table class='MsoISOTable' style='mso-table-anchor-horizontal:column;mso-table-overlap:never;border-spacing:0;border-width:1px;'>
869
+ <a name='B' id='B'/>
870
+ <thead>
871
+ <tr>
872
+ <th style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' align='center' valign='middle'>
873
+ <div class='Tableheader'>A</div>
874
+ </th>
875
+ <th style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;' align='center' valign='middle'>
876
+ <p class='Tableheader' style='text-align: center'>B</p>
877
+ </th>
878
+ </tr>
879
+ </thead>
880
+ <tbody>
881
+ <tr>
882
+ <th style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
883
+ <div class='Tablebody'>C</div>
884
+ </th>
885
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
886
+ <p class='Tablebody'>D</p>
887
+ </td>
888
+ </tr>
889
+ </tbody>
890
+ <tfoot>
891
+ <tr>
892
+ <th style='font-weight:bold;border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
893
+ <div class='Tablebody'>E</div>
894
+ </th>
895
+ <td style='border-top:solid windowtext 1.5pt;mso-border-top-alt:solid windowtext 1.5pt;border-bottom:solid windowtext 1.5pt;mso-border-bottom-alt:solid windowtext 1.5pt;'>
896
+ <p class='Tablebody'>F</p>
897
+ </td>
898
+ </tr>
899
+ </tfoot>
900
+ </table>
901
+ </div>
902
+ </div>
903
+ </div>
904
+ WORD
905
+ FileUtils.rm_f "test.doc"
906
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
907
+ expect(File.exist?("test.doc")).to be true
908
+ output = File.read("test.doc", encoding: "UTF-8")
909
+ .sub(/^.*<html/m, "<html")
910
+ .sub(/<\/html>.*$/m, "</html>")
911
+ expect(xmlpp(Nokogiri::XML(output)
912
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml))
913
+ .to be_equivalent_to xmlpp(word)
914
+ end
915
+
916
+ it "deals with figures" do
917
+ input = <<~INPUT
918
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
919
+ <bibdata>
920
+ <status><stage>50</stage></status>
921
+ </bibdata>
922
+ <sections>
923
+ <clause id="A">
924
+ <figure id="B">
925
+ <name>Table1</name>
926
+ <image src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" height="20" width="auto"/>
927
+ <note id="C"><name>FIGURENOTE</name><p>Note</p></note>
928
+ <example id="D"><p>Example</p></example>
929
+ </figure>
930
+ </clause>
931
+ </sections>
932
+ </iso-standard>
933
+ INPUT
934
+ word = <<~WORD
935
+ <div class='WordSection3'>
936
+ <p class='zzSTDTitle'/>
937
+ <div>
938
+ <a name='A' id='A'/>
939
+ <h1/>
940
+ <div class='figure'>
941
+ <a name='B' id='B'/>
942
+ <p class='FigureGraphic'>
943
+ <img src='_.gif' height='20' width='20'/>
944
+ </p>
945
+ <div class='Figurenote'>
946
+ <a name='C' id='C'/>
947
+ <p class='Figurenote'>
948
+ FIGURENOTE
949
+ <span style='mso-tab-count:1'>  </span>
950
+ Note
951
+ </p>
952
+ </div>
953
+ <div style='page-break-after:avoid;'>
954
+ <a name='D' id='D'/>
955
+ <p class='Example'>
956
+ <span style='mso-tab-count:1'>  </span>
957
+ Example
958
+ </p>
959
+ </div>
960
+ <p class='Figuretitle' style='text-align:center;'>Table1</p>
961
+ </div>
962
+ </div>
963
+ </div>
964
+ WORD
965
+ FileUtils.rm_f "test.doc"
966
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
967
+ expect(File.exist?("test.doc")).to be true
968
+ output = File.read("test.doc", encoding: "UTF-8")
969
+ .sub(/^.*<html/m, "<html")
970
+ .sub(/<\/html>.*$/m, "</html>")
971
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
972
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
973
+ .to be_equivalent_to xmlpp(word)
974
+ end
975
+
976
+ it "deals with examples" do
977
+ input = <<~INPUT
978
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
979
+ <bibdata>
980
+ <status><stage>50</stage></status>
981
+ </bibdata>
982
+ <sections>
983
+ <clause id="A">
984
+ <example id="B">
985
+ <name>EXAMPLE</name>
986
+ <p>First example</p>
987
+ </example>
988
+ <example id="C">
989
+ <p>Second example</p>
990
+ <sourcecode>Code</sourcecode>
991
+ <p>Continuation</p>
992
+ </example>
993
+ </clause>
994
+ </sections>
995
+ </iso-standard>
996
+ INPUT
997
+ word = <<~WORD
998
+ <div class='WordSection3'>
999
+ <p class='zzSTDTitle'/>
1000
+ <div>
1001
+ <a name='A' id='A'/>
1002
+ <h1/>
1003
+ <div>
1004
+ <a name='B' id='B'/>
1005
+ <p class='Example'>
1006
+ EXAMPLE
1007
+ <span style='mso-tab-count:1'>  </span>
1008
+ First example
1009
+ </p>
1010
+ </div>
1011
+ <div>
1012
+ <a name='C' id='C'/>
1013
+ <p class='Example'>
1014
+ <span style='mso-tab-count:1'>  </span>
1015
+ Second example
1016
+ </p>
1017
+ <p class='Code-' style='margin-bottom:12pt;'>Code</p>
1018
+ <p class='Examplecontinued'>Continuation</p>
1019
+ </div>
1020
+ </div>
1021
+ </div>
1022
+ WORD
1023
+ FileUtils.rm_f "test.doc"
1024
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1025
+ expect(File.exist?("test.doc")).to be true
1026
+ output = File.read("test.doc", encoding: "UTF-8")
1027
+ .sub(/^.*<html/m, "<html")
1028
+ .sub(/<\/html>.*$/m, "</html>")
1029
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1030
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1031
+ .to be_equivalent_to xmlpp(word)
1032
+ end
1033
+
1034
+ it "deals with notes" do
1035
+ input = <<~INPUT
1036
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1037
+ <bibdata>
1038
+ <status><stage>50</stage></status>
1039
+ </bibdata>
1040
+ <sections>
1041
+ <clause id="A">
1042
+ <note id="B">
1043
+ <name>NOTE</name>
1044
+ <p>First example</p>
1045
+ </note>
1046
+ <note id="C">
1047
+ <p>Second example</p>
1048
+ <sourcecode>Code</sourcecode>
1049
+ <p>Continuation</p>
1050
+ </note>
1051
+ </clause>
1052
+ </sections>
1053
+ </iso-standard>
1054
+ INPUT
1055
+ word = <<~WORD
1056
+ <div class='WordSection3'>
1057
+ <p class='zzSTDTitle'/>
1058
+ <div>
1059
+ <a name='A' id='A'/>
1060
+ <h1/>
1061
+ <div>
1062
+ <a name='B' id='B'/>
1063
+ <p class='Note'>
1064
+ NOTE
1065
+ <span style='mso-tab-count:1'>  </span>
1066
+ First example
1067
+ </p>
1068
+ </div>
1069
+ <div>
1070
+ <a name='C' id='C'/>
1071
+ <p class='Note'>
1072
+ <span style='mso-tab-count:1'>  </span>
1073
+ Second example
1074
+ </p>
1075
+ <p class='Code-'>Code</p>
1076
+ <p class='Notecontinued'>Continuation</p>
1077
+ </div>
1078
+ </div>
1079
+ </div>
1080
+ WORD
1081
+ FileUtils.rm_f "test.doc"
1082
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1083
+ expect(File.exist?("test.doc")).to be true
1084
+ output = File.read("test.doc", encoding: "UTF-8")
1085
+ .sub(/^.*<html/m, "<html")
1086
+ .sub(/<\/html>.*$/m, "</html>")
1087
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1088
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1089
+ .to be_equivalent_to xmlpp(word)
1090
+ end
1091
+
1092
+ it "deals with unordered lists embedded within notes and examples" do
1093
+ input = <<~INPUT
1094
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1095
+ <bibdata>
1096
+ <status><stage>50</stage></status>
1097
+ </bibdata>
1098
+ <sections>
1099
+ <clause id="A">
1100
+ <note id="B">
1101
+ <ul>
1102
+ <li><p>A</p></li>
1103
+ <li><p>B</p></li>
1104
+ <li><ul>
1105
+ <li>C</li>
1106
+ <li>D</li>
1107
+ <li><ul>
1108
+ <li>E</li>
1109
+ <li>F</li>
1110
+ <li><ul>
1111
+ <li>G</li>
1112
+ <li>H</li>
1113
+ <li><ul>
1114
+ <li>I</li>
1115
+ <li>J</li>
1116
+ <li><ul>
1117
+ <li>K</li>
1118
+ <li>L</li>
1119
+ <li>M</li>
1120
+ </ul></li>
1121
+ <li>N</li>
1122
+ </ul></li>
1123
+ <li>O</li>
1124
+ </ul></li>
1125
+ <li>P</li>
1126
+ </ul></li>
1127
+ <li>Q</li>
1128
+ </ul></li>
1129
+ <li>R</li>
1130
+ </ul>
1131
+ </note>
1132
+ </clause>
1133
+ </sections>
1134
+ </iso-standard>
1135
+ INPUT
1136
+ word = <<~WORD
1137
+ <div class='WordSection3'>
1138
+ <p class='zzSTDTitle'/>
1139
+ <div>
1140
+ <a name='A' id='A'/>
1141
+ <h1>1</h1>
1142
+ <div>
1143
+ <a name='B' id='B'/>
1144
+ <p class='Note'>
1145
+ NOTE
1146
+ <span style='mso-tab-count:1'>  </span>
1147
+ </p>
1148
+ <p class='ListContinue2-'>
1149
+
1150
+ <span style='mso-tab-count:1'> </span>
1151
+ A
1152
+ </p>
1153
+ <p class='ListContinue2-'>
1154
+
1155
+ <span style='mso-tab-count:1'> </span>
1156
+ B
1157
+ </p>
1158
+ <p class='ListContinue3-'>
1159
+
1160
+ <span style='mso-tab-count:1'> </span>
1161
+ C
1162
+ </p>
1163
+ <p class='ListContinue3-'>
1164
+
1165
+ <span style='mso-tab-count:1'> </span>
1166
+ D
1167
+ </p>
1168
+ <p class='ListContinue4-'>
1169
+
1170
+ <span style='mso-tab-count:1'> </span>
1171
+ E
1172
+ </p>
1173
+ <p class='ListContinue4-'>
1174
+
1175
+ <span style='mso-tab-count:1'> </span>
1176
+ F
1177
+ </p>
1178
+ <p class='ListContinue5-'>
1179
+
1180
+ <span style='mso-tab-count:1'> </span>
1181
+ G
1182
+ </p>
1183
+ <p class='ListContinue5-'>
1184
+
1185
+ <span style='mso-tab-count:1'> </span>
1186
+ H
1187
+ </p>
1188
+ <p class='ListContinue5-'>
1189
+
1190
+ <span style='mso-tab-count:1'> </span>
1191
+ I
1192
+ </p>
1193
+ <p class='ListContinue5-'>
1194
+
1195
+ <span style='mso-tab-count:1'> </span>
1196
+ J
1197
+ </p>
1198
+ <p class='ListContinue5-'>
1199
+
1200
+ <span style='mso-tab-count:1'> </span>
1201
+ K
1202
+ </p>
1203
+ <p class='ListContinue5-'>
1204
+
1205
+ <span style='mso-tab-count:1'> </span>
1206
+ L
1207
+ </p>
1208
+ <p class='ListContinue5-'>
1209
+
1210
+ <span style='mso-tab-count:1'> </span>
1211
+ M
1212
+ </p>
1213
+ <p class='ListContinue5-'>
1214
+
1215
+ <span style='mso-tab-count:1'> </span>
1216
+ N
1217
+ </p>
1218
+ <p class='ListContinue5-'>
1219
+
1220
+ <span style='mso-tab-count:1'> </span>
1221
+ O
1222
+ </p>
1223
+ <p class='ListContinue4-'>
1224
+
1225
+ <span style='mso-tab-count:1'> </span>
1226
+ P
1227
+ </p>
1228
+ <p class='ListContinue3-'>
1229
+
1230
+ <span style='mso-tab-count:1'> </span>
1231
+ Q
1232
+ </p>
1233
+ <p class='ListContinue2-'>
1234
+
1235
+ <span style='mso-tab-count:1'> </span>
1236
+ R
1237
+ </p>
1238
+ </div>
1239
+ </div>
1240
+ </div>
1241
+ WORD
1242
+ FileUtils.rm_f "test.doc"
1243
+ presxml = IsoDoc::Iso::PresentationXMLConvert.new({})
1244
+ .convert("test", input, true)
1245
+ IsoDoc::Iso::WordConvert.new({}).convert("test", presxml, false)
1246
+ expect(File.exist?("test.doc")).to be true
1247
+ output = File.read("test.doc", encoding: "UTF-8")
1248
+ .sub(/^.*<html/m, "<html")
1249
+ .sub(/<\/html>.*$/m, "</html>")
1250
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1251
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1252
+ .to be_equivalent_to xmlpp(word)
1253
+ end
1254
+
1255
+ it "deals with ordered lists embedded within notes and examples" do
1256
+ input = <<~INPUT
1257
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1258
+ <bibdata>
1259
+ <status><stage>50</stage></status>
1260
+ </bibdata>
1261
+ <sections>
1262
+ <clause id="A">
1263
+ <example id="B">
1264
+ <ol>
1265
+ <li><p>A</p></li>
1266
+ <li><p>B</p></li>
1267
+ <li><ol>
1268
+ <li>C</li>
1269
+ <li>D</li>
1270
+ <li><ol>
1271
+ <li>E</li>
1272
+ <li>F</li>
1273
+ <li><ol>
1274
+ <li>G</li>
1275
+ <li>H</li>
1276
+ <li><ol>
1277
+ <li>I</li>
1278
+ <li>J</li>
1279
+ <li><ol>
1280
+ <li>K</li>
1281
+ <li>L</li>
1282
+ <li>M</li>
1283
+ </ol></li>
1284
+ <li>N</li>
1285
+ </ol></li>
1286
+ <li>O</li>
1287
+ </ol></li>
1288
+ <li>P</li>
1289
+ </ol></li>
1290
+ <li>Q</li>
1291
+ </ol></li>
1292
+ <li>R</li>
1293
+ </ol>
1294
+ </example>
1295
+ </clause>
1296
+ </sections>
1297
+ </iso-standard>
1298
+ INPUT
1299
+ word = <<~WORD
1300
+ <div class='WordSection3'>
1301
+ <p class='zzSTDTitle'/>
1302
+ <div>
1303
+ <a name='A' id='A'/>
1304
+ <h1>1</h1>
1305
+ <div>
1306
+ <a name='B' id='B'/>
1307
+ <p class='Example'>
1308
+ EXAMPLE
1309
+ <span style='mso-tab-count:1'>  </span>
1310
+ </p>
1311
+ <p class='ListNumber2-'>
1312
+ a)
1313
+ <span style='mso-tab-count:1'> </span>
1314
+ A
1315
+ </p>
1316
+ <p class='ListNumber2-'>
1317
+ b)
1318
+ <span style='mso-tab-count:1'> </span>
1319
+ B
1320
+ </p>
1321
+ <p class='ListNumber3-'>
1322
+ 1)
1323
+ <span style='mso-tab-count:1'> </span>
1324
+ C
1325
+ </p>
1326
+ <p class='ListNumber3-'>
1327
+ 2)
1328
+ <span style='mso-tab-count:1'> </span>
1329
+ D
1330
+ </p>
1331
+ <p class='ListNumber4-'>
1332
+ i)
1333
+ <span style='mso-tab-count:1'> </span>
1334
+ E
1335
+ </p>
1336
+ <p class='ListNumber4-'>
1337
+ ii)
1338
+ <span style='mso-tab-count:1'> </span>
1339
+ F
1340
+ </p>
1341
+ <p class='ListNumber5-'>
1342
+ A)
1343
+ <span style='mso-tab-count:1'> </span>
1344
+ G
1345
+ </p>
1346
+ <p class='ListNumber5-'>
1347
+ B)
1348
+ <span style='mso-tab-count:1'> </span>
1349
+ H
1350
+ </p>
1351
+ <p class='ListNumber5-'>
1352
+ I)
1353
+ <span style='mso-tab-count:1'> </span>
1354
+ I
1355
+ </p>
1356
+ <p class='ListNumber5-'>
1357
+ II)
1358
+ <span style='mso-tab-count:1'> </span>
1359
+ J
1360
+ </p>
1361
+ <p class='ListNumber5-'>
1362
+ a)
1363
+ <span style='mso-tab-count:1'> </span>
1364
+ K
1365
+ </p>
1366
+ <p class='ListNumber5-'>
1367
+ b)
1368
+ <span style='mso-tab-count:1'> </span>
1369
+ L
1370
+ </p>
1371
+ <p class='ListNumber5-'>
1372
+ c)
1373
+ <span style='mso-tab-count:1'> </span>
1374
+ M
1375
+ </p>
1376
+ <p class='ListNumber5-'>
1377
+ III)
1378
+ <span style='mso-tab-count:1'> </span>
1379
+ N
1380
+ </p>
1381
+ <p class='ListNumber5-'>
1382
+ C)
1383
+ <span style='mso-tab-count:1'> </span>
1384
+ O
1385
+ </p>
1386
+ <p class='ListNumber4-'>
1387
+ iii)
1388
+ <span style='mso-tab-count:1'> </span>
1389
+ P
1390
+ </p>
1391
+ <p class='ListNumber3-'>
1392
+ 3)
1393
+ <span style='mso-tab-count:1'> </span>
1394
+ Q
1395
+ </p>
1396
+ <p class='ListNumber2-'>
1397
+ c)
1398
+ <span style='mso-tab-count:1'> </span>
1399
+ R
1400
+ </p>
1401
+ </div>
1402
+ </div>
1403
+ </div>
1404
+ WORD
1405
+ FileUtils.rm_f "test.doc"
1406
+ presxml = IsoDoc::Iso::PresentationXMLConvert.new({})
1407
+ .convert("test", input, true)
1408
+ IsoDoc::Iso::WordConvert.new({}).convert("test", presxml, false)
1409
+ expect(File.exist?("test.doc")).to be true
1410
+ output = File.read("test.doc", encoding: "UTF-8")
1411
+ .sub(/^.*<html/m, "<html")
1412
+ .sub(/<\/html>.*$/m, "</html>")
1413
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1414
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1415
+ .to be_equivalent_to xmlpp(word)
1416
+ end
1417
+
1418
+ it "ignores intervening ul in numbering ol" do
1419
+ input = <<~INPUT
1420
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1421
+ <bibdata>
1422
+ <status><stage>50</stage></status>
1423
+ </bibdata>
1424
+ <sections>
1425
+ <clause id="A">
1426
+ <ul>
1427
+ <li>A</li>
1428
+ <li>
1429
+ <ol>
1430
+ <li>List</li>
1431
+ <li>
1432
+ <ul>
1433
+ <li>B</li>
1434
+ <li>
1435
+ <ol>
1436
+ <li>List 2</li>
1437
+ </ol>
1438
+ </li>
1439
+ </ul>
1440
+ </li>
1441
+ </ol>
1442
+ </li>
1443
+ </ul>
1444
+ </clause></sections>
1445
+ </iso-standard>
1446
+ INPUT
1447
+ word = <<~WORD
1448
+ <div class='WordSection3'>
1449
+ <p class='zzSTDTitle'/>
1450
+ <div>
1451
+ <a name='A' id='A'/>
1452
+ <h1>1</h1>
1453
+ <p class='ListContinue1'>
1454
+
1455
+ <span style='mso-tab-count:1'> </span>
1456
+ A
1457
+ </p>
1458
+ <p class='MsoListNumber2'>
1459
+ a)
1460
+ <span style='mso-tab-count:1'> </span>
1461
+ List
1462
+ </p>
1463
+ <p class='MsoListContinue3'>
1464
+
1465
+ <span style='mso-tab-count:1'> </span>
1466
+ B
1467
+ </p>
1468
+ <p class='MsoListNumber4'>
1469
+ 1)
1470
+ <span style='mso-tab-count:1'> </span>
1471
+ List 2
1472
+ </p>
1473
+ </div>
1474
+ </div>
1475
+ WORD
1476
+ FileUtils.rm_f "test.doc"
1477
+ presxml = IsoDoc::Iso::PresentationXMLConvert.new({})
1478
+ .convert("test", input, true)
1479
+ IsoDoc::Iso::WordConvert.new({}).convert("test", presxml, false)
1480
+ expect(File.exist?("test.doc")).to be true
1481
+ output = File.read("test.doc", encoding: "UTF-8")
1482
+ .sub(/^.*<html/m, "<html")
1483
+ .sub(/<\/html>.*$/m, "</html>")
1484
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1485
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1486
+ .to be_equivalent_to xmlpp(word)
1487
+ end
1488
+
1489
+ it "deals with definition lists embedded within notes and examples" do
1490
+ input = <<~INPUT
1491
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1492
+ <bibdata>
1493
+ <status><stage>50</stage></status>
1494
+ </bibdata>
1495
+ <sections>
1496
+ <clause id="A">
1497
+ <example id="B">
1498
+ <name>EXAMPLE</name>
1499
+ <dl>
1500
+ <dt>A</dt><dd>B</dd>
1501
+ </dl>
1502
+ </example>
1503
+ </clause>
1504
+ </sections>
1505
+ </iso-standard>
1506
+ INPUT
1507
+ word = <<~WORD
1508
+ <div class='WordSection3'>
1509
+ <p class='zzSTDTitle'/>
1510
+ <div>
1511
+ <a name='A' id='A'/>
1512
+ <h1/>
1513
+ <div>
1514
+ <a name='B' id='B'/>
1515
+ <p class='Example'>
1516
+ EXAMPLE
1517
+ <span style='mso-tab-count:1'>  </span>
1518
+ </p>
1519
+ <table class='dl' style='margin-left: 1cm;'>
1520
+ <tr>
1521
+ <td valign='top' align='left'>
1522
+ <p align='left' style='margin-left:0pt;text-align:left;' class='Tablebody'>A</p>
1523
+ </td>
1524
+ <td valign='top'>
1525
+ <div class='Tablebody'>B</div>
1526
+ </td>
1527
+ </tr>
1528
+ </table>
1529
+ </div>
1530
+ </div>
1531
+ </div>
1532
+ WORD
1533
+ FileUtils.rm_f "test.doc"
1534
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1535
+ expect(File.exist?("test.doc")).to be true
1536
+ output = File.read("test.doc", encoding: "UTF-8")
1537
+ .sub(/^.*<html/m, "<html")
1538
+ .sub(/<\/html>.*$/m, "</html>")
1539
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1540
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1541
+ .to be_equivalent_to xmlpp(word)
1542
+ end
1543
+
1544
+ it "deals with annexes" do
1545
+ input = <<~INPUT
1546
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1547
+ <bibdata>
1548
+ <status><stage>50</stage></status>
1549
+ </bibdata>
1550
+ <annex id="A"><title>Annex</title>
1551
+ <clause id="B"><title>Subannex</title>
1552
+ <clause id="C"><title>Subsubannex</title>
1553
+ </clause>
1554
+ </clause>
1555
+ </annex>
1556
+ </iso-standard>
1557
+ INPUT
1558
+ word = <<~WORD
1559
+ <div class='WordSection3'>
1560
+ <p class='zzSTDTitle'/>
1561
+ <p class='MsoBodyText'>
1562
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
1563
+ </p>
1564
+ <div class='Section3'>
1565
+ <a name='A' id='A'/>
1566
+ <p class='ANNEX'>Annex</p>
1567
+ <div>
1568
+ <a name='B' id='B'/>
1569
+ <p class='a2'>Subannex</p>
1570
+ <div>
1571
+ <a name='C' id='C'/>
1572
+ <p class='a3'>Subsubannex</p>
1573
+ </div>
1574
+ </div>
1575
+ </div>
1576
+ </div>
1577
+ WORD
1578
+ FileUtils.rm_f "test.doc"
1579
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1580
+ expect(File.exist?("test.doc")).to be true
1581
+ output = File.read("test.doc", encoding: "UTF-8")
1582
+ .sub(/^.*<html/m, "<html")
1583
+ .sub(/<\/html>.*$/m, "</html>")
1584
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1585
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1586
+ .to be_equivalent_to xmlpp(word)
1587
+ end
1588
+
1589
+ it "deals with blockquotes" do
1590
+ input = <<~INPUT
1591
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1592
+ <bibdata>
1593
+ <status><stage>50</stage></status>
1594
+ </bibdata>
1595
+ <sections>
1596
+ <clause id="A">
1597
+ <quote>
1598
+ <p>Normal clause</p>
1599
+ <note><p>Note clause</p></note>
1600
+ <example>
1601
+ <p>Example start</p>
1602
+ <sourcecode>X</sourcecode>
1603
+ <p>Example continued</p>
1604
+ </example>
1605
+ <sourcecode>X</sourcecode>
1606
+ </quote>
1607
+ </clause>
1608
+ </sections>
1609
+ </iso-standard>
1610
+ INPUT
1611
+ word = <<~WORD
1612
+ <div class='WordSection3'>
1613
+ <p class='zzSTDTitle'/>
1614
+ <div>
1615
+ <a name='A' id='A'/>
1616
+ <h1/>
1617
+ <div>
1618
+ <p class='BodyTextindent1'>Normal clause</p>
1619
+ <div>
1620
+ <p class='Noteindent'>
1621
+ <span style='mso-tab-count:1'>  </span>
1622
+ Note clause
1623
+ </p>
1624
+ </div>
1625
+ <div id=''>
1626
+ <p class='Exampleindent'>
1627
+ <span style='mso-tab-count:1'>  </span>
1628
+ Example start
1629
+ </p>
1630
+ <p class='Code--'>X</p>
1631
+ <p class='Exampleindentcontinued'>Example continued</p>
1632
+ </div>
1633
+ <p class='Code-'>X</p>
1634
+ </div>
1635
+ </div>
1636
+ </div>
1637
+ WORD
1638
+ FileUtils.rm_f "test.doc"
1639
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1640
+ expect(File.exist?("test.doc")).to be true
1641
+ output = File.read("test.doc", encoding: "UTF-8")
1642
+ .sub(/^.*<html/m, "<html")
1643
+ .sub(/<\/html>.*$/m, "</html>")
1644
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1645
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1646
+ .to be_equivalent_to xmlpp(word)
1647
+ end
1648
+
1649
+ it "deals with title" do
1650
+ input = <<~INPUT
1651
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1652
+ <bibdata>
1653
+ <title language="en" format="text/plain" type="title-intro">Date and time</title>
1654
+ <title language="en" format="text/plain" type="title-main">Representations for information interchange</title>
1655
+ <title language="en" format="text/plain" type="title-part">Basic rules</title>
1656
+ <status><stage>50</stage></status>
1657
+ <ext><doctype>international-standard</doctype>
1658
+ <structuredidentifier><project-number part="1" origyr="2022-03-10">8601</project-number></structuredidentifier>
1659
+ </ext>
1660
+ </bibdata>
1661
+ <sections>
1662
+ <clause id="A"><title>First clause</title>
1663
+ </clause>
1664
+ </sections>
1665
+ </iso-standard>
1666
+ INPUT
1667
+ word = <<~WORD
1668
+ <div class='WordSection3'>
1669
+ <p class='zzSTDTitle'>
1670
+ Date and time — Representations for information interchange —
1671
+ <span style='font-weight:normal'>Part 1</span>
1672
+ Basic rules
1673
+ </p>
1674
+ <div>
1675
+ <a name='A' id='A'/>
1676
+ <h1>First clause</h1>
1677
+ </div>
1678
+ </div>
1679
+ WORD
1680
+ title = <<~WORD
1681
+ <div class='WordSection1'>
1682
+ <p class='zzCover' style='font-weight:normal;'>
1683
+ <span lang='EN-GB' xml:lang='EN-GB'>Reference number of project: </span>
1684
+ </p>
1685
+ <p class='zzCover' style='font-weight:normal;'>
1686
+ <span lang='EN-GB' xml:lang='EN-GB'>Committee identification: /</span>
1687
+ </p>
1688
+ <p class='zzCover'>
1689
+ <span lang='EN-GB' xml:lang='EN-GB'>
1690
+ <b>
1691
+ Date and time — Representations for information interchange
1692
+ — Part 1: Basic rules
1693
+ </b>
1694
+ </span>
1695
+ </p>
1696
+ <p class='zzCover' style='font-weight:normal;'>
1697
+ <i/>
1698
+ </p>
1699
+ </div>
1700
+ WORD
1701
+ FileUtils.rm_f "test.doc"
1702
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1703
+ expect(File.exist?("test.doc")).to be true
1704
+ output = File.read("test.doc", encoding: "UTF-8")
1705
+ .sub(/^.*<html/m, "<html")
1706
+ .sub(/<\/html>.*$/m, "</html>")
1707
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1708
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1709
+ .to be_equivalent_to xmlpp(word)
1710
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1711
+ .at("//xmlns:div[@class = 'WordSection1']").to_xml)))
1712
+ .to be_equivalent_to xmlpp(title)
1713
+ end
1714
+
1715
+ it "deals with amendments" do
1716
+ input = <<~INPUT
1717
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1718
+ <bibdata>
1719
+ <title language="en" format="text/plain" type="title-intro">Date and time</title>
1720
+ <title language="en" format="text/plain" type="title-main">Representations for information interchange</title>
1721
+ <title language="en" format="text/plain" type="title-part">Basic rules</title>
1722
+ <title language="en" format="text/plain" type="title-amd">Technical corrections</title>
1723
+ <status><stage>50</stage></status>
1724
+ <ext><doctype>amendment</doctype>
1725
+ <structuredidentifier><project-number part="1" amendment="1" origyr="2022-03-10">8601</project-number>
1726
+ </structuredidentifier>
1727
+ </ext>
1728
+ </bibdata>
1729
+ <preface>
1730
+ <foreword id="F"><title>Foreword</title></foreword>
1731
+ </preface>
1732
+ <sections>
1733
+ <clause id="A"><title>First clause</title>
1734
+ </clause>
1735
+ </sections>
1736
+ </iso-standard>
1737
+ INPUT
1738
+ word = <<~WORD
1739
+ <div class='WordSection3'>
1740
+ <p class='zzSTDTitle'>
1741
+ Date and time — Representations for information interchange —
1742
+ <span style='font-weight:normal'>Part 1</span>
1743
+ Basic rules
1744
+ <span style='font-weight:normal'> AMENDMENT 1: Technical corrections</span>
1745
+ </p>
1746
+ <div>
1747
+ <a name='A' id='A'/>
1748
+ <p style='font-style:italic;page-break-after:avoid;' class='MsoBodyText'>First clause</p>
1749
+ </div>
1750
+ </div>
1751
+ WORD
1752
+ FileUtils.rm_f "test.doc"
1753
+ IsoDoc::Iso::WordConvert.new({}).convert("test", input, false)
1754
+ expect(File.exist?("test.doc")).to be true
1755
+ output = File.read("test.doc", encoding: "UTF-8")
1756
+ .sub(/^.*<html/m, "<html")
1757
+ .sub(/<\/html>.*$/m, "</html>")
1758
+ expect(strip_guid(xmlpp(Nokogiri::XML(output)
1759
+ .at("//xmlns:div[@class = 'WordSection3']").to_xml)))
1760
+ .to be_equivalent_to xmlpp(word)
1761
+ end
1762
+
1763
+ it "deals with copyright boilerplate" do
1764
+ presxml = <<~OUTPUT
1765
+ <iso-standard type="presentation" xmlns="http://riboseinc.com/isoxml">
1766
+ <bibdata type="standard">
1767
+ <status>
1768
+ <stage language="">50</stage>
1769
+ </status>
1770
+ </bibdata>
1771
+ <boilerplate>
1772
+ <copyright-statement>
1773
+ <clause><title>COPYRIGHT PROTECTED DOCUMENT</title>
1774
+ <p id="boilerplate-year">© ISO 2019, Published in Switzerland
1775
+ </p>
1776
+ <p id="boilerplate-message">I am the Walrus.
1777
+ </p>
1778
+ <p id="boilerplate-name">ISO copyright office</p>
1779
+ <p align="left" id="boilerplate-address">ISO copyright office
1780
+ <br/>
1781
+ Ch. de Blandonnet 8 ?~@? CP 401
1782
+ <br/>
1783
+ CH-1214 Vernier, Geneva, Switzerland
1784
+ <br/>
1785
+ Tel. + 41 22 749 01 11
1786
+ <br/>
1787
+ Fax + 41 22 749 09 47
1788
+ <br/>
1789
+ copyright@iso.org
1790
+ <br/>
1791
+ www.iso.org</p>
1792
+ </clause>
1793
+ </copyright-statement>
1794
+ <license-statement>
1795
+ <clause>
1796
+ <title depth="1">Warning for Stuff</title>
1797
+ <p>This document is not an ISO International Standard. It is distributed for review and
1798
+ comment. It is subject to change without notice and may not be referred to as
1799
+ an International Standard.</p>
1800
+ <p>Recipients
1801
+ of this draft are invited to submit, with their comments, notification of any
1802
+ relevant patent rights of which they are aware and to provide supporting
1803
+ documentation.</p>
1804
+ </clause>
1805
+ </license-statement>
1806
+ </boilerplate>
1807
+ </iso-standard>
1808
+ OUTPUT
1809
+
1810
+ FileUtils.rm_f "test.doc"
1811
+ IsoDoc::Iso::WordConvert.new(wordstylesheet: "spec/assets/word.css")
1812
+ .convert("test", presxml, false)
1813
+ word = File.read("test.doc", encoding: "UTF-8")
1814
+ expect(xmlpp(word
1815
+ .sub(%r{^.*<div class="boilerplate-copyright">}m,
1816
+ '<div class="boilerplate-copyright">')
1817
+ .sub(%r{</div>.*$}m, "</div></div>")))
1818
+ .to be_equivalent_to xmlpp(<<~"OUTPUT")
1819
+ <div class='boilerplate-copyright'>
1820
+ <div>
1821
+ <p class='zzCopyright'>
1822
+ <a name='boilerplate-year' id='boilerplate-year'/>
1823
+ © ISO 2019, Published in Switzerland
1824
+ </p>
1825
+ <p class='zzCopyright'>
1826
+ <a name='boilerplate-message' id='boilerplate-message'/>
1827
+ I am the Walrus.
1828
+ </p>
1829
+ <p class='zzCopyright'>
1830
+ <a name='boilerplate-name' id='boilerplate-name'/>
1831
+ ISO copyright office
1832
+ </p>
1833
+ <p style='text-align:left;' align='left' class='zzCopyright'>
1834
+ <a name='boilerplate-address' id='boilerplate-address'/>
1835
+ ISO copyright office
1836
+ </p>
1837
+ <p class='zzCopyright'> Ch. de Blandonnet 8 ?~@? CP 401 </p>
1838
+ <p class='zzCopyright'> CH-1214 Vernier, Geneva, Switzerland </p>
1839
+ <p class='zzCopyright'> Tel. + 41 22 749 01 11 </p>
1840
+ <p class='zzCopyright'> Fax + 41 22 749 09 47 </p>
1841
+ <p class='zzCopyright'> copyright@iso.org </p>
1842
+ <p class='zzCopyright'> www.iso.org</p>
1843
+ </div>
1844
+ </div>
1845
+ OUTPUT
1846
+
1847
+ FileUtils.rm_f "test.doc"
1848
+ IsoDoc::Iso::WordConvert.new(wordstylesheet: "spec/assets/word.css")
1849
+ .convert("test",
1850
+ presxml.sub(%r{<stage language="">50</stage>},
1851
+ "<stage>60</stage><substage>00</substage>"), false)
1852
+ word = File.read("test.doc", encoding: "UTF-8")
1853
+ expect(xmlpp(word
1854
+ .sub(%r{^.*<div class="boilerplate-copyright">}m,
1855
+ '<div class="boilerplate-copyright">')
1856
+ .sub(%r{</div>.*$}m, "</div></div>")))
1857
+ .to be_equivalent_to xmlpp(<<~"OUTPUT")
1858
+ <div class='boilerplate-copyright'>
1859
+ <div>
1860
+ <p class='zzCopyright'>
1861
+ <a name='boilerplate-year' id='boilerplate-year'/>
1862
+ © ISO 2019, Published in Switzerland
1863
+ </p>
1864
+ <p class='zzCopyright'>
1865
+ <a name='boilerplate-message' id='boilerplate-message'/>
1866
+ I am the Walrus.
1867
+ </p>
1868
+ <p class='zzCopyright'>
1869
+ <a name='boilerplate-name' id='boilerplate-name'/>
1870
+ ISO copyright office
1871
+ </p>
1872
+ <p style='text-indent:20.15pt;' align='left' class='zzCopyright'>
1873
+ <a name='boilerplate-address' id='boilerplate-address'/>
1874
+ ISO copyright office
1875
+ </p>
1876
+ <p class='zzCopyright' style='text-indent:20.15pt;'> Ch. de Blandonnet 8 ?~@? CP 401 </p>
1877
+ <p class='zzCopyright' style='text-indent:20.15pt;'> CH-1214 Vernier, Geneva, Switzerland </p>
1878
+ <p class='zzCopyright' style='text-indent:20.15pt;'> Tel. + 41 22 749 01 11 </p>
1879
+ <p class='zzCopyright' style='text-indent:20.15pt;'> Fax + 41 22 749 09 47 </p>
1880
+ <p class='zzCopyright' style='text-indent:20.15pt;'> copyright@iso.org </p>
1881
+ <p class='zzCopyright' style='text-indent:20.15pt;'> www.iso.org</p>
1882
+ </div>
1883
+ </div>
1884
+ OUTPUT
1885
+ end
1886
+ end