rd2odt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. data/FUTURE +63 -0
  2. data/LICENSE +21 -0
  3. data/NEWS +42 -0
  4. data/README +78 -0
  5. data/Rakefile +51 -0
  6. data/bin/rd2odt +4 -0
  7. data/doc/sample/body-text.rd +5 -0
  8. data/doc/sample/enum-list-over-headline-multi-level.rd +10 -0
  9. data/doc/sample/enum-list-over-headline.rd +9 -0
  10. data/doc/sample/enum-list-over-item-list-multi-level-2.rd +9 -0
  11. data/doc/sample/enum-list-over-item-list-multi-level.rd +8 -0
  12. data/doc/sample/enum-list-over-item-list.rd +7 -0
  13. data/doc/sample/headline.rd +60 -0
  14. data/doc/sample/include-file-figure.odt +0 -0
  15. data/doc/sample/include-file-ole-object.odt +0 -0
  16. data/doc/sample/include-file-original-styled-text.odt +0 -0
  17. data/doc/sample/include-file-shape.odt +0 -0
  18. data/doc/sample/include-file-simple-styled-text.odt +0 -0
  19. data/doc/sample/include-file-simple-text.odt +0 -0
  20. data/doc/sample/include-file-table.odt +0 -0
  21. data/doc/sample/include.rd +21 -0
  22. data/doc/sample/list.rd +22 -0
  23. data/doc/sample/multi-paragraph.rd +12 -0
  24. data/doc/sample/page-break.odt +0 -0
  25. data/doc/sample/verbatim.rd +8 -0
  26. data/doc/sample.rd.ja +75 -0
  27. data/doc/sample.rd.ja.ott +0 -0
  28. data/doc/sample.rd.ja.pdf +0 -0
  29. data/doc/specification.ja.rd +35 -0
  30. data/lib/rd2odt/rdtool/NOTICE.rd2odt +8 -0
  31. data/lib/rd2odt/rdtool/README.rd +50 -0
  32. data/lib/rd2odt/rdtool/README.rd.ja +53 -0
  33. data/lib/rd2odt/rdtool/rd/block-element.rb +114 -0
  34. data/lib/rd2odt/rdtool/rd/complex-list-item.rb +65 -0
  35. data/lib/rd2odt/rdtool/rd/desclist.rb +55 -0
  36. data/lib/rd2odt/rdtool/rd/document-struct.rb +46 -0
  37. data/lib/rd2odt/rdtool/rd/element.rb +160 -0
  38. data/lib/rd2odt/rdtool/rd/filter.rb +255 -0
  39. data/lib/rd2odt/rdtool/rd/inline-element.rb +233 -0
  40. data/lib/rd2odt/rdtool/rd/labeled-element.rb +14 -0
  41. data/lib/rd2odt/rdtool/rd/list.rb +57 -0
  42. data/lib/rd2odt/rdtool/rd/loose-struct.rb +11 -0
  43. data/lib/rd2odt/rdtool/rd/methodlist.rb +57 -0
  44. data/lib/rd2odt/rdtool/rd/output-format-visitor.rb +28 -0
  45. data/lib/rd2odt/rdtool/rd/package.rb +4 -0
  46. data/lib/rd2odt/rdtool/rd/parser-util.rb +14 -0
  47. data/lib/rd2odt/rdtool/rd/rbl-file.rb +69 -0
  48. data/lib/rd2odt/rdtool/rd/rbl-suite.rb +37 -0
  49. data/lib/rd2odt/rdtool/rd/rd-struct.rb +86 -0
  50. data/lib/rd2odt/rdtool/rd/rd2html-lib.rb +490 -0
  51. data/lib/rd2odt/rdtool/rd/rd2html-opt.rb +67 -0
  52. data/lib/rd2odt/rdtool/rd/rd2man-lib.rb +241 -0
  53. data/lib/rd2odt/rdtool/rd/rd2rdo-lib.rb +19 -0
  54. data/lib/rd2odt/rdtool/rd/rd2rmi-lib.rb +32 -0
  55. data/lib/rd2odt/rdtool/rd/rdblockparser.tab.rb +1050 -0
  56. data/lib/rd2odt/rdtool/rd/rdfmt.rb +15 -0
  57. data/lib/rd2odt/rdtool/rd/rdinlineparser.tab.rb +1243 -0
  58. data/lib/rd2odt/rdtool/rd/rdvisitor.rb +214 -0
  59. data/lib/rd2odt/rdtool/rd/reference-resolver.rb +114 -0
  60. data/lib/rd2odt/rdtool/rd/search-file.rb +14 -0
  61. data/lib/rd2odt/rdtool/rd/tree.rb +103 -0
  62. data/lib/rd2odt/rdtool/rd/version.rb +39 -0
  63. data/lib/rd2odt/rdtool/rd/visitor.rb +86 -0
  64. data/lib/rd2odt.rb +603 -0
  65. data/rd2odt.gemspec +108 -0
  66. data/setup.rb +1585 -0
  67. data/test/functional/rd2odt-spec.rb +733 -0
  68. data/test/test-helper.rb +93 -0
  69. data/test/unit/rd2odt-spec.rb +831 -0
  70. metadata +122 -0
@@ -0,0 +1,831 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.join(File.dirname(__FILE__), "..", "test-helper")
4
+
5
+ describe RD2ODT, "ah_to_xml" do
6
+ # not supported.
7
+ # it "returns empty string if empty array" do
8
+ # RD2ODT.ah_to_xml([]).should == nil
9
+ # end
10
+
11
+ it "returns xml document" do
12
+ RD2ODT.ah_to_xml([:br]).should == "<br />"
13
+ RD2ODT.ah_to_xml([:text__p]).should == "<text:p />"
14
+ RD2ODT.ah_to_xml([:text__style_name]).should == "<text:style-name />"
15
+ RD2ODT.ah_to_xml([:text__sequence_decl,
16
+ {
17
+ :text__display_outline_level => "0",
18
+ :text__name => "Table",
19
+ },
20
+ ]).should ==
21
+ '<text:sequence-decl text:display-outline-level="0" text:name="Table" />'
22
+ RD2ODT.ah_to_xml([:text__p, "this is a pen."]).should ==
23
+ "<text:p>this is a pen.</text:p>"
24
+ RD2ODT.ah_to_xml([:text__p, '&"><']).should ==
25
+ "<text:p>&amp;&quot;&gt;&lt;</text:p>"
26
+ RD2ODT.ah_to_xml([:text__p,
27
+ %Q'Lo<text:s text:c="2" />ok&gt;'.to_sym]).should ==
28
+ %Q'<text:p>Lo<text:s text:c="2" />ok&gt;</text:p>'
29
+ RD2ODT.ah_to_xml([:text__p,
30
+ {:text__style_name => "Text_20_body"},
31
+ "this is a pen.",
32
+ ]).should ==
33
+ '<text:p text:style-name="Text_20_body">this is a pen.</text:p>'
34
+ RD2ODT.ah_to_xml([:office__text,
35
+ [:text__p,
36
+ {:text__style_name => "Text_20_body"},
37
+ "this is a pen.",
38
+ ],
39
+ ]).should ==
40
+ <<EOF.gsub(/\n\z/, "")
41
+ <office:text>
42
+ <text:p text:style-name="Text_20_body">this is a pen.</text:p>
43
+ </office:text>
44
+ EOF
45
+ RD2ODT.ah_to_xml([:office__body,
46
+ {
47
+ :abc__def_ghi => "123",
48
+ :jkl_mno__pqr => "456",
49
+ },
50
+ [:office__text,
51
+ [:text__p,
52
+ {:text__style_name => "Text_20_body"},
53
+ "this is a pen.",
54
+ ],
55
+ ],
56
+ ]).should ==
57
+ <<EOF.gsub(/\n\z/, "")
58
+ <office:body abc:def-ghi="123" jkl-mno:pqr="456">
59
+ <office:text>
60
+ <text:p text:style-name="Text_20_body">this is a pen.</text:p>
61
+ </office:text>
62
+ </office:body>
63
+ EOF
64
+ RD2ODT.ah_to_xml([
65
+ [:text__p,
66
+ {:text__style_name => "Preformatted_20_Text"},
67
+ "text-1",
68
+ ],
69
+ [:text__p,
70
+ {:text__style_name => "Preformatted_20_Text"},
71
+ "text-2",
72
+ ],
73
+ ]).should ==
74
+ <<EOF.gsub(/\n\z/, "")
75
+ <text:p text:style-name="Preformatted_20_Text">text-1</text:p>
76
+ <text:p text:style-name="Preformatted_20_Text">text-2</text:p>
77
+ EOF
78
+ end
79
+ end
80
+
81
+ def str_to_treat_input_ary(s)
82
+ ary = s.split("\n").map { |l|
83
+ l + "\n"
84
+ }
85
+
86
+ # last line does not have "\n" case.
87
+ if !/\n\z/.match(s)
88
+ ary.last.chomp!
89
+ end
90
+
91
+ return ary
92
+ end
93
+
94
+ describe RD2ODT, "treat_input" do
95
+ it "adds '=begin' to first line and adds '=end' to last line if both lines is
96
+ not exist." do
97
+ actual_str = <<ACTUAL
98
+ foo
99
+ bar
100
+ ACTUAL
101
+ expected = str_to_treat_input_ary(<<EXPECTED)
102
+ =begin
103
+ foo
104
+ bar
105
+ =end
106
+ EXPECTED
107
+
108
+ actual_1 = str_to_treat_input_ary(actual_str)
109
+ RD2ODT.treat_input(actual_1).should == expected
110
+
111
+ actual_2 = str_to_treat_input_ary(actual_str.chomp)
112
+ RD2ODT.treat_input(actual_2).should == expected
113
+ end
114
+
115
+ it "does not add '=begin' to first line if it is exist." do
116
+ ary = str_to_treat_input_ary(<<EOF)
117
+ foo
118
+ =begin
119
+ bar
120
+ EOF
121
+ RD2ODT.treat_input(ary.dup).should == ary.dup
122
+ end
123
+
124
+ it "does not add '=end' to last line if it is exist." do
125
+ ary = str_to_treat_input_ary(<<EOF)
126
+ foo
127
+ =end
128
+ bar
129
+ EOF
130
+ RD2ODT.treat_input(ary.dup).should == ary.dup
131
+ end
132
+ end
133
+
134
+ describe RD2ODT::RD2ODTVisitor, "apply_to_DocumentElement" do
135
+ before do
136
+ @visitor = RD2ODT::RD2ODTVisitor.new
137
+ end
138
+
139
+ it "returns top level document structure" do
140
+ sub_content = [:text__p,
141
+ {:text__style_name => "Text_20_body"},
142
+ "本文",
143
+ ]
144
+ result = @visitor.apply_to_DocumentElement(nil,
145
+ [sub_content,
146
+ sub_content])
147
+ result.should ==
148
+ [:office__document_content,
149
+ {
150
+ :xmlns__office => "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
151
+ :xmlns__style => "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
152
+ :xmlns__text => "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
153
+ :xmlns__table => "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
154
+ :xmlns__draw => "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
155
+ :xmlns__fo =>
156
+ "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
157
+ :xmlns__xlink => "http://www.w3.org/1999/xlink",
158
+ :xmlns__dc => "http://purl.org/dc/elements/1.1/",
159
+ :xmlns__meta => "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
160
+ :xmlns__number =>
161
+ "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
162
+ :xmlns__svg =>
163
+ "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
164
+ :xmlns__chart => "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
165
+ :xmlns__dr3d => "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
166
+ :xmlns__math => "http://www.w3.org/1998/Math/MathML",
167
+ :xmlns__form => "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
168
+ :xmlns__script => "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
169
+ :xmlns__ooo => "http://openoffice.org/2004/office",
170
+ :xmlns__ooow => "http://openoffice.org/2004/writer",
171
+ :xmlns__oooc => "http://openoffice.org/2004/calc",
172
+ :xmlns__dom => "http://www.w3.org/2001/xml-events",
173
+ :xmlns__xforms => "http://www.w3.org/2002/xforms",
174
+ :xmlns__xsd => "http://www.w3.org/2001/XMLSchema",
175
+ :xmlns__xsi => "http://www.w3.org/2001/XMLSchema-instance",
176
+ :xmlns__field =>
177
+ "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:field:1.0",
178
+ :office__version => "1.1",
179
+ },
180
+ [:office__scripts],
181
+ [:office__font_face_decls,
182
+ [:style__font_face,
183
+ {
184
+ :style__name => "さざなみ明朝",
185
+ :svg__font_family => "さざなみ明朝",
186
+ :style__font_family_generic => "roman",
187
+ :style__font_pitch => "variable",
188
+ }],
189
+ [:style__font_face,
190
+ {
191
+ :style__name => "IPAゴシック",
192
+ :svg__font_family => "IPAゴシック",
193
+ :style__font_family_generic => "swiss",
194
+ :style__font_pitch => "variable",
195
+ }],
196
+ [:style__font_face,
197
+ {
198
+ :style__name => "IPAゴシック1",
199
+ :svg__font_family => "IPAゴシック",
200
+ :style__font_family_generic => "system",
201
+ :style__font_pitch => "variable",
202
+ }],
203
+ ], # :office__font_face_decls
204
+ [:office__automatic_styles],
205
+ [:office__body,
206
+ [:office__text,
207
+ [:text__sequence_decls,
208
+ [:text__sequence_decl,
209
+ {
210
+ :text__display_outline_level => "0",
211
+ :text__name => "Illustration",
212
+ }],
213
+ [:text__sequence_decl,
214
+ {
215
+ :text__display_outline_level => "0",
216
+ :text__name => "Table",
217
+ }],
218
+ [:text__sequence_decl,
219
+ {
220
+ :text__display_outline_level => "0",
221
+ :text__name => "Text",
222
+ }],
223
+ [:text__sequence_decl,
224
+ {
225
+ :text__display_outline_level => "0",
226
+ :text__name => "Drawing",
227
+ }],
228
+ ], # :text__sequence_decls
229
+ sub_content,
230
+ sub_content,
231
+ ], # :office__text
232
+ ], # :office__body
233
+ ] # :office__document_content
234
+ end
235
+
236
+ it "returns top level document structure with office:automatic-styles" do
237
+ sub_content = [:text__p,
238
+ {:text__style_name => "Text_20_body"},
239
+ "本文",
240
+ ]
241
+ styles = []
242
+ styles << "<a><b/></a>"
243
+ styles << "<c d='e'><f/></c>"
244
+ styles.each do |s|
245
+ @visitor.automatic_styles << REXML::Document.new(s)
246
+ end
247
+ result = @visitor.apply_to_DocumentElement(nil,
248
+ [sub_content,
249
+ sub_content])
250
+ result.should ==
251
+ [:office__document_content,
252
+ {
253
+ :xmlns__office => "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
254
+ :xmlns__style => "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
255
+ :xmlns__text => "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
256
+ :xmlns__table => "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
257
+ :xmlns__draw => "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
258
+ :xmlns__fo =>
259
+ "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
260
+ :xmlns__xlink => "http://www.w3.org/1999/xlink",
261
+ :xmlns__dc => "http://purl.org/dc/elements/1.1/",
262
+ :xmlns__meta => "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
263
+ :xmlns__number =>
264
+ "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
265
+ :xmlns__svg =>
266
+ "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
267
+ :xmlns__chart => "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
268
+ :xmlns__dr3d => "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
269
+ :xmlns__math => "http://www.w3.org/1998/Math/MathML",
270
+ :xmlns__form => "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
271
+ :xmlns__script => "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
272
+ :xmlns__ooo => "http://openoffice.org/2004/office",
273
+ :xmlns__ooow => "http://openoffice.org/2004/writer",
274
+ :xmlns__oooc => "http://openoffice.org/2004/calc",
275
+ :xmlns__dom => "http://www.w3.org/2001/xml-events",
276
+ :xmlns__xforms => "http://www.w3.org/2002/xforms",
277
+ :xmlns__xsd => "http://www.w3.org/2001/XMLSchema",
278
+ :xmlns__xsi => "http://www.w3.org/2001/XMLSchema-instance",
279
+ :xmlns__field =>
280
+ "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:field:1.0",
281
+ :office__version => "1.1",
282
+ },
283
+ [:office__scripts],
284
+ [:office__font_face_decls,
285
+ [:style__font_face,
286
+ {
287
+ :style__name => "さざなみ明朝",
288
+ :svg__font_family => "さざなみ明朝",
289
+ :style__font_family_generic => "roman",
290
+ :style__font_pitch => "variable",
291
+ }],
292
+ [:style__font_face,
293
+ {
294
+ :style__name => "IPAゴシック",
295
+ :svg__font_family => "IPAゴシック",
296
+ :style__font_family_generic => "swiss",
297
+ :style__font_pitch => "variable",
298
+ }],
299
+ [:style__font_face,
300
+ {
301
+ :style__name => "IPAゴシック1",
302
+ :svg__font_family => "IPAゴシック",
303
+ :style__font_family_generic => "system",
304
+ :style__font_pitch => "variable",
305
+ }],
306
+ ], # :office__font_face_decls
307
+ [:office__automatic_styles,
308
+ *styles.map { |s|
309
+ s.to_sym
310
+ }
311
+ ],
312
+ [:office__body,
313
+ [:office__text,
314
+ [:text__sequence_decls,
315
+ [:text__sequence_decl,
316
+ {
317
+ :text__display_outline_level => "0",
318
+ :text__name => "Illustration",
319
+ }],
320
+ [:text__sequence_decl,
321
+ {
322
+ :text__display_outline_level => "0",
323
+ :text__name => "Table",
324
+ }],
325
+ [:text__sequence_decl,
326
+ {
327
+ :text__display_outline_level => "0",
328
+ :text__name => "Text",
329
+ }],
330
+ [:text__sequence_decl,
331
+ {
332
+ :text__display_outline_level => "0",
333
+ :text__name => "Drawing",
334
+ }],
335
+ ], # :text__sequence_decls
336
+ sub_content,
337
+ sub_content,
338
+ ], # :office__text
339
+ ], # :office__body
340
+ ] # :office__document_content
341
+ end
342
+ end
343
+
344
+ describe RD2ODT::RD2ODTVisitor, "apply_to_StringElement" do
345
+ before do
346
+ @visitor = RD2ODT::RD2ODTVisitor.new
347
+ end
348
+
349
+ it "returns text:p element" do
350
+ element = RD::StringElement.new("本文\n")
351
+ result = @visitor.apply_to_StringElement(element)
352
+ result.should == "本文"
353
+ end
354
+
355
+ it "remove \\r and \\n charactor" do
356
+ element = RD::StringElement.new("本文1\n本文2\n本文3\n")
357
+ result = @visitor.apply_to_StringElement(element)
358
+ result.should == "本文1本文2本文3"
359
+
360
+ element = RD::StringElement.new("本文1\r\n本文2\r\n本文3\r\n")
361
+ result = @visitor.apply_to_StringElement(element)
362
+ result.should == "本文1本文2本文3"
363
+ end
364
+ end
365
+
366
+ describe RD2ODT::RD2ODTVisitor, "apply_to_TextBlock" do
367
+ before do
368
+ @visitor = RD2ODT::RD2ODTVisitor.new
369
+ end
370
+
371
+ it "returns text:p element" do
372
+ sub_content = "本文"
373
+ result = @visitor.apply_to_TextBlock(nil, [sub_content])
374
+ result.should == [:text__p,
375
+ {:text__style_name => "Text_20_body"},
376
+ sub_content,
377
+ ]
378
+ end
379
+ end
380
+
381
+ describe RD2ODT::RD2ODTVisitor, "apply_to_Headline" do
382
+ before do
383
+ @visitor = RD2ODT::RD2ODTVisitor.new
384
+ end
385
+
386
+ it "returns text:list element in '=' level without text:continue-numbering when first '='" do
387
+ level = 1
388
+ title = "見出し1"
389
+ element = RD::Headline.new(level)
390
+ element.title << title
391
+ result = @visitor.apply_to_Headline(element, element.title)
392
+ result.should == [:text__list,
393
+ {:text__style_name => "Numbering_20_2"},
394
+ [:text__list_item,
395
+ [:text__p,
396
+ {:text__style_name => "Heading_20_1"},
397
+ "見出し1"
398
+ ],
399
+ ],
400
+ ]
401
+ @visitor.continue_numbering_headline.should == true
402
+ end
403
+
404
+ it "returns text:list element in '=' level with text:continue-numbering when not first '='" do
405
+ level = 1
406
+ title = "見出し2"
407
+ element = RD::Headline.new(level)
408
+ element.title << title
409
+ @visitor.continue_numbering_headline = true
410
+ result = @visitor.apply_to_Headline(element, element.title)
411
+ result.should == [:text__list,
412
+ {
413
+ :text__style_name => "Numbering_20_2",
414
+ :text__continue_numbering => "true",
415
+ },
416
+ [:text__list_item,
417
+ [:text__p,
418
+ {:text__style_name => "Heading_20_1"},
419
+ "見出し2"
420
+ ],
421
+ ],
422
+ ]
423
+ @visitor.continue_numbering_headline.should == true
424
+ end
425
+
426
+ it "returns text:list element in '==' level" do
427
+ level = 2
428
+ title = "見出し2"
429
+ element = RD::Headline.new(level)
430
+ element.title << title
431
+ result = @visitor.apply_to_Headline(element, element.title)
432
+ result.should == [:text__list,
433
+ {
434
+ :text__style_name => "Numbering_20_2",
435
+ :text__continue_numbering => "true",
436
+ },
437
+ [:text__list_item,
438
+ [:text__list,
439
+ {:text__continue_numbering => "true"},
440
+ [:text__list_item,
441
+ [:text__p,
442
+ {:text__style_name => "Heading_20_2"},
443
+ "見出し2",
444
+ ],
445
+ ],
446
+ ],
447
+ ],
448
+ ]
449
+ end
450
+
451
+ it "returns text:list element in '===' level" do
452
+ level = 3
453
+ title = "見出し3"
454
+ element = RD::Headline.new(level)
455
+ element.title << title
456
+ result = @visitor.apply_to_Headline(element, element.title)
457
+ result.should == [:text__list,
458
+ {
459
+ :text__style_name => "Numbering_20_2",
460
+ :text__continue_numbering => "true",
461
+ },
462
+ [:text__list_item,
463
+ [:text__list,
464
+ {:text__continue_numbering => "true"},
465
+ [:text__list_item,
466
+ [:text__list,
467
+ {:text__continue_numbering => "true"},
468
+ [:text__list_item,
469
+ [:text__p,
470
+ {:text__style_name => "Heading_20_3"},
471
+ "見出し3",
472
+ ],
473
+ ],
474
+ ],
475
+ ],
476
+ ],
477
+ ],
478
+ ]
479
+ end
480
+ end
481
+
482
+ describe RD2ODT::RD2ODTVisitor, "apply_to_EnumListItem" do
483
+ before do
484
+ @visitor = RD2ODT::RD2ODTVisitor.new
485
+ end
486
+
487
+ it "returns text:list-item element" do
488
+ result = @visitor.apply_to_EnumListItem(nil, [:sub_content_1,
489
+ :sub_content_2])
490
+ result.should == [:text__list_item,
491
+ :sub_content_1,
492
+ :sub_content_2,
493
+ ]
494
+ end
495
+ end
496
+
497
+ describe RD2ODT::RD2ODTVisitor, "apply_to_EnumList" do
498
+ before do
499
+ @visitor = RD2ODT::RD2ODTVisitor.new
500
+ end
501
+
502
+ it "returns text:list element" do
503
+ result = @visitor.apply_to_EnumList(nil, [:sub_content_1,
504
+ :sub_content_2])
505
+ result.should == [:text__list,
506
+ {
507
+ :text__style_name => "Numbering_20_1",
508
+ :text__continue_numbering => "false",
509
+ },
510
+ :sub_content_1,
511
+ :sub_content_2,
512
+ ]
513
+ end
514
+ end
515
+
516
+ describe RD2ODT::RD2ODTVisitor, "apply_to_ItemListItem" do
517
+ before do
518
+ @visitor = RD2ODT::RD2ODTVisitor.new
519
+ end
520
+
521
+ # same as apply_to_EnumListItem
522
+ it "returns text:list-item element" do
523
+ result = @visitor.apply_to_ItemListItem(nil, [:sub_content_1,
524
+ :sub_content_2])
525
+ result.should == [:text__list_item,
526
+ :sub_content_1,
527
+ :sub_content_2,
528
+ ]
529
+ end
530
+ end
531
+
532
+ describe RD2ODT::RD2ODTVisitor, "apply_to_ItemList" do
533
+ before do
534
+ @visitor = RD2ODT::RD2ODTVisitor.new
535
+ end
536
+
537
+ it "returns text:list element" do
538
+ result = @visitor.apply_to_ItemList(nil, [:sub_content_1,
539
+ :sub_content_2])
540
+ result.should == [:text__list,
541
+ {:text__style_name => "List_20_1"},
542
+ :sub_content_1,
543
+ :sub_content_2,
544
+ ]
545
+ end
546
+ end
547
+
548
+ describe RD2ODT::RD2ODTVisitor, "apply_to_Verbatim" do
549
+ before do
550
+ @visitor = RD2ODT::RD2ODTVisitor.new
551
+ end
552
+
553
+ it "returns text:list element" do
554
+ content_strings = [
555
+ "This is verbatim element.\n",
556
+ " " * 2 + "Lo" + " " * 5 + "ok!\n",
557
+ "\tLo" + "\t\t" + "ok!\n",
558
+ "In the last line, text:line-break is not exist.\n",
559
+ ]
560
+ element = RD::Verbatim.new(content_strings)
561
+ result = @visitor.apply_to_Verbatim(element)
562
+ result.should == [:text__p,
563
+ {:text__style_name => "Preformatted_20_Text"},
564
+ [
565
+ "This is verbatim element.",
566
+ '<text:s text:c="2" />Lo<text:s text:c="5" />ok!<text:line-break /><text:tab />Lo<text:tab /><text:tab />ok!',
567
+ "In the last line, text:line-break is not exist.",
568
+ ].join("<text:line-break />").to_sym,
569
+ ]
570
+ end
571
+ end
572
+
573
+ describe RD2ODT::RD2ODTVisitor, "apply_to_Include" do
574
+ include XmlMatchers
575
+
576
+ before do
577
+ class ::Time
578
+ class << self
579
+ alias orig_now now
580
+
581
+ def now
582
+ return Time.mktime(2008, 12, 30, 12, 34, 56, 78901)
583
+ end
584
+ end
585
+ end
586
+
587
+ @name_prefix = sprintf("rd2odt:%d:%06d:%d:",
588
+ Time.now.tv_sec, Time.now.tv_usec, 1)
589
+
590
+ @visitor = RD2ODT::RD2ODTVisitor.new
591
+
592
+ sample_dir_path = File.join($top_srcdir, "doc", "sample")
593
+ tree_mock = Struct.new(:include_paths).new([sample_dir_path])
594
+ @parent_element = Struct.new(:tree).new(tree_mock)
595
+ end
596
+
597
+ after do
598
+ class ::Time
599
+ class << self
600
+ alias now orig_now
601
+ end
602
+ end
603
+ end
604
+
605
+ it "includes other document" do
606
+ element = RD::Include.new("include-file-simple-text.odt")
607
+ element.parent = @parent_element
608
+ result = @visitor.apply_to_Include(element)
609
+ result[0].should == <<EOF.chomp.to_sym
610
+ <text:p text:style-name='#{@name_prefix}Standard'>これは&lt;&lt;&lt;のサンプルです.</text:p>
611
+ EOF
612
+ result[1].should == <<EOF.chomp.to_sym
613
+ <text:p text:style-name='#{@name_prefix}Standard'>単純なテキストのincludeサンプルです.</text:p>
614
+ EOF
615
+ result[2].should == <<EOF.chomp.to_sym
616
+ <text:p text:style-name='#{@name_prefix}Standard'/>
617
+ EOF
618
+ result.length.should == 3
619
+ result.class.should == Array
620
+ @visitor.number_of_include_files.should == 1
621
+ @visitor.additional_styles[0].to_s.should be_same_as_this_xml(<<EOF.chomp)
622
+ <style:style style:name='#{@name_prefix}Standard' style:class='text' style:family='paragraph'/>
623
+ EOF
624
+ @visitor.additional_styles[1].to_s.should be_same_as_this_xml(<<EOF.chomp)
625
+ <style:style style:name='#{@name_prefix}Text_20_body' style:class='text' style:parent-style-name='#{@name_prefix}Standard' style:display-name='#{@name_prefix}Text body' style:family='paragraph'>
626
+ <style:paragraph-properties fo:margin-bottom='0.212cm' fo:margin-top='0cm'/>
627
+ </style:style>
628
+ EOF
629
+ # additional_styles[2..6] test is omitted.
630
+ @visitor.additional_styles.length.should == 7
631
+ @visitor.additional_styles.class == Array
632
+ end
633
+
634
+ =begin
635
+ it "includes other document" do
636
+ element = RD::Include.new("include-file-simple-styled-text.odt")
637
+ element.parent = @parent_element
638
+ result = @visitor.apply_to_Include(element)
639
+ result[0].should == <<EOF.chomp.to_sym
640
+ <text:p text:style-name='Standard'>これは&lt;&lt;&lt;のサンプルです.</text:p>
641
+ EOF
642
+ result[1].should == <<EOF.chomp.to_sym
643
+ <text:p text:style-name='Standard'>標準: 単純なテキストのincludeサンプルです.</text:p>
644
+ EOF
645
+ result[2].should == <<EOF.chomp.to_sym
646
+ <text:p text:style-name='Standard'/>
647
+ EOF
648
+ result[3].should == <<EOF.chomp.to_sym
649
+ <text:h text:outline-level='1' text:style-name='Heading_20_1'>見出し1</text:h>
650
+ EOF
651
+ result[4].should == <<EOF.chomp.to_sym
652
+ <text:h text:outline-level='2' text:style-name='Heading_20_2'>見出し1.1</text:h>
653
+ EOF
654
+ result[5].should == <<EOF.chomp.to_sym
655
+ <text:p text:style-name='Text_20_body'>本文</text:p>
656
+ EOF
657
+ result[6].should == <<EOF.chomp.to_sym
658
+ <text:p text:style-name='Standard'/>
659
+ EOF
660
+ result[7].should == <<EOF.chomp.to_sym
661
+ <text:p text:style-name='Preformatted_20_Text'>書式設定前テキスト</text:p>
662
+ EOF
663
+ result[8].should == <<EOF.chomp.to_sym
664
+ <text:p text:style-name='Standard'/>
665
+ EOF
666
+ result[9].should == <<EOF.chomp.to_sym
667
+ <text:p text:style-name='Standard'>文字用書式スタイルのincludeテスト</text:p>
668
+ EOF
669
+ result[10].should == <<EOF.chomp.to_sym
670
+ <text:p text:style-name='Standard'><text:span text:style-name='Emphasis'>強調</text:span>標準</text:p>
671
+ EOF
672
+ result[11].should == <<EOF.chomp.to_sym
673
+ <text:p text:style-name='Standard'><text:span text:style-name='Variable'>変数</text:span>標準</text:p>
674
+ EOF
675
+ result[12].should == <<EOF.chomp.to_sym
676
+ <text:p text:style-name='Standard'><text:span text:style-name='Teletype'>等幅フォント</text:span>標準</text:p>
677
+ EOF
678
+ result[13].should == <<EOF.chomp.to_sym
679
+ <text:p text:style-name='Standard'/>
680
+ EOF
681
+ result.length.should == 14
682
+ result.class.should == Array
683
+ end
684
+ =end
685
+
686
+ it "includes other document which containts table:table" do
687
+ element = RD::Include.new("include-file-table.odt")
688
+ element.parent = @parent_element
689
+ result = @visitor.apply_to_Include(element)
690
+ result[0].should == <<EOF.chomp.to_sym
691
+ <text:p text:style-name='#{@name_prefix}Standard'>これは&lt;&lt;&lt;のサンプルです.</text:p>
692
+ EOF
693
+ result[1].should be_same_as_this_xml(<<EOF.chomp.to_sym)
694
+ <table:table table:name='#{@name_prefix}表1' table:style-name='#{@name_prefix}表1'>
695
+ <table:table-column table:number-columns-repeated='3' table:style-name='#{@name_prefix}表1.A'/>
696
+ <table:table-row>
697
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.A1'>
698
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>表つき文書の</text:p>
699
+ </table:table-cell>
700
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.A1'>
701
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>埋め込み</text:p>
702
+ </table:table-cell>
703
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.C1'>
704
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>サンプル</text:p>
705
+ </table:table-cell>
706
+ </table:table-row>
707
+ <table:table-row>
708
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.A2'>
709
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>1</text:p>
710
+ </table:table-cell>
711
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.A2'>
712
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>2</text:p>
713
+ </table:table-cell>
714
+ <table:table-cell office:value-type='string' table:style-name='#{@name_prefix}表1.C2'>
715
+ <text:p text:style-name='#{@name_prefix}Table_20_Contents'>3</text:p>
716
+ </table:table-cell>
717
+ </table:table-row>
718
+ </table:table>
719
+ EOF
720
+ result[2].should == <<EOF.chomp.to_sym
721
+ <text:p text:style-name='#{@name_prefix}Standard'/>
722
+ EOF
723
+ result.length.should == 3
724
+ result.class.should == Array
725
+ @visitor.automatic_styles[0].to_s.should be_same_as_this_xml(<<EOF.chomp)
726
+ <style:style style:name='#{@name_prefix}表1' style:family='table'>
727
+ <style:table-properties table:align='margins' style:width='16.999cm'/>
728
+ </style:style>
729
+ EOF
730
+ @visitor.automatic_styles[1].to_s.should be_same_as_this_xml(<<EOF.chomp)
731
+ <style:style style:name='#{@name_prefix}表1.A' style:family='table-column'>
732
+ <style:table-column-properties style:column-width='5.666cm' style:rel-column-width='21845*'/>
733
+ </style:style>
734
+ EOF
735
+ # automatic_styles[2..5] test is omitted.
736
+ @visitor.automatic_styles.length.should == 6
737
+ @visitor.automatic_styles.class.should == Array
738
+ end
739
+
740
+ it "includes other document which containts draw:*" do
741
+ element = RD::Include.new("include-file-shape.odt")
742
+ element.parent = @parent_element
743
+ result = @visitor.apply_to_Include(element)
744
+ result[0].should == <<EOF.chomp.to_sym
745
+ <text:p text:style-name='#{@name_prefix}Standard'>これは&lt;&lt;&lt;のサンプルです.</text:p>
746
+ EOF
747
+ result[1].should be_same_as_this_xml(<<EOF.chomp.to_sym)
748
+ <text:p text:style-name='#{@name_prefix}Standard'><draw:g text:anchor-type='paragraph' draw:z-index='0' draw:style-name='#{@name_prefix}gr1'><draw:custom-shape svg:x='3.348cm' svg:y='0.088cm' svg:height='3.911cm' draw:style-name='#{@name_prefix}gr2' svg:width='3.887cm'>
749
+ <text:p/>
750
+ <draw:enhanced-geometry draw:glue-points='10800 0 3160 3160 0 10800 3160 18440 10800 21600 18440 18440 21600 10800 18440 3160' draw:type='smiley' draw:enhanced-path='U 10800 10800 10800 10800 0 23592960 Z N U 7305 7515 1165 1165 0 23592960 Z N U 14295 7515 1165 1165 0 23592960 Z N M 4870 ?f1 C 8680 ?f2 12920 ?f2 16730 ?f1 F N' draw:modifiers='17520' draw:text-areas='3200 3200 18400 18400' svg:viewBox='0 0 21600 21600'>
751
+ <draw:equation draw:name='f0' draw:formula='$0 -15510'/>
752
+ <draw:equation draw:name='f1' draw:formula='17520-?f0 '/>
753
+ <draw:equation draw:name='f2' draw:formula='15510+?f0 '/>
754
+ <draw:handle draw:handle-range-y-maximum='17520' draw:handle-range-y-minimum='15510' draw:handle-position='10800 $0'/>
755
+ </draw:enhanced-geometry>
756
+ </draw:custom-shape><draw:custom-shape svg:x='8.225cm' svg:y='0.873cm' draw:text-style-name='P1' svg:height='1.881cm' draw:style-name='#{@name_prefix}gr3' svg:width='3.303cm'>
757
+ <text:p text:style-name='#{@name_prefix}P1'>Yes,</text:p>
758
+ <text:p text:style-name='#{@name_prefix}P1'>This is the sample!</text:p>
759
+ <draw:enhanced-geometry draw:type='round-rectangular-callout' draw:enhanced-path='M 3590 0 X 0 3590 L ?f2 ?f3 0 8970 0 12630 ?f4 ?f5 0 18010 Y 3590 21600 L ?f6 ?f7 8970 21600 12630 21600 ?f8 ?f9 18010 21600 X 21600 18010 L ?f10 ?f11 21600 12630 21600 8970 ?f12 ?f13 21600 3590 Y 18010 0 L ?f14 ?f15 12630 0 8970 0 ?f16 ?f17 Z N' draw:modifiers='-7311.47891083823 20689.0346766635' draw:text-areas='800 800 20800 20800' svg:viewBox='0 0 21600 21600'>
760
+ <draw:equation draw:name='f0' draw:formula='$0 -10800'/>
761
+ <draw:equation draw:name='f1' draw:formula='$1 -10800'/>
762
+ <draw:equation draw:name='f2' draw:formula='if(?f18 ,$0 ,0)'/>
763
+ <draw:equation draw:name='f3' draw:formula='if(?f18 ,$1 ,6280)'/>
764
+ <draw:equation draw:name='f4' draw:formula='if(?f23 ,$0 ,0)'/>
765
+ <draw:equation draw:name='f5' draw:formula='if(?f23 ,$1 ,15320)'/>
766
+ <draw:equation draw:name='f6' draw:formula='if(?f26 ,$0 ,6280)'/>
767
+ <draw:equation draw:name='f7' draw:formula='if(?f26 ,$1 ,21600)'/>
768
+ <draw:equation draw:name='f8' draw:formula='if(?f29 ,$0 ,15320)'/>
769
+ <draw:equation draw:name='f9' draw:formula='if(?f29 ,$1 ,21600)'/>
770
+ <draw:equation draw:name='f10' draw:formula='if(?f32 ,$0 ,21600)'/>
771
+ <draw:equation draw:name='f11' draw:formula='if(?f32 ,$1 ,15320)'/>
772
+ <draw:equation draw:name='f12' draw:formula='if(?f34 ,$0 ,21600)'/>
773
+ <draw:equation draw:name='f13' draw:formula='if(?f34 ,$1 ,6280)'/>
774
+ <draw:equation draw:name='f14' draw:formula='if(?f36 ,$0 ,15320)'/>
775
+ <draw:equation draw:name='f15' draw:formula='if(?f36 ,$1 ,0)'/>
776
+ <draw:equation draw:name='f16' draw:formula='if(?f38 ,$0 ,6280)'/>
777
+ <draw:equation draw:name='f17' draw:formula='if(?f38 ,$1 ,0)'/>
778
+ <draw:equation draw:name='f18' draw:formula='if($0 ,-1,?f19 )'/>
779
+ <draw:equation draw:name='f19' draw:formula='if(?f1 ,-1,?f22 )'/>
780
+ <draw:equation draw:name='f20' draw:formula='abs(?f0 )'/>
781
+ <draw:equation draw:name='f21' draw:formula='abs(?f1 )'/>
782
+ <draw:equation draw:name='f22' draw:formula='?f20 -?f21 '/>
783
+ <draw:equation draw:name='f23' draw:formula='if($0 ,-1,?f24 )'/>
784
+ <draw:equation draw:name='f24' draw:formula='if(?f1 ,?f22 ,-1)'/>
785
+ <draw:equation draw:name='f25' draw:formula='$1 -21600'/>
786
+ <draw:equation draw:name='f26' draw:formula='if(?f25 ,?f27 ,-1)'/>
787
+ <draw:equation draw:name='f27' draw:formula='if(?f0 ,-1,?f28 )'/>
788
+ <draw:equation draw:name='f28' draw:formula='?f21 -?f20 '/>
789
+ <draw:equation draw:name='f29' draw:formula='if(?f25 ,?f30 ,-1)'/>
790
+ <draw:equation draw:name='f30' draw:formula='if(?f0 ,?f28 ,-1)'/>
791
+ <draw:equation draw:name='f31' draw:formula='$0 -21600'/>
792
+ <draw:equation draw:name='f32' draw:formula='if(?f31 ,?f33 ,-1)'/>
793
+ <draw:equation draw:name='f33' draw:formula='if(?f1 ,?f22 ,-1)'/>
794
+ <draw:equation draw:name='f34' draw:formula='if(?f31 ,?f35 ,-1)'/>
795
+ <draw:equation draw:name='f35' draw:formula='if(?f1 ,-1,?f22 )'/>
796
+ <draw:equation draw:name='f36' draw:formula='if($1 ,-1,?f37 )'/>
797
+ <draw:equation draw:name='f37' draw:formula='if(?f0 ,?f28 ,-1)'/>
798
+ <draw:equation draw:name='f38' draw:formula='if($1 ,-1,?f39 )'/>
799
+ <draw:equation draw:name='f39' draw:formula='if(?f0 ,-1,?f28 )'/>
800
+ <draw:equation draw:name='f40' draw:formula='$0 '/>
801
+ <draw:equation draw:name='f41' draw:formula='$1 '/>
802
+ <draw:handle draw:handle-position='$0 $1'/>
803
+ </draw:enhanced-geometry>
804
+ </draw:custom-shape>
805
+ </draw:g>シェイプ付きのOpen Documentファイルです.</text:p>
806
+ EOF
807
+ result[2].should == <<EOF.chomp.to_sym
808
+ <text:p text:style-name='#{@name_prefix}Standard'/>
809
+ EOF
810
+ result.length.should == 3
811
+ result.class.should == Array
812
+ @visitor.automatic_styles[0].to_s.should be_same_as_this_xml(<<EOF.chomp)
813
+ <style:style style:name='#{@name_prefix}P1' style:family='paragraph'>
814
+ <style:paragraph-properties fo:text-align='center'/>
815
+ </style:style>
816
+ EOF
817
+ @visitor.automatic_styles[1].to_s.should be_same_as_this_xml(<<EOF.chomp)
818
+ <style:style style:name='#{@name_prefix}gr1' style:family='graphic'>
819
+ <style:graphic-properties style:flow-with-text='false' style:horizontal-pos='from-left' style:wrap='none' style:vertical-rel='paragraph' draw:wrap-influence-on-position='once-concurrent' style:horizontal-rel='paragraph' style:run-through='foreground' style:vertical-pos='from-top'/>
820
+ </style:style>
821
+ EOF
822
+ @visitor.automatic_styles[2].to_s.should be_same_as_this_xml(<<EOF.chomp)
823
+ <style:style style:name='#{@name_prefix}gr2' style:family='graphic'>
824
+ <style:graphic-properties draw:textarea-vertical-align='middle' draw:auto-grow-height='false' style:run-through='foreground' draw:textarea-horizontal-align='justify'/>
825
+ </style:style>
826
+ EOF
827
+ # automatic_styles[3] test is omitted.
828
+ @visitor.automatic_styles.length.should == 4
829
+ @visitor.automatic_styles.class.should == Array
830
+ end
831
+ end