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/doc/README
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
== Ruby Rich Text Format (RTF) Library 0.1.0
|
2
|
+
The RTF library provides a pure Ruby set of functionality that can be used to
|
3
|
+
programmatically create RTF documents. The main aim in developing this library
|
4
|
+
is to ease the complexity involved in assembling RTF documents although some
|
5
|
+
consideration has also been given to generating documents that are easier to
|
6
|
+
manually interpret too.
|
7
|
+
|
8
|
+
This library does not include functionality for parsing RTF documents. Nor does
|
9
|
+
the library claim to provide extensive coverage of the RTF specification. The
|
10
|
+
library was developed mostly with reference to the RTF Pocket Guide by Sean M.
|
11
|
+
Burke and some reference to the RTF specification itself. The introduction to
|
12
|
+
the RTF Pocket Guide states that the book covers version 1.7 of the RTF
|
13
|
+
specification so I guess, as this was the primary source, that this is the
|
14
|
+
version that the library covers too. Finally, no consideration was given to
|
15
|
+
making the functionality within the library thread safe.
|
16
|
+
|
17
|
+
In creating this library I set out to make it reasonably easy to create RTF
|
18
|
+
documents in code. Having said that I'm certain that it is possible to generate
|
19
|
+
invalid RTF documents with this library.
|
20
|
+
|
21
|
+
=== Known Issues
|
22
|
+
I've tried to assemble a reasonably extensive (although I won't claim
|
23
|
+
exhaustive) unit test for the library. Despite that, this is an early release of
|
24
|
+
the code and I'm sure there will be issues with it given the complexity inherent
|
25
|
+
in RTF. The following are issues that I'm already aware of with the library...
|
26
|
+
|
27
|
+
* The implementation of headers and footers is incomplete. Stick to using
|
28
|
+
universal headers and footers for the time being.
|
29
|
+
|
30
|
+
* The library makes no attempt to split large chunks of text into separate
|
31
|
+
lines. This can make editing the resulting document in a text editor a little
|
32
|
+
awkward.
|
33
|
+
|
34
|
+
* RTF is, when it comes down to it, a Microsoft standard. As a result I have
|
35
|
+
taken Word and Wordpad to be definitive when it comes to displaying the RTF
|
36
|
+
documents generated by the library. I have tried things like Abiword and
|
37
|
+
Open Office with varying degrees of success. I'm certainly not saying that
|
38
|
+
this is due to deficencies in these particular applications as it could
|
39
|
+
equally be a lack of my understanding of the RTF standard or problems with my
|
40
|
+
implementation. Still, I think I should mention the point that I don't get
|
41
|
+
consistent appearance across all of the RTF viewers I've tried.
|
42
|
+
|
43
|
+
=== To Do
|
44
|
+
This section details that areas where I feel the library is currently lacking
|
45
|
+
or incomplete. I hope to address the things detailed here in later releases of
|
46
|
+
the code.
|
47
|
+
|
48
|
+
* Check into RTF image handling with a view to adding support for the insertion
|
49
|
+
of images into a Document.
|
50
|
+
|
51
|
+
* Provide a complete implementation for the headers and footers.
|
52
|
+
|
53
|
+
=== Some Examples
|
54
|
+
Okay, so how is the library used. Well lets look at some examples to see if we
|
55
|
+
can cast a little light on the matter. The examples provided here assume that
|
56
|
+
you are already familiar with the Ruby language. So, for a start, consider...
|
57
|
+
|
58
|
+
require 'rubygems'
|
59
|
+
require 'rtf'
|
60
|
+
|
61
|
+
include RTF
|
62
|
+
|
63
|
+
The first thing to look at here at the are the first two lines. The RTF library
|
64
|
+
is provided as a Ruby gem and these two lines load the libraries functionality
|
65
|
+
into the script. The third line of code includes the RTF module into the current
|
66
|
+
name space. This is a convenience mechanism that saves on specifically having
|
67
|
+
to refer to the module when accessing the RTF library. Next we want to create
|
68
|
+
an RTF document and that is done like this...
|
69
|
+
|
70
|
+
document = Document.new(Font.new(Font::ROMAN, 'Times New Roman'))
|
71
|
+
|
72
|
+
This line of code creates a new Document object, specifying that the default
|
73
|
+
font for the document will the the Times New Roman font. So we have a document,
|
74
|
+
what can we do with it. Well, lets add a short paragraph of text...
|
75
|
+
|
76
|
+
document.paragraph << "This is a short paragraph of text."
|
77
|
+
|
78
|
+
That's fine, but what if we wanted to extend that paragraph or we simply wanted
|
79
|
+
to add more text than we've added here? Well, the paragraph method accepts a
|
80
|
+
block to which it passes the actual paragraph object, so we could do something
|
81
|
+
like the following...
|
82
|
+
|
83
|
+
document.paragraph do |p|
|
84
|
+
p << "This is the first sentence in the paragraph. "
|
85
|
+
p << "This is the second sentence in the paragraph. "
|
86
|
+
p << "And this is the third sentence in the paragraph."
|
87
|
+
end
|
88
|
+
|
89
|
+
This is a common approach used by the RTF library, allowing a block to define
|
90
|
+
the scope of a document element. Lets see a more complicated example of this
|
91
|
+
in which we apply a number of document effects. Lets say that we want to insert
|
92
|
+
some code into the document. We want the code to appear in the document slightly
|
93
|
+
indented on the left hand side, in a non-proportionately space font and we want
|
94
|
+
it in bold text. Heres the code that shows how to do that...
|
95
|
+
|
96
|
+
01 styles = {}
|
97
|
+
02 styles['PS_CODE'] = ParagraphStyle.new
|
98
|
+
03 styles['CS_CODE'] = CharacterStyle.new
|
99
|
+
04
|
100
|
+
05 styles['PS_CODE'].left_indent = 200
|
101
|
+
06 styles['CS_CODE'].font = Font.new(Font::MODERN, 'Courier')
|
102
|
+
07 styles['CS_CODE'].bold = true
|
103
|
+
08
|
104
|
+
09 document.paragraph(styles['PS_CODE']) do |n1|
|
105
|
+
10 n1.apply(styles['CS_CODE']) do |n2|
|
106
|
+
11 n2 << "count = 0"
|
107
|
+
12 n2.line_break
|
108
|
+
13 n2 << "File.open('file.txt', 'r') do |file|"
|
109
|
+
14 n2.line_break
|
110
|
+
15 n2 << " file.each_line {|line| count += 1}"
|
111
|
+
16 n2.line_break
|
112
|
+
17 n2 << "end"
|
113
|
+
18 n2.line_break
|
114
|
+
19 n2 << "puts \"File contains \#{count} lines.\""
|
115
|
+
20 end
|
116
|
+
21 end
|
117
|
+
|
118
|
+
This is a much larger piece of code and covers a number of topics that need to
|
119
|
+
be addressed. I have included line numbers with code so that individual elements
|
120
|
+
can be referenced. Lines 1 to 3 are the first new elements. Here we create a
|
121
|
+
Hash and assign it to a variable called styles. On the next two lines we create
|
122
|
+
two style objects, one that can be applied to paragraphs and one that applies
|
123
|
+
to characters.
|
124
|
+
|
125
|
+
On lines 5 to 7 we update settings on the style objects we've created. We set
|
126
|
+
the left indentation value of the paragraph style to 200. The 200 in this case
|
127
|
+
refers to a measurement of twips. A twip is a type setting measurement that
|
128
|
+
equates to one twentieth of a point (about a fifty seventh of a millimetre or
|
129
|
+
one seventy second of an inch). This is the measurement scale used by RTF
|
130
|
+
documents so it is also employed in the library.
|
131
|
+
|
132
|
+
On lines 6 and 7 we update the character style to use a courier font and to
|
133
|
+
apply bold styling to the text. On line 9 we start a new paragraph in our
|
134
|
+
document. This differs from our previous use of this method in that we specify
|
135
|
+
a style that will be applied to the paragraph created, the paragraph style we
|
136
|
+
had prepared earlier.
|
137
|
+
|
138
|
+
The block accompanying the paragraph method takes the single parameter that we
|
139
|
+
have seen previously. At this point its probably a good idea to point out that
|
140
|
+
the elements that make up an RTF document created with the library are all
|
141
|
+
stored as nodes in a tree. We've named the one passed to the paragraph method as
|
142
|
+
n1 to reflect this.
|
143
|
+
|
144
|
+
Within the block we've called a method on the paragraph node called apply. This
|
145
|
+
method applies a character style and we're using the one we prepared earlier.
|
146
|
+
Like the call to the paragraph method, the apply method is passed a block. All
|
147
|
+
text added to the blocks node (n2 in this case) will have the styling we've
|
148
|
+
defined (bold courier font) applied to it.
|
149
|
+
|
150
|
+
Note, that within the apply block we could still use the n1 node. Any text we
|
151
|
+
added to this would appear in the paragraph but wouldn't be styled and, it
|
152
|
+
should be noted, will appear before any text added to n2 (as the n2 node only
|
153
|
+
becomes part of the document when the apply block completes).
|
154
|
+
|
155
|
+
Within the apply method block we add some lines of text to the n2 node. Note
|
156
|
+
that, as this is all encompassed within the parapgraph block, all the text is
|
157
|
+
part of a single paragraph. To get each of the lines of code to appear on a
|
158
|
+
line of their own we have used the line_break method which inserts a carriage
|
159
|
+
return into the document. Note you should use this method to insert line breaks
|
160
|
+
rather than trying to add a string containing "\n". RTF is a text based standard
|
161
|
+
and won't treat "\n" as you're expecting. You should note also that we've had to
|
162
|
+
escape the '#' in one of the code lines to stop Ruby considering it as an
|
163
|
+
interpolated value.
|
164
|
+
|
165
|
+
Okay, so we've seen have the basics of creating a document and adding elements
|
166
|
+
to that document. How do we get what we've created to a file. Well thats
|
167
|
+
actually quite straight forward. As was mentioned previously, RTF is a text
|
168
|
+
based standard so you simply generate the RTF and write it to a file. Heres an
|
169
|
+
example...
|
170
|
+
|
171
|
+
File.open('my_document.rtf') {|file| file.write(document.to_rtf)}
|
172
|
+
|
173
|
+
There you have it. You've been given a quick overview of the basics of using
|
174
|
+
the library. For more information consult the HTML based API documentation that
|
175
|
+
is installed with the library gem (if you're reading this you may already be
|
176
|
+
looking at this documentation). Another source of information is the examples
|
177
|
+
directory, so check that out too.
|
data/doc/makedoc.bat
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rtf'
|
5
|
+
|
6
|
+
include RTF
|
7
|
+
|
8
|
+
# Create required styles.
|
9
|
+
styles = {}
|
10
|
+
styles['HEADER'] = CharacterStyle.new
|
11
|
+
styles['HEADER'].bold = true
|
12
|
+
styles['HEADER'].font_size = 28
|
13
|
+
styles['NORMAL'] = ParagraphStyle.new
|
14
|
+
styles['NORMAL'].justification = ParagraphStyle::FULL_JUSTIFY
|
15
|
+
styles['INDENTED'] = ParagraphStyle.new
|
16
|
+
styles['INDENTED'].left_indent = 400
|
17
|
+
|
18
|
+
document = Document.new(Font.new(Font::ROMAN, 'Arial'))
|
19
|
+
document.paragraph do |p|
|
20
|
+
p.apply(styles['HEADER']) do |s|
|
21
|
+
s << '1.0 Introduction'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
document.paragraph(styles['NORMAL']) do |p|
|
25
|
+
p << 'Here is a short example program in the Ruby programming '
|
26
|
+
p << 'language that demonstrates writing a single line of text '
|
27
|
+
p << 'to a file created in the current working directory...'
|
28
|
+
end
|
29
|
+
|
30
|
+
c = 1
|
31
|
+
document.paragraph(styles['INDENTED']) do |n1|
|
32
|
+
n1.line_break
|
33
|
+
n1.font(Font.new(Font::MODERN, 'Courier New')) do |n2|
|
34
|
+
n2 << "#{sprintf('%02d', c)} File.open('output.txt', 'w') do |file|"
|
35
|
+
c += 1
|
36
|
+
n2.line_break
|
37
|
+
n2 << "#{sprintf('%02d', c)} file.write('Some text.')"
|
38
|
+
c += 1
|
39
|
+
n2.line_break
|
40
|
+
n2 << "#{sprintf('%02d', c)} end"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
document.line_break
|
45
|
+
document.paragraph(styles['NORMAL']) do |p|
|
46
|
+
p << "And there you have it. A simple example indeed."
|
47
|
+
end
|
48
|
+
|
49
|
+
File.open('example01.rtf', 'w') do |file|
|
50
|
+
file.write(document.to_rtf)
|
51
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rtf'
|
5
|
+
|
6
|
+
include RTF
|
7
|
+
|
8
|
+
colours = [Colour.new(0, 0, 0),
|
9
|
+
Colour.new(255, 255, 255)]
|
10
|
+
|
11
|
+
# Create the used styles.
|
12
|
+
styles = {}
|
13
|
+
styles['EMPHASISED'] = CharacterStyle.new
|
14
|
+
styles['EMPHASISED'].bold = true
|
15
|
+
styles['EMPHASISED'].underline = true
|
16
|
+
styles['NORMAL'] = ParagraphStyle.new
|
17
|
+
styles['NORMAL'].space_after = 300
|
18
|
+
|
19
|
+
document = Document.new(Font.new(Font::ROMAN, 'Arial'))
|
20
|
+
|
21
|
+
document.paragraph(styles['NORMAL']) do |p|
|
22
|
+
p << 'This document is a simple programmatically generated file that is '
|
23
|
+
p << 'used to demonstrate table generation. A table containing 3 rows '
|
24
|
+
p << 'and three columns should be displayed below this text.'
|
25
|
+
end
|
26
|
+
|
27
|
+
table = document.table(3, 3, 2000, 4000, 2000)
|
28
|
+
table.border_width = 5
|
29
|
+
table[0][0] << 'Cell 0,0'
|
30
|
+
table[0][1].top_border_width = 10
|
31
|
+
table[0][1] << 'This is a little preamble text for '
|
32
|
+
table[0][1].apply(styles['EMPHASISED']) << 'Cell 0,1'
|
33
|
+
table[0][1].line_break
|
34
|
+
table[0][1] << ' to help in examining how formatting is working.'
|
35
|
+
table[0][2] << 'Cell 0,2'
|
36
|
+
table[1][0] << 'Cell 1,0'
|
37
|
+
table[1][1] << 'Cell 1,1'
|
38
|
+
table[1][2] << 'Cell 1,2'
|
39
|
+
table[2][0] << 'Cell 2,0'
|
40
|
+
table[2][1] << 'Cell 2,1'
|
41
|
+
table[2][2] << 'Cell 2,2'
|
42
|
+
|
43
|
+
File.open('example02.rtf', 'w') do |file|
|
44
|
+
file.write(document.to_rtf)
|
45
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rtf'
|
5
|
+
|
6
|
+
include RTF
|
7
|
+
|
8
|
+
fonts = [Font.new(Font::ROMAN, 'Times New Roman'),
|
9
|
+
Font.new(Font::MODERN, 'Courier')]
|
10
|
+
|
11
|
+
styles = {}
|
12
|
+
styles['PS_HEADING'] = ParagraphStyle.new
|
13
|
+
styles['PS_NORMAL'] = ParagraphStyle.new
|
14
|
+
styles['PS_NORMAL'].justification = ParagraphStyle::FULL_JUSTIFY
|
15
|
+
styles['PS_INDENTED'] = ParagraphStyle.new
|
16
|
+
styles['PS_INDENTED'].left_indent = 300
|
17
|
+
styles['PS_TITLE'] = ParagraphStyle.new
|
18
|
+
styles['PS_TITLE'].space_before = 100
|
19
|
+
styles['PS_TITLE'].space_after = 200
|
20
|
+
styles['CS_HEADING'] = CharacterStyle.new
|
21
|
+
styles['CS_HEADING'].bold = true
|
22
|
+
styles['CS_HEADING'].font_size = 36
|
23
|
+
styles['CS_CODE'] = CharacterStyle.new
|
24
|
+
styles['CS_CODE'].font = fonts[1]
|
25
|
+
styles['CS_CODE'].font_size = 16
|
26
|
+
|
27
|
+
document = Document.new(fonts[0])
|
28
|
+
|
29
|
+
document.paragraph(styles['PS_HEADING']) do |p1|
|
30
|
+
p1.apply(styles['CS_HEADING']) << 'Example Program'
|
31
|
+
end
|
32
|
+
|
33
|
+
document.paragraph(styles['PS_NORMAL']) do |p1|
|
34
|
+
p1 << 'This document is automatically generated using the RTF Ruby '
|
35
|
+
p1 << 'library by Peter Wood. This serves as an example of what can '
|
36
|
+
p1 << 'be achieved in document creation via the library. The source '
|
37
|
+
p1 << 'code that was used to generate it is listed below...'
|
38
|
+
end
|
39
|
+
|
40
|
+
document.paragraph(styles['PS_INDENTED']) do |p1|
|
41
|
+
n = 1
|
42
|
+
p1.apply(styles['CS_CODE']) do |p2|
|
43
|
+
File.open('example03.rb') do |file|
|
44
|
+
file.each_line do |line|
|
45
|
+
p2.line_break
|
46
|
+
p2 << "#{n > 9 ? '' : ' '}#{n} #{line.chomp}"
|
47
|
+
n += 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
document.paragraph(styles['PS_TITLE']) do |p1|
|
54
|
+
p1.italic do |p2|
|
55
|
+
p2.bold << 'Listing 1:'
|
56
|
+
p2 << ' Generator program code listing.'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
document.paragraph(styles['PS_NORMAL']) do |p1|
|
61
|
+
p1 << "This example shows the creation of a new document and the "
|
62
|
+
p1 << "of textual content to it. The example also provides examples "
|
63
|
+
p1 << "of using block scope to delimit style scope (lines 35-40)."
|
64
|
+
end
|
65
|
+
|
66
|
+
File.open('example03.rtf', 'w') {|file| file.write(document.to_rtf)}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
{\rtf1\ansi\deff0\deflang\plain\fs24
|
2
|
+
{\fonttbl
|
3
|
+
{\f0\froman Times New Roman;}
|
4
|
+
{\f1\fmodern Courier;}
|
5
|
+
}
|
6
|
+
{\info
|
7
|
+
{\createim\yr2005\mo11\dy8\hr15\min16}
|
8
|
+
}
|
9
|
+
{\pard\ql
|
10
|
+
{\b\fs36
|
11
|
+
Example Program
|
12
|
+
}
|
13
|
+
\par}
|
14
|
+
{\pard\qj
|
15
|
+
This document is automatically generated using the RTF Ruby library by Peter Wood. This serves as an example of what can be achieved in document creation via the library. The source code that was used to generate it is listed below...
|
16
|
+
\par}
|
17
|
+
{\pard\ql\li300
|
18
|
+
{\f1\fs16
|
19
|
+
{\line}
|
20
|
+
1 #!/usr/bin/env ruby
|
21
|
+
{\line}
|
22
|
+
2
|
23
|
+
{\line}
|
24
|
+
3 require 'rubygems'
|
25
|
+
{\line}
|
26
|
+
4 require 'rtf'
|
27
|
+
{\line}
|
28
|
+
5
|
29
|
+
{\line}
|
30
|
+
6 include RTF
|
31
|
+
{\line}
|
32
|
+
7
|
33
|
+
{\line}
|
34
|
+
8 fonts = [Font.new(Font::ROMAN, 'Times New Roman'),
|
35
|
+
{\line}
|
36
|
+
9 Font.new(Font::MODERN, 'Courier')]
|
37
|
+
{\line}
|
38
|
+
10
|
39
|
+
{\line}
|
40
|
+
11 styles = \{\}
|
41
|
+
{\line}
|
42
|
+
12 styles['PS_HEADING'] = ParagraphStyle.new
|
43
|
+
{\line}
|
44
|
+
13 styles['PS_NORMAL'] = ParagraphStyle.new
|
45
|
+
{\line}
|
46
|
+
14 styles['PS_NORMAL'].justification = ParagraphStyle::FULL_JUSTIFY
|
47
|
+
{\line}
|
48
|
+
15 styles['PS_INDENTED'] = ParagraphStyle.new
|
49
|
+
{\line}
|
50
|
+
16 styles['PS_INDENTED'].left_indent = 300
|
51
|
+
{\line}
|
52
|
+
17 styles['PS_TITLE'] = ParagraphStyle.new
|
53
|
+
{\line}
|
54
|
+
18 styles['PS_TITLE'].space_before = 100
|
55
|
+
{\line}
|
56
|
+
19 styles['PS_TITLE'].space_after = 200
|
57
|
+
{\line}
|
58
|
+
20 styles['CS_HEADING'] = CharacterStyle.new
|
59
|
+
{\line}
|
60
|
+
21 styles['CS_HEADING'].bold = true
|
61
|
+
{\line}
|
62
|
+
22 styles['CS_HEADING'].font_size = 36
|
63
|
+
{\line}
|
64
|
+
23 styles['CS_CODE'] = CharacterStyle.new
|
65
|
+
{\line}
|
66
|
+
24 styles['CS_CODE'].font = fonts[1]
|
67
|
+
{\line}
|
68
|
+
25 styles['CS_CODE'].font_size = 16
|
69
|
+
{\line}
|
70
|
+
26
|
71
|
+
{\line}
|
72
|
+
27 document = Document.new(fonts[0])
|
73
|
+
{\line}
|
74
|
+
28
|
75
|
+
{\line}
|
76
|
+
29 document.paragraph(styles['PS_HEADING']) do |p1|
|
77
|
+
{\line}
|
78
|
+
30 p1.apply(styles['CS_HEADING']) << 'Example Program'
|
79
|
+
{\line}
|
80
|
+
31 end
|
81
|
+
{\line}
|
82
|
+
32
|
83
|
+
{\line}
|
84
|
+
33 document.paragraph(styles['PS_NORMAL']) do |p1|
|
85
|
+
{\line}
|
86
|
+
34 p1 << 'This document is automatically generated using the RTF Ruby '
|
87
|
+
{\line}
|
88
|
+
35 p1 << 'library by Peter Wood. This serves as an example of what can '
|
89
|
+
{\line}
|
90
|
+
36 p1 << 'be achieved in document creation via the library. The source '
|
91
|
+
{\line}
|
92
|
+
37 p1 << 'code that was used to generate it is listed below...'
|
93
|
+
{\line}
|
94
|
+
38 end
|
95
|
+
{\line}
|
96
|
+
39
|
97
|
+
{\line}
|
98
|
+
40 document.paragraph(styles['PS_INDENTED']) do |p1|
|
99
|
+
{\line}
|
100
|
+
41 n = 1
|
101
|
+
{\line}
|
102
|
+
42 p1.apply(styles['CS_CODE']) do |p2|
|
103
|
+
{\line}
|
104
|
+
43 File.open('example03.rb') do |file|
|
105
|
+
{\line}
|
106
|
+
44 file.each_line do |line|
|
107
|
+
{\line}
|
108
|
+
45 p2.line_break
|
109
|
+
{\line}
|
110
|
+
46 p2 << "#\{n > 9 ? '' : ' '\}#\{n\} #\{line.chomp\}"
|
111
|
+
{\line}
|
112
|
+
47 n += 1
|
113
|
+
{\line}
|
114
|
+
48 end
|
115
|
+
{\line}
|
116
|
+
49 end
|
117
|
+
{\line}
|
118
|
+
50 end
|
119
|
+
{\line}
|
120
|
+
51 end
|
121
|
+
{\line}
|
122
|
+
52
|
123
|
+
{\line}
|
124
|
+
53 document.paragraph(styles['PS_TITLE']) do |p1|
|
125
|
+
{\line}
|
126
|
+
54 p1.italic do |p2|
|
127
|
+
{\line}
|
128
|
+
55 p2.bold << 'Listing 1:'
|
129
|
+
{\line}
|
130
|
+
56 p2 << ' Generator program code listing.'
|
131
|
+
{\line}
|
132
|
+
57 end
|
133
|
+
{\line}
|
134
|
+
58 end
|
135
|
+
{\line}
|
136
|
+
59
|
137
|
+
{\line}
|
138
|
+
60 document.paragraph(styles['PS_NORMAL']) do |p1|
|
139
|
+
{\line}
|
140
|
+
61 p1 << "This example shows the creation of a new document and the "
|
141
|
+
{\line}
|
142
|
+
62 p1 << "of textual content to it. The example also provides examples "
|
143
|
+
{\line}
|
144
|
+
63 p1 << "of using block scope to delimit style scope (lines 35-40)."
|
145
|
+
{\line}
|
146
|
+
64 end
|
147
|
+
{\line}
|
148
|
+
65
|
149
|
+
{\line}
|
150
|
+
66 File.open('example03.rtf', 'w') \{|file| file.write(document.to_rtf)\}
|
151
|
+
}
|
152
|
+
\par}
|
153
|
+
{\pard\ql\sb100\sa200
|
154
|
+
{\i
|
155
|
+
{\b
|
156
|
+
Listing 1:
|
157
|
+
}
|
158
|
+
Generator program code listing.
|
159
|
+
}
|
160
|
+
\par}
|
161
|
+
{\pard\qj
|
162
|
+
This example shows the creation of a new document and the of textual content to it. The example also provides examples of using block scope to delimit style scope (lines 35-40).
|
163
|
+
\par}
|
164
|
+
}
|