clbustos-rtf 0.3.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,5 +1,20 @@
1
1
  == CHANGES
2
-
2
+ 0.4.2
3
+ * Fix bug causing TextNode.to_rtf to return nil under 1.8.7[Jason Langenauer]
4
+ * Tests run under Ruby 1.9.2 and later [clbustos]
5
+ 0.4.1
6
+ * Links: implemented hyperlinks[Marcello Barnaba]
7
+ * Lists: add a newline before every new list[Marcello Barnaba]
8
+ 0.4.0
9
+ * Lists: Decimal: quick&dirty implementation of sequential numbering[Marcello Barnaba]
10
+ * Lists: Decimal: fixed marker name generation: it must contain the dot[Marcello Barnaba]
11
+ * Lists: removed last StringIO occurrences in new code[Marcello Barnaba]
12
+ * Lists: wrote minimal object model test[Marcello Barnaba]
13
+ * Lists: refactored and cleaned up the API a bit[Marcello Barnaba]
14
+ * Lists: wrote the API bridge between Nodes and Lists[Marcello Barnaba]
15
+ * Lists: initial implementation of listtable header generation[Marcello Barnaba]
16
+ * Node: cleaned up the generic to_rtf, added the .wrap option to the constructor[Marcello Barnaba]
17
+ * Node: stubbed out paragraph generation into a new ParagraphNode[Marcello Barnaba]
3
18
  0.3.1
4
19
  * Added the #subscript helper to the CommandNode class [vjt]
5
20
 
@@ -1,3 +1,15 @@
1
+ == Purpose of this fork
2
+
3
+ * [DONE] Add support for ordered and unordered lists
4
+ * [DONE] Add support for hyperlinks
5
+ * [TODO] Write comprehensive tests for OL and UL
6
+ * [TODO] Clean up the API
7
+ * [TODO] DRY the code
8
+
9
+ Please, please, please: if you come along this library and would lend me an
10
+ hand to complete tests, please help. Thank you!
11
+
12
+
1
13
  == Ruby Rich Text Format (RTF) Library
2
14
  The RTF library provides a pure Ruby set of functionality that can be used to
3
15
  programmatically create RTF documents. The main aim in developing this library
@@ -65,7 +77,7 @@ name space. This is a convenience mechanism that saves on specifically having
65
77
  to refer to the module when accessing the RTF library. Next we want to create
66
78
  an RTF document and that is done like this...
67
79
 
68
- document = RTF::Document.new(RTF::Font::ROMAN)
80
+ document = RTF::Document.new(RTF::Font.new(RTF::Font::ROMAN, 'Times New Roman'))
69
81
 
70
82
  This line of code creates a new Document object, specifying that the default
71
83
  font for the document will the the Times New Roman font. So we have a document,
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- $:.unshift(File.dirname(__FILE__))
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__)))
2
2
  require 'rake'
3
3
 
4
4
  begin
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 3
4
- :patch: 1
3
+ :minor: 4
4
+ :patch: 2
5
5
  :build:
data/lib/rtf.rb CHANGED
@@ -7,6 +7,7 @@ require 'rtf/style'
7
7
  require 'rtf/information'
8
8
  require 'rtf/paper'
9
9
  require 'rtf/node'
10
+ require 'rtf/list'
10
11
 
11
12
  # This module encapsulates all the classes and definitions relating to the RTF
12
13
  # library.
@@ -31,4 +32,4 @@ module RTF
31
32
  raise RTFError.new(message)
32
33
  end
33
34
  end # End of the RTFError class.
34
- end # End of the RTF module.
35
+ end # End of the RTF module.
@@ -0,0 +1,219 @@
1
+ module RTF
2
+ class ListTable
3
+ def initialize
4
+ @templates = []
5
+ end
6
+
7
+ def new_template
8
+ @templates.push ListTemplate.new(next_template_id)
9
+ @templates.last
10
+ end
11
+
12
+ def to_rtf(indent=0)
13
+ return '' if @templates.empty?
14
+
15
+ prefix = indent > 0 ? ' ' * indent : ''
16
+
17
+ # List table
18
+ text = "#{prefix}{\\*\\listtable"
19
+ @templates.each {|tpl| text << tpl.to_rtf}
20
+ text << "}"
21
+
22
+ # List override table, a Cargo Cult.
23
+ text << "#{prefix}{\\*\\listoverridetable"
24
+ @templates.each do |tpl|
25
+ text << "{\\listoverride\\listid#{tpl.id}\\listoverridecount0\\ls#{tpl.id}}"
26
+ end
27
+ text << "}\n"
28
+ end
29
+
30
+ protected
31
+ def next_template_id
32
+ @templates.size + 1
33
+ end
34
+
35
+ end
36
+
37
+ class ListMarker
38
+ def initialize(name, codepoint=nil)
39
+ @name = name
40
+ @codepoint = codepoint
41
+ end
42
+
43
+ def bullet?
44
+ !@codepoint.nil?
45
+ end
46
+
47
+ def type
48
+ bullet? ? :bullet : :decimal
49
+ end
50
+
51
+ def number_type
52
+ # 23: bullet, 0: arabic
53
+ # applies to the \levelnfcN macro
54
+ #
55
+ bullet? ? 23 : 0
56
+ end
57
+
58
+ def name
59
+ name = "\\{#@name\\}"
60
+ name << '.' unless bullet?
61
+ name
62
+ end
63
+
64
+ def template_format
65
+ # The first char is the string size, the next ones are
66
+ # either placeholders (\'0X) or actual characters to
67
+ # include in the format. In the bullet case, \uc0 is
68
+ # used to get rid of the multibyte translation: we want
69
+ # an Unicode character.
70
+ #
71
+ # In the decimal case, we have a fixed format, with a
72
+ # dot following the actual number.
73
+ #
74
+ if bullet?
75
+ "\\'01\\uc0\\u#@codepoint"
76
+ else
77
+ "\\'02\\'00. "
78
+ end
79
+ end
80
+
81
+ def text_format(n=nil)
82
+ text =
83
+ if bullet?
84
+ "\\uc0\\u#@codepoint"
85
+ else
86
+ "#{n}."
87
+ end
88
+
89
+ "\t#{text}\t"
90
+ end
91
+ end
92
+
93
+ class ListTemplate
94
+ attr_reader :id
95
+
96
+ Markers = {
97
+ :disc => ListMarker.new('disc', 0x2022),
98
+ :hyphen => ListMarker.new('hyphen', 0x2043),
99
+ :decimal => ListMarker.new('decimal' )
100
+ }
101
+
102
+ def initialize(id)
103
+ @levels = []
104
+ @id = id
105
+ end
106
+
107
+ def level_for(level, kind = :bullets)
108
+ @levels[level-1] ||= begin
109
+ # Only disc for now: we'll add support
110
+ # for more customization options later
111
+ marker = Markers[kind == :bullets ? :disc : :decimal]
112
+ ListLevel.new(self, marker, level)
113
+ end
114
+ end
115
+
116
+ def to_rtf(indent=0)
117
+ prefix = indent > 0 ? ' ' * indent : ''
118
+
119
+ text = "#{prefix}{\\list\\listtemplate#{id}\\listhybrid"
120
+ @levels.each {|lvl| text << lvl.to_rtf}
121
+ text << "{\\listname;}\\listid#{id}}\n"
122
+
123
+ text
124
+ end
125
+ end
126
+
127
+ class ListLevel
128
+ ValidLevels = (1..9)
129
+
130
+ LevelTabs = [
131
+ 220, 720, 1133, 1700, 2267,
132
+ 2834, 3401, 3968, 4535, 5102,
133
+ 5669, 6236, 6803
134
+ ].freeze
135
+
136
+ ResetTabs = [560].concat(LevelTabs[2..-1]).freeze
137
+
138
+ attr_reader :level, :marker
139
+
140
+ def initialize(template, marker, level)
141
+ unless marker.kind_of? ListMarker
142
+ RTFError.fire("Invalid marker #{marker.inspect}")
143
+ end
144
+
145
+ unless ValidLevels.include? level
146
+ RTFError.fire("Invalid list level: #{level}")
147
+ end
148
+
149
+ @template = template
150
+ @level = level
151
+ @marker = marker
152
+ end
153
+
154
+ def type
155
+ @marker.type
156
+ end
157
+
158
+ def reset_tabs
159
+ ResetTabs
160
+ end
161
+
162
+ def tabs
163
+ @tabs ||= begin
164
+ tabs = LevelTabs.dup # Kernel#tap would be prettier here
165
+
166
+ (@level - 1).times do
167
+ # Reverse-engineered while looking at Textedit.app
168
+ # generated output: they already made sure that it
169
+ # would look good on every RTF editor :-p
170
+ #
171
+ a, = tabs.shift(3)
172
+ a,b = a + 720, a + 1220
173
+ tabs.shift while tabs.first < b
174
+ tabs.unshift a, b
175
+ end
176
+
177
+ tabs
178
+ end
179
+ end
180
+
181
+ def id
182
+ @id ||= @template.id * 10 + level
183
+ end
184
+
185
+ def indent
186
+ @indent ||= level * 720
187
+ end
188
+
189
+ def to_rtf(indent=0)
190
+ prefix = indent > 0 ? ' ' * indent : ''
191
+
192
+ text = "#{prefix}{\\listlevel\\levelstartat1"
193
+
194
+ # Marker type. The first declaration is for Backward Compatibility (BC).
195
+ nfc = @marker.number_type
196
+ text << "\\levelnfc#{nfc}\\levelnfcn#{nfc}"
197
+
198
+ # Justification, currently only left justified (0). First decl for BC.
199
+ text << '\leveljc0\leveljcn0'
200
+
201
+ # Character that follows the level text, currently only TAB.
202
+ text << '\levelfollow0'
203
+
204
+ # BC: Minimum distance from the left & right edges.
205
+ text << '\levelindent0\levelspace360'
206
+
207
+ # Marker name
208
+ text << "{\\*\\levelmarker #{@marker.name}}"
209
+
210
+ # Marker text format
211
+ text << "{\\leveltext\\leveltemplateid#{id}#{@marker.template_format};}"
212
+ text << '{\levelnumbers;}'
213
+
214
+ # The actual spacing
215
+ text << "\\fi-360\\li#{self.indent}\\lin#{self.indent}}\n"
216
+ end
217
+
218
+ end
219
+ end
@@ -120,6 +120,8 @@ module RTF
120
120
  rtf.encode("UTF-16LE").each_codepoint.map {|cp|
121
121
  cp < 128 ? cp.chr : "\\u#{cp}\\'3f"
122
122
  }.join("")
123
+ else
124
+ rtf
123
125
  end
124
126
  end
125
127
  end # End of the TextNode class.
@@ -212,6 +214,9 @@ module RTF
212
214
  # be written to separate lines whether the node is converted
213
215
  # to RTF. Defaults to true
214
216
  attr_accessor :split
217
+ # A boolean to indicate whether the prefix and suffix should
218
+ # be wrapped in curly braces. Defaults to true.
219
+ attr_accessor :wrap
215
220
 
216
221
  # This is the constructor for the CommandNode class.
217
222
  #
@@ -223,11 +228,14 @@ module RTF
223
228
  # split:: A boolean to indicate whether the prefix and suffix should
224
229
  # be written to separate lines whether the node is converted
225
230
  # to RTF. Defaults to true.
226
- def initialize(parent, prefix, suffix=nil, split=true)
231
+ # wrap:: A boolean to indicate whether the prefix and suffix should
232
+ # be wrapped in curly braces. Defaults to true.
233
+ def initialize(parent, prefix, suffix=nil, split=true, wrap=true)
227
234
  super(parent)
228
235
  @prefix = prefix
229
236
  @suffix = suffix
230
237
  @split = split
238
+ @wrap = wrap
231
239
  end
232
240
 
233
241
  # This method adds text to a command node. If the last child node of the
@@ -246,19 +254,20 @@ module RTF
246
254
 
247
255
  # This method generates the RTF text for a CommandNode object.
248
256
  def to_rtf
249
- text = StringIO.new
250
- separator = split? ? "\n" : " "
251
- line = (separator == " ")
257
+ text = StringIO.new
258
+
259
+ text << '{' if wrap?
260
+ text << @prefix if @prefix
252
261
 
253
- text << "{#{@prefix}"
254
- text << separator if self.size > 0
255
262
  self.each do |entry|
256
- text << "\n" if line
257
- line = true
258
- text << "#{entry.to_rtf}"
263
+ text << "\n" if split?
264
+ text << entry.to_rtf
259
265
  end
260
- text << "\n" if split?
261
- text << "#{@suffix}}"
266
+
267
+ text << "\n" if split?
268
+ text << @suffix if @suffix
269
+ text << '}' if wrap?
270
+
262
271
  text.string
263
272
  end
264
273
 
@@ -273,16 +282,43 @@ module RTF
273
282
  # for the new paragraph. Defaults to nil to indicate that the
274
283
  # currently applied paragraph styling should be used.
275
284
  def paragraph(style=nil)
276
- # Create the node prefix.
277
- text = StringIO.new
278
- text << '\pard'
279
- text << style.prefix(nil, nil) if style != nil
280
-
281
- node = CommandNode.new(self, text.string, '\par')
285
+ node = ParagraphNode.new(self, style)
282
286
  yield node if block_given?
283
287
  self.store(node)
284
288
  end
285
289
 
290
+ # This method provides a short cut means of creating a new ordered or
291
+ # unordered list. The method requires a block that will be passed a
292
+ # single parameter that'll be a reference to the first level of the
293
+ # list. See the +ListLevelNode+ doc for more information.
294
+ #
295
+ # Example usage:
296
+ #
297
+ # rtf.list do |level1|
298
+ # level1.item do |li|
299
+ # li << 'some text'
300
+ # li.apply(some_style) {|x| x << 'some styled text'}
301
+ # end
302
+ #
303
+ # level1.list(:decimal) do |level2|
304
+ # level2.item {|li| li << 'some other text in a decimal list'}
305
+ # level2.item {|li| li << 'and here we go'}
306
+ # end
307
+ # end
308
+ #
309
+ def list(kind=:bullets)
310
+ node = ListNode.new(self)
311
+ yield node.list(kind)
312
+ self.store(node)
313
+ end
314
+
315
+ def link(url, text=nil)
316
+ node = LinkNode.new(self, url)
317
+ node << text if text
318
+ yield node if block_given?
319
+ self.store(node)
320
+ end
321
+
286
322
  # This method provides a short cut means of creating a line break command
287
323
  # node. This command node does not take a block and may possess no other
288
324
  # content.
@@ -541,11 +577,123 @@ module RTF
541
577
  node
542
578
  end
543
579
 
544
- alias :write :<<
545
- alias :color :colour
580
+ alias :write :<<
581
+ alias :color :colour
546
582
  alias :split? :split
583
+ alias :wrap? :wrap
547
584
  end # End of the CommandNode class.
548
585
 
586
+ # This class represents a paragraph within an RTF document.
587
+ class ParagraphNode < CommandNode
588
+ def initialize(parent, style=nil)
589
+ prefix = '\pard'
590
+ prefix << style.prefix(nil, nil) if style
591
+
592
+ super(parent, prefix, '\par')
593
+ end
594
+ end
595
+
596
+ # This class represents an ordered/unordered list within an RTF document.
597
+ #
598
+ # Currently list nodes can contain any type of node, but this behaviour
599
+ # will change in future releases. The class overrides the +list+ method
600
+ # to return a +ListLevelNode+.
601
+ #
602
+ class ListNode < CommandNode
603
+ def initialize(parent)
604
+ prefix = "\\"
605
+
606
+ suffix = '\pard'
607
+ suffix << ListLevel::ResetTabs.map {|tw| "\\tx#{tw}"}.join
608
+ suffix << '\ql\qlnatural\pardirnatural\cf0 \\'
609
+
610
+ super(parent, prefix, suffix, true, false)
611
+
612
+ @template = root.lists.new_template
613
+ end
614
+
615
+ # This method creates a new +ListLevelNode+ of the given kind and
616
+ # stores it in the document tree.
617
+ #
618
+ # ==== Parameters
619
+ # kind:: The kind of this list level, may be either :bullets or :decimal
620
+ def list(kind)
621
+ self.store ListLevelNode.new(self, @template, kind)
622
+ end
623
+ end
624
+
625
+ # This class represents a list level, and carries out indenting information
626
+ # and the bullet or number that is prepended to each +ListTextNode+.
627
+ #
628
+ # The class overrides the +list+ method to implement nesting, and provides
629
+ # the +item+ method to add a new list item, the +ListTextNode+.
630
+ class ListLevelNode < CommandNode
631
+ def initialize(parent, template, kind, level=1)
632
+ @template = template
633
+ @kind = kind
634
+ @level = template.level_for(level, kind)
635
+
636
+ prefix = '\pard'
637
+ prefix << @level.tabs.map {|tw| "\\tx#{tw}"}.join
638
+ prefix << "\\li#{@level.indent}\\fi-#{@level.indent}"
639
+ prefix << "\\ql\\qlnatural\\pardirnatural\n"
640
+ prefix << "\\ls#{@template.id}\\ilvl#{@level.level-1}\\cf0"
641
+
642
+ super(parent, prefix, nil, true, false)
643
+ end
644
+
645
+ # Returns the kind of this level, either :bullets or :decimal
646
+ attr_reader :kind
647
+
648
+ # Returns the indenting level of this list, from 1 to 9
649
+ def level
650
+ @level.level
651
+ end
652
+
653
+ # Creates a new +ListTextNode+ and yields it to the calling block
654
+ def item
655
+ node = ListTextNode.new(self, @level)
656
+ yield node
657
+ self.store(node)
658
+ end
659
+
660
+ # Creates a new +ListLevelNode+ to implement nested lists
661
+ def list(kind=@kind)
662
+ node = ListLevelNode.new(self, @template, kind, @level.level+1)
663
+ yield node
664
+ self.store(node)
665
+ end
666
+ end
667
+
668
+ # This class represents a list item, that can contain text or
669
+ # other nodes. Currently any type of node is accepted, but after
670
+ # more extensive testing this behaviour may change.
671
+ class ListTextNode < CommandNode
672
+ def initialize(parent, level)
673
+ @level = level
674
+ @parent = parent
675
+
676
+ number = siblings_count + 1 if parent.kind == :decimal
677
+ prefix = "{\\listtext#{@level.marker.text_format(number)}}"
678
+ suffix = '\\'
679
+
680
+ super(parent, prefix, suffix, false, false)
681
+ end
682
+
683
+ private
684
+ def siblings_count
685
+ parent.children.select {|n| n.kind_of?(self.class)}.size
686
+ end
687
+ end
688
+
689
+ class LinkNode < CommandNode
690
+ def initialize(parent, url)
691
+ prefix = "\\field{\\*\\fldinst HYPERLINK \"#{url}\"}{\\fldrslt "
692
+ suffix = "}"
693
+
694
+ super(parent, prefix, suffix, false)
695
+ end
696
+ end
549
697
 
550
698
  # This class represents a table node within an RTF document. Table nodes are
551
699
  # specialised container nodes that contain only TableRowNodes and have their
@@ -951,19 +1099,8 @@ module RTF
951
1099
  # ComamndNode class to forbid the creation of paragraphs.
952
1100
  #
953
1101
  # ==== Parameters
954
- # justification:: The justification to be applied to the paragraph.
955
- # before:: The amount of space, in twips, to be inserted before
956
- # the paragraph. Defaults to nil.
957
- # after:: The amount of space, in twips, to be inserted after
958
- # the paragraph. Defaults to nil.
959
- # left:: The amount of indentation to place on the left of the
960
- # paragraph. Defaults to nil.
961
- # right:: The amount of indentation to place on the right of the
962
- # paragraph. Defaults to nil.
963
- # first:: The amount of indentation to place on the left of the
964
- # first line in the paragraph. Defaults to nil.
965
- def paragraph(justification=CommandNode::LEFT_JUSTIFY, before=nil,
966
- after=nil, left=nil, right=nil, first=nil)
1102
+ # style:: The paragraph style, ignored
1103
+ def paragraph(style=nil)
967
1104
  RTFError.fire("TableCellNode#paragraph() called. Table cells cannot "\
968
1105
  "contain paragraphs.")
969
1106
  end
@@ -1496,8 +1633,8 @@ module RTF
1496
1633
  LC_VIETNAMESE = 1066
1497
1634
 
1498
1635
  # Attribute accessor.
1499
- attr_reader :fonts, :colours, :information, :character_set, :language,
1500
- :style
1636
+ attr_reader :fonts, :lists, :colours, :information, :character_set,
1637
+ :language, :style
1501
1638
 
1502
1639
  # Attribute mutator.
1503
1640
  attr_writer :character_set, :language
@@ -1516,6 +1653,7 @@ module RTF
1516
1653
  def initialize(font, style=nil, character=CS_ANSI, language=LC_ENGLISH_UK)
1517
1654
  super(nil, '\rtf1')
1518
1655
  @fonts = FontTable.new(font)
1656
+ @lists = ListTable.new
1519
1657
  @default_font = 0
1520
1658
  @colours = ColourTable.new
1521
1659
  @information = Information.new
@@ -1669,6 +1807,7 @@ module RTF
1669
1807
  text << "\n#{@fonts.to_rtf}"
1670
1808
  text << "\n#{@colours.to_rtf}" if @colours.size > 0
1671
1809
  text << "\n#{@information.to_rtf}"
1810
+ text << "\n#{@lists.to_rtf}"
1672
1811
  if @headers.compact != []
1673
1812
  text << "\n#{@headers[3].to_rtf}" if @headers[3] != nil
1674
1813
  text << "\n#{@headers[2].to_rtf}" if @headers[2] != nil
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class CharacterStyleTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # ColourTable class unit test class.
4
4
  class ColourTableTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Colour class unit test class.
4
4
  class ColourTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class CommandNodeTest < Test::Unit::TestCase
@@ -40,7 +40,7 @@ class CommandNodeTest < Test::Unit::TestCase
40
40
 
41
41
  assert(root.paragraph(style) != nil)
42
42
  assert(root.size == 1)
43
- assert(root[0].class == CommandNode)
43
+ assert(root[0].class == ParagraphNode)
44
44
  assert(root[0].prefix == '\pard\ql')
45
45
  assert(root[0].suffix == '\par')
46
46
  assert(root.split == true)
@@ -207,6 +207,32 @@ class CommandNodeTest < Test::Unit::TestCase
207
207
  assert(table[0][2].width == 200)
208
208
  end
209
209
 
210
+ # List object model test
211
+ def test_list
212
+ root = Document.new(Font.new(Font::ROMAN, 'Arial'))
213
+ root.list do |l1|
214
+ assert l1.class == ListLevelNode
215
+ assert l1.level == 1
216
+
217
+ l1.item do |li|
218
+ assert li.class == ListTextNode
219
+ text = li << 'text'
220
+ assert text.class == TextNode
221
+ assert text.text == 'text'
222
+ end
223
+
224
+ l1.list do |l2|
225
+ assert l2.class == ListLevelNode
226
+ assert l2.level == 2
227
+ l2.item do |li|
228
+ text = li << 'text'
229
+ assert text.class == TextNode
230
+ assert text.text == 'text'
231
+ end
232
+ end
233
+ end
234
+ end
235
+
210
236
  # This test checks the previous_node and next_node methods that could not be
211
237
  # fully and properly checked in the NodeTest.rb file.
212
238
  def test_peers
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class ContainerNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class DocumentStyleTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class DocumentTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # FontTable class unit test class.
4
4
  class FontTableTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Font class unit test class.
4
4
  class FontTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class FooterNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class HeaderNodeTest < Test::Unit::TestCase
@@ -1,6 +1,6 @@
1
1
  $:.unshift(File.dirname(__FILE__)+"/../lib")
2
2
 
3
- require 'test_helper'
3
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
4
4
 
5
5
  # Colour class unit test class.
6
6
  class ImageNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class InformationTest < Test::Unit::TestCase
@@ -124,4 +124,4 @@ class InformationTest < Test::Unit::TestCase
124
124
  text << "\\hr#{time.hour}\\min#{time.min}}"
125
125
  text.string
126
126
  end
127
- end
127
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class NodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class ParagraphStyleTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class StyleTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class TableCellNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class TableNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class TableRowNodeTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.dirname(__FILE__)+'/test_helper')
2
2
 
3
3
  # Information class unit test class.
4
4
  class TextNodeTest < Test::Unit::TestCase
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clbustos-rtf
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 11
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 3
8
- - 1
9
- version: 0.3.1
8
+ - 4
9
+ - 2
10
+ version: 0.4.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Peter Wood
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-09-14 00:00:00 -04:00
18
+ date: 2010-11-23 00:00:00 -03:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -45,6 +46,7 @@ files:
45
46
  - lib/rtf/colour.rb
46
47
  - lib/rtf/font.rb
47
48
  - lib/rtf/information.rb
49
+ - lib/rtf/list.rb
48
50
  - lib/rtf/node.rb
49
51
  - lib/rtf/paper.rb
50
52
  - lib/rtf/style.rb
@@ -80,54 +82,58 @@ homepage: http://github.com/clbustos/rtf
80
82
  licenses: []
81
83
 
82
84
  post_install_message:
83
- rdoc_options:
84
- - --charset=UTF-8
85
+ rdoc_options: []
86
+
85
87
  require_paths:
86
88
  - lib
87
89
  required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
88
91
  requirements:
89
92
  - - ">="
90
93
  - !ruby/object:Gem::Version
94
+ hash: 3
91
95
  segments:
92
96
  - 0
93
97
  version: "0"
94
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
95
100
  requirements:
96
101
  - - ">="
97
102
  - !ruby/object:Gem::Version
103
+ hash: 3
98
104
  segments:
99
105
  - 0
100
106
  version: "0"
101
107
  requirements: []
102
108
 
103
109
  rubyforge_project: ruby-statsample
104
- rubygems_version: 1.3.6
110
+ rubygems_version: 1.3.7
105
111
  signing_key:
106
112
  specification_version: 3
107
113
  summary: Ruby library to create rich text format documents.
108
114
  test_files:
109
- - test/node_test.rb
110
- - test/information_test.rb
111
- - test/container_node_test.rb
112
- - test/table_cell_node_test.rb
115
+ - examples/example01.rb
116
+ - examples/example02.rb
117
+ - examples/example03.rb
118
+ - examples/example04.rb
113
119
  - test/character_style_test.rb
114
- - test/paragraph_style_test.rb
115
- - test/font_test.rb
116
- - test/document_test.rb
117
- - test/style_test.rb
118
- - test/font_table_test.rb
119
- - test/text_node_test.rb
120
- - test/table_node_test.rb
121
120
  - test/colour_table_test.rb
122
- - test/image_node_test.rb
121
+ - test/colour_test.rb
122
+ - test/command_node_test.rb
123
+ - test/container_node_test.rb
123
124
  - test/document_style_test.rb
124
- - test/test_helper.rb
125
+ - test/document_test.rb
126
+ - test/font_table_test.rb
127
+ - test/font_test.rb
125
128
  - test/footer_node_test.rb
126
- - test/table_row_node_test.rb
127
- - test/colour_test.rb
128
129
  - test/header_node_test.rb
129
- - test/command_node_test.rb
130
- - examples/example01.rb
131
- - examples/example02.rb
132
- - examples/example03.rb
133
- - examples/example04.rb
130
+ - test/image_node_test.rb
131
+ - test/information_test.rb
132
+ - test/node_test.rb
133
+ - test/paragraph_style_test.rb
134
+ - test/style_test.rb
135
+ - test/table_cell_node_test.rb
136
+ - test/table_node_test.rb
137
+ - test/table_row_node_test.rb
138
+ - test/test_helper.rb
139
+ - test/text_node_test.rb