rd2odt 0.1.0

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