rtf 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/README +177 -0
- data/doc/makedoc.bat +2 -0
- data/examples/example01.rb +51 -0
- data/examples/example02.rb +45 -0
- data/examples/example03.rb +66 -0
- data/examples/example03.rtf +164 -0
- data/lib/rtf.rb +34 -0
- data/lib/rtf/colour.rb +173 -0
- data/lib/rtf/font.rb +173 -0
- data/lib/rtf/information.rb +112 -0
- data/lib/rtf/node.rb +1398 -0
- data/lib/rtf/paper.rb +55 -0
- data/lib/rtf/style.rb +305 -0
- data/test/CharacterStyleTest.rb +142 -0
- data/test/ColourTableTest.rb +98 -0
- data/test/ColourTest.rb +122 -0
- data/test/CommandNodeTest.rb +220 -0
- data/test/ContainerNodeTest.rb +70 -0
- data/test/DocumentStyleTest.rb +85 -0
- data/test/DocumentTest.rb +112 -0
- data/test/FontTableTest.rb +96 -0
- data/test/FontTest.rb +53 -0
- data/test/FooterNodeTest.rb +36 -0
- data/test/HeaderNodeTest.rb +36 -0
- data/test/InformationTest.rb +133 -0
- data/test/NodeTest.rb +31 -0
- data/test/ParagraphStyleTest.rb +87 -0
- data/test/StyleTest.rb +22 -0
- data/test/TableCellNodeTest.rb +95 -0
- data/test/TableNodeTest.rb +89 -0
- data/test/TableRowNodeTest.rb +65 -0
- data/test/TextNodeTest.rb +56 -0
- data/test/run.bat +2 -0
- data/test/unittest.bat +2 -0
- data/test/unittest.rb +21 -0
- metadata +78 -0
data/lib/rtf.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'rtf/font'
|
5
|
+
require 'rtf/colour'
|
6
|
+
require 'rtf/style'
|
7
|
+
require 'rtf/information'
|
8
|
+
require 'rtf/paper'
|
9
|
+
require 'rtf/node'
|
10
|
+
|
11
|
+
# This module encapsulates all the classes and definitions relating to the RTF
|
12
|
+
# library.
|
13
|
+
module RTF
|
14
|
+
# This is the exception class used by the RTF library code to indicate
|
15
|
+
# errors.
|
16
|
+
class RTFError < StandardError
|
17
|
+
# This is the constructor for the RTFError class.
|
18
|
+
#
|
19
|
+
# ==== Parameters
|
20
|
+
# message:: A reference to a string containing the error message for
|
21
|
+
# the exception defaults to nil.
|
22
|
+
def initialize(message=nil)
|
23
|
+
super(message == nil ? 'No error message available.' : message)
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method provides a short cut for raising RTFErrors.
|
27
|
+
#
|
28
|
+
# ==== Parameters
|
29
|
+
# message:: A string containing the exception message. Defaults to nil.
|
30
|
+
def RTFError.fire(message=nil)
|
31
|
+
raise RTFError.new(message)
|
32
|
+
end
|
33
|
+
end # End of the RTFError class.
|
34
|
+
end # End of the RTF module.
|
data/lib/rtf/colour.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
module RTF
|
6
|
+
# This class represents a colour within a RTF document.
|
7
|
+
class Colour
|
8
|
+
# Attribute accessor.
|
9
|
+
attr_reader :red, :green, :blue
|
10
|
+
|
11
|
+
|
12
|
+
# This is the constructor for the Colour class.
|
13
|
+
#
|
14
|
+
# ==== Parameters
|
15
|
+
# red:: The intensity setting for red in the colour. Must be an
|
16
|
+
# integer between 0 and 255.
|
17
|
+
# green:: The intensity setting for green in the colour. Must be an
|
18
|
+
# integer between 0 and 255.
|
19
|
+
# blue:: The intensity setting for blue in the colour. Must be an
|
20
|
+
# integer between 0 and 255.
|
21
|
+
#
|
22
|
+
# ==== Exceptions
|
23
|
+
# RTFError:: Generated whenever an invalid intensity setting is
|
24
|
+
# specified for the red, green or blue values.
|
25
|
+
def initialize(red, green, blue)
|
26
|
+
if red.kind_of?(Integer) == false || red < 0 || red > 255
|
27
|
+
RTFError.fire("Invalid red intensity setting ('#{red}') specified "\
|
28
|
+
"for a Colour object.")
|
29
|
+
end
|
30
|
+
if green.kind_of?(Integer) == false || green < 0 || green > 255
|
31
|
+
RTFError.fire("Invalid green intensity setting ('#{green}') "\
|
32
|
+
"specified for a Colour object.")
|
33
|
+
end
|
34
|
+
if blue.kind_of?(Integer) == false || blue < 0 || blue > 255
|
35
|
+
RTFError.fire("Invalid blue intensity setting ('#{blue}') "\
|
36
|
+
"specified for a Colour object.")
|
37
|
+
end
|
38
|
+
|
39
|
+
@red = red
|
40
|
+
@green = green
|
41
|
+
@blue = blue
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method overloads the comparison operator for the Colour class.
|
45
|
+
#
|
46
|
+
# ==== Parameters
|
47
|
+
# object:: A reference to the object to be compared with.
|
48
|
+
def ==(object)
|
49
|
+
object.instance_of?(Colour) &&
|
50
|
+
object.red == @red &&
|
51
|
+
object.green == @green &&
|
52
|
+
object.blue == @blue
|
53
|
+
end
|
54
|
+
|
55
|
+
# This method returns a textual description for a Colour object.
|
56
|
+
#
|
57
|
+
# ==== Parameters
|
58
|
+
# indent:: The number of spaces to prefix to the lines created by the
|
59
|
+
# method. Defaults to zero.
|
60
|
+
def to_s(indent=0)
|
61
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
62
|
+
"#{prefix}Colour (#{@red}/#{@green}/#{@blue})"
|
63
|
+
end
|
64
|
+
|
65
|
+
# This method generates the RTF text for a Colour object.
|
66
|
+
#
|
67
|
+
# ==== Parameters
|
68
|
+
# indent:: The number of spaces to prefix to the lines created by the
|
69
|
+
# method. Defaults to zero.
|
70
|
+
def to_rtf(indent=0)
|
71
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
72
|
+
"#{prefix}\\red#{@red}\\green#{@green}\\blue#{@blue};"
|
73
|
+
end
|
74
|
+
end # End of the Colour class.
|
75
|
+
|
76
|
+
|
77
|
+
# This class represents a table of colours used within a RTF document. This
|
78
|
+
# class need not be directly instantiated as it will be used internally by,
|
79
|
+
# and can be obtained from a Document object.
|
80
|
+
class ColourTable
|
81
|
+
# This is the constructor for the ColourTable class.
|
82
|
+
#
|
83
|
+
# ==== Parameters
|
84
|
+
# *colours:: An array of zero or more colours that make up the colour
|
85
|
+
# table entries.
|
86
|
+
def initialize(*colours)
|
87
|
+
@colours = []
|
88
|
+
colours.each {|colour| add(colour)}
|
89
|
+
end
|
90
|
+
|
91
|
+
# This method fetches a count of the number of colours within a colour
|
92
|
+
# table.
|
93
|
+
def size
|
94
|
+
@colours.size
|
95
|
+
end
|
96
|
+
|
97
|
+
# This method adds a new colour to a ColourTable object. If the colour
|
98
|
+
# already exists within the table or is not a Colour object then this
|
99
|
+
# method does nothing.
|
100
|
+
#
|
101
|
+
# ==== Parameters
|
102
|
+
# colour:: The colour to be added to the table.
|
103
|
+
def add(colour)
|
104
|
+
if colour.instance_of?(Colour)
|
105
|
+
@colours.push(colour) if @colours.index(colour) == nil
|
106
|
+
end
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
# This method iterates over the contents of a ColourTable object. This
|
111
|
+
# iteration does not include the implicit default colour entry.
|
112
|
+
def each
|
113
|
+
if block_given?
|
114
|
+
@colours.each {|colour| yield colour}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# This method overloads the array dereference operator for the ColourTable
|
119
|
+
# class. It is not possible to dereference the implicit default colour
|
120
|
+
# using this method. An invalid index will return a nil value.
|
121
|
+
#
|
122
|
+
# ==== Parameters
|
123
|
+
# index:: The index of the colour to be retrieved.
|
124
|
+
def [](index)
|
125
|
+
@colours[index]
|
126
|
+
end
|
127
|
+
|
128
|
+
# This method retrieves the index of a specified colour within the table.
|
129
|
+
# If the colour doesn't exist within the table then nil is returned. It
|
130
|
+
# should be noted that the index of a colour will be one more than its
|
131
|
+
# order of entry to account for the implicit default colour entry.
|
132
|
+
#
|
133
|
+
# ==== Parameters
|
134
|
+
# colour:: The colour to retrieve the index of.
|
135
|
+
def index(colour)
|
136
|
+
index = @colours.index(colour)
|
137
|
+
index == nil ? index : index + 1
|
138
|
+
end
|
139
|
+
|
140
|
+
# This method generates a textual description for a ColourTable object.
|
141
|
+
#
|
142
|
+
# ==== Parameters
|
143
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
144
|
+
# method. Defaults to zero.
|
145
|
+
def to_s(indent=0)
|
146
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
147
|
+
text = StringIO.new
|
148
|
+
|
149
|
+
text << "#{prefix}Colour Table (#{@colours.size} colours)"
|
150
|
+
@colours.each {|colour| text << "\n#{prefix} #{colour}"}
|
151
|
+
|
152
|
+
text.string
|
153
|
+
end
|
154
|
+
|
155
|
+
# This method generates the RTF text for a ColourTable object.
|
156
|
+
#
|
157
|
+
# ==== Parameters
|
158
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
159
|
+
# method. Defaults to zero.
|
160
|
+
def to_rtf(indent=0)
|
161
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
162
|
+
text = StringIO.new
|
163
|
+
|
164
|
+
text << "#{prefix}{\\colortbl\n#{prefix};"
|
165
|
+
@colours.each {|colour| text << "\n#{prefix}#{colour.to_rtf}"}
|
166
|
+
text << "\n#{prefix}}"
|
167
|
+
|
168
|
+
text.string
|
169
|
+
end
|
170
|
+
|
171
|
+
alias << add
|
172
|
+
end # End of the ColourTable class.
|
173
|
+
end # End of the RTF module.
|
data/lib/rtf/font.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
module RTF
|
6
|
+
# This class represents a font for use with some RTF content.
|
7
|
+
class Font
|
8
|
+
# A declaration for a font family. This family is used for monospaced
|
9
|
+
# fonts (e.g. Courier New).
|
10
|
+
MODERN = :modern
|
11
|
+
|
12
|
+
# A declaration for a font family. This family is used for proportionally
|
13
|
+
# spaced serif fonts (e.g. Arial, Times New Roman).
|
14
|
+
ROMAN = :roman
|
15
|
+
|
16
|
+
# A declaration for a font family. This family is used for proportionally
|
17
|
+
# spaced sans serif fonts (e.g. Tahoma, Lucida Sans).
|
18
|
+
SWISS = :swiss
|
19
|
+
|
20
|
+
# A declaration for a font family. This family is used where none of the
|
21
|
+
# other families apply.
|
22
|
+
NIL = 'nil'.intern
|
23
|
+
|
24
|
+
|
25
|
+
# Attribute accessor.
|
26
|
+
attr_reader :family, :name
|
27
|
+
|
28
|
+
|
29
|
+
# This is the constructor for the Font class.
|
30
|
+
#
|
31
|
+
# ==== Parameters
|
32
|
+
# family:: The font family for the new font. This should be one of
|
33
|
+
# Font::MODERN, Font::ROMAN, Font::SWISS or
|
34
|
+
# Font::NIL.
|
35
|
+
# name:: A string containing the font name.
|
36
|
+
#
|
37
|
+
# ==== Exceptions
|
38
|
+
# RTFError:: Generated whenever an invalid font family is specified.
|
39
|
+
def initialize(family, name)
|
40
|
+
# Check that a valid family has been provided.
|
41
|
+
if ![MODERN, ROMAN, SWISS, NIL].include?(family)
|
42
|
+
RTFError::fire("Unknown font family specified for Font object.")
|
43
|
+
end
|
44
|
+
@family = family
|
45
|
+
@name = name
|
46
|
+
end
|
47
|
+
|
48
|
+
# This method overloads the equivalence test operator for the Font class
|
49
|
+
# to allow for Font comparisons.
|
50
|
+
#
|
51
|
+
# ==== Parameters
|
52
|
+
# object:: A reference to the object to be compared with.
|
53
|
+
def ==(object)
|
54
|
+
object.instance_of?(Font) &&
|
55
|
+
object.family == @family &&
|
56
|
+
object.name == @name
|
57
|
+
end
|
58
|
+
|
59
|
+
# This method fetches a textual description for a Font object.
|
60
|
+
#
|
61
|
+
# ==== Parameters
|
62
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
63
|
+
# method. Defaults to zero.
|
64
|
+
def to_s(indent=0)
|
65
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
66
|
+
"#{prefix}Family: #{@family.id2name}, Name: #{@name}"
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method generates the RTF representation for a Font object as it
|
70
|
+
# would appear within a document font table.
|
71
|
+
#
|
72
|
+
# ==== Parameters
|
73
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
74
|
+
# method. Defaults to zero.
|
75
|
+
def to_rtf(indent=0)
|
76
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
77
|
+
"#{prefix}\\f#{@family.id2name} #{@name};"
|
78
|
+
end
|
79
|
+
end # End of the Font class.
|
80
|
+
|
81
|
+
|
82
|
+
# This class represents the font table for an RTF document. An instance of
|
83
|
+
# the class is used internally by the Document class and should not need to
|
84
|
+
# be explicitly instantiated (although it can be obtained from a Document
|
85
|
+
# object if needed).
|
86
|
+
class FontTable
|
87
|
+
# This is the constructor for the RTFTable class.
|
88
|
+
#
|
89
|
+
# ==== Parameters
|
90
|
+
# *fonts:: Zero or more font objects that are to be added to the font
|
91
|
+
# table. Objects that are not Fonts will be ignored.
|
92
|
+
def initialize(*fonts)
|
93
|
+
@fonts = []
|
94
|
+
fonts.each {|font| add(font)}
|
95
|
+
end
|
96
|
+
|
97
|
+
# This method is used to retrieve a count of the number of fonts held
|
98
|
+
# within an instance of the FontTable class.
|
99
|
+
def size
|
100
|
+
@fonts.size
|
101
|
+
end
|
102
|
+
|
103
|
+
# This method adds a font to a FontTable instance. This method returns
|
104
|
+
# a reference to the FontTable object updated.
|
105
|
+
#
|
106
|
+
# ==== Parameters
|
107
|
+
# font:: A reference to the font to be added. If this is not a Font
|
108
|
+
# object or already exists in the table it will be ignored.
|
109
|
+
def add(font)
|
110
|
+
if font.instance_of?(Font)
|
111
|
+
@fonts.push(font) if @fonts.index(font) == nil
|
112
|
+
end
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# This method iterates over the contents of a FontTable object. This
|
117
|
+
# method expects a block that takes a single parameter (the next font
|
118
|
+
# from the table).
|
119
|
+
def each
|
120
|
+
@fonts.each {|font| yield font} if block_given?
|
121
|
+
end
|
122
|
+
|
123
|
+
# This method overloads the array dereference operator for the FontTable
|
124
|
+
# class.
|
125
|
+
#
|
126
|
+
# ==== Parameters
|
127
|
+
# index:: The index into the font table of the font to be retrieved. If
|
128
|
+
# the index is invalid then nil is returned.
|
129
|
+
def [](index)
|
130
|
+
@fonts[index]
|
131
|
+
end
|
132
|
+
|
133
|
+
# This method fetches the index of a font within a FontTable object. If
|
134
|
+
# the font does not exist in the table then nil is returned.
|
135
|
+
#
|
136
|
+
# ==== Parameters
|
137
|
+
# font:: A reference to the font to check for.
|
138
|
+
def index(font)
|
139
|
+
@fonts.index(font)
|
140
|
+
end
|
141
|
+
|
142
|
+
# This method generates a textual description for a FontTable object.
|
143
|
+
#
|
144
|
+
# ==== Parameters
|
145
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
146
|
+
# method. Defaults to zero.
|
147
|
+
def to_s(indent=0)
|
148
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
149
|
+
text = StringIO.new
|
150
|
+
text << "#{prefix}Font Table (#{@fonts.size} fonts)"
|
151
|
+
@fonts.each {|font| text << "\n#{prefix} #{font}"}
|
152
|
+
text.string
|
153
|
+
end
|
154
|
+
|
155
|
+
# This method generates the RTF text for a FontTable object.
|
156
|
+
#
|
157
|
+
# ==== Parameters
|
158
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
159
|
+
# method. Defaults to zero.
|
160
|
+
def to_rtf(indent=0)
|
161
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
162
|
+
text = StringIO.new
|
163
|
+
text << "#{prefix}{\\fonttbl"
|
164
|
+
@fonts.each_index do |index|
|
165
|
+
text << "\n#{prefix}{\\f#{index}#{@fonts[index].to_rtf}}"
|
166
|
+
end
|
167
|
+
text << "\n#{prefix}}"
|
168
|
+
text.string
|
169
|
+
end
|
170
|
+
|
171
|
+
alias << add
|
172
|
+
end # End of the FontTable class.
|
173
|
+
end # End of the RTF module.
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'parsedate'
|
5
|
+
|
6
|
+
module RTF
|
7
|
+
# This class represents an information group for a RTF document.
|
8
|
+
class Information
|
9
|
+
# Attribute accessor.
|
10
|
+
attr_reader :title, :author, :company, :created, :comments
|
11
|
+
|
12
|
+
# Attribute mutator.
|
13
|
+
attr_writer :title, :author, :company, :comments
|
14
|
+
|
15
|
+
|
16
|
+
# This is the constructor for the Information class.
|
17
|
+
#
|
18
|
+
# ==== Parameters
|
19
|
+
# title:: A string containing the document title information. Defaults
|
20
|
+
# to nil.
|
21
|
+
# author:: A string containing the document author information.
|
22
|
+
# Defaults to nil.
|
23
|
+
# company:: A string containing the company name information. Defaults
|
24
|
+
# to nil.
|
25
|
+
# comments:: A string containing the information comments. Defaults to
|
26
|
+
# nil to indicate no comments.
|
27
|
+
# creation:: A Time object or a String that can be parsed into a Time
|
28
|
+
# object (using ParseDate) indicating the document creation
|
29
|
+
# date and time. Defaults to nil to indicate the current
|
30
|
+
# date and time.
|
31
|
+
#
|
32
|
+
# ==== Exceptions
|
33
|
+
# RTFError:: Generated whenever invalid creation date/time details are
|
34
|
+
# specified.
|
35
|
+
def initialize(title=nil, author=nil, company=nil, comments=nil, creation=nil)
|
36
|
+
@title = title
|
37
|
+
@author = author
|
38
|
+
@company = company
|
39
|
+
@comments = comments
|
40
|
+
self.created = (creation == nil ? Time.new : creation)
|
41
|
+
end
|
42
|
+
|
43
|
+
# This method provides the created attribute mutator for the Information
|
44
|
+
# class.
|
45
|
+
#
|
46
|
+
# ==== Parameters
|
47
|
+
# setting:: The new creation date/time setting for the object. This
|
48
|
+
# should be either a Time object or a string containing
|
49
|
+
# date/time details that can be parsed into a Time object
|
50
|
+
# (using the parsedate method).
|
51
|
+
#
|
52
|
+
# ==== Exceptions
|
53
|
+
# RTFError:: Generated whenever invalid creation date/time details are
|
54
|
+
# specified.
|
55
|
+
def created=(setting)
|
56
|
+
if setting.instance_of?(Time)
|
57
|
+
@created = setting
|
58
|
+
else
|
59
|
+
datetime = ParseDate::parsedate(setting.to_s)
|
60
|
+
if datetime == nil
|
61
|
+
RTFError.fire("Invalid document creation date/time information "\
|
62
|
+
"specified.")
|
63
|
+
end
|
64
|
+
@created = Time.local(datetime[0], datetime[1], datetime[2],
|
65
|
+
datetime[3], datetime[4], datetime[5])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method creates a textual description for an Information object.
|
70
|
+
#
|
71
|
+
# ==== Parameters
|
72
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
73
|
+
# method. Defaults to zero.
|
74
|
+
def to_s(indent=0)
|
75
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
76
|
+
text = StringIO.new
|
77
|
+
|
78
|
+
text << "#{prefix}Information"
|
79
|
+
text << "\n#{prefix} Title: #{@title}" if @title != nil
|
80
|
+
text << "\n#{prefix} Author: #{@author}" if @author != nil
|
81
|
+
text << "\n#{prefix} Company: #{@company}" if @company != nil
|
82
|
+
text << "\n#{prefix} Comments: #{@comments}" if @comments != nil
|
83
|
+
text << "\n#{prefix} Created: #{@created}" if @created != nil
|
84
|
+
|
85
|
+
text.string
|
86
|
+
end
|
87
|
+
|
88
|
+
# This method generates the RTF text for an Information object.
|
89
|
+
#
|
90
|
+
# ==== Parameters
|
91
|
+
# indent:: The number of spaces to prefix to the lines generated by the
|
92
|
+
# method. Defaults to zero.
|
93
|
+
def to_rtf(indent=0)
|
94
|
+
prefix = indent > 0 ? ' ' * indent : ''
|
95
|
+
text = StringIO.new
|
96
|
+
|
97
|
+
text << "#{prefix}{\\info"
|
98
|
+
text << "\n#{prefix}{\\title #{@title}}" if @title != nil
|
99
|
+
text << "\n#{prefix}{\\author #{@author}}" if @author != nil
|
100
|
+
text << "\n#{prefix}{\\company #{@company}}" if @company != nil
|
101
|
+
text << "\n#{prefix}{\\doccomm #{@comments}}" if @comments != nil
|
102
|
+
if @created != nil
|
103
|
+
text << "\n#{prefix}{\\createim\\yr#{@created.year}"
|
104
|
+
text << "\\mo#{@created.month}\\dy#{@created.day}"
|
105
|
+
text << "\\hr#{@created.hour}\\min#{@created.min}}"
|
106
|
+
end
|
107
|
+
text << "\n#{prefix}}"
|
108
|
+
|
109
|
+
text.string
|
110
|
+
end
|
111
|
+
end # End of the Information class.
|
112
|
+
end # End of the RTF module.
|