forked from thechrisoshow/rtf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.txt
201 lines (158 loc) · 8.81 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
= rtf
* https://github.com/clbustos/rtf
== Purpose of this fork
* [DONE] Add support for ordered and unordered lists
* [DONE] Add support for hyperlinks
* [DONE] Support for UTF8 text
* [TODO] Write comprehensive tests for OL and UL
* [TODO] Clean up the API
* [TODO] DRY the code
* [TODO] Add an HTML-to-RTF converter
Please, please, please: if you come along this library and would lend me an
hand to complete tests, please help. Thank you!
== DESCRIPTION:
The RTF library provides a pure Ruby set of functionality that can be used to
programmatically create RTF documents. The main aim in developing this library
is to ease the complexity involved in assembling RTF documents although some
consideration has also been given to generating documents that are easier to
manually interpret too.
This library does not include functionality for parsing RTF documents. Nor does
the library claim to provide extensive coverage of the RTF specification. The
library was developed mostly with reference to the RTF Pocket Guide by Sean M.
Burke and some reference to the RTF specification itself. The introduction to
the RTF Pocket Guide states that the book covers version 1.7 of the RTF
specification so I guess, as this was the primary source, that this is the
version that the library covers too. Finally, no consideration was given to
making the functionality within the library thread safe.
In creating this library I set out to make it reasonably easy to create RTF
documents in code. Having said that I'm certain that it is possible to generate
invalid RTF documents with this library.
=== FEATURES/PROBLEMS:
I've tried to assemble a reasonably extensive (although I won't claim
exhaustive) unit test for the library. Despite that, this is an early release of
the code and I'm sure there will be issues with it given the complexity inherent
in RTF. The following are issues that I'm already aware of with the library...
* The implementation of headers and footers is incomplete. Stick to using
universal headers and footers for the time being.
* The library makes no attempt to split large chunks of text into separate
lines. This can make editing the resulting document in a text editor a little
awkward.
* RTF is, when it comes down to it, a Microsoft standard. As a result I have
taken Word and Wordpad to be definitive when it comes to displaying the RTF
documents generated by the library. I have tried things like Abiword and
Open Office with varying degrees of success. I'm certainly not saying that
this is due to deficencies in these particular applications as it could
equally be a lack of my understanding of the RTF standard or problems with my
implementation. Still, I think I should mention the point that I don't get
consistent appearance across all of the RTF viewers I've tried.
=== To do
This section details that areas where I feel the library is currently lacking
or incomplete. I hope to address the things detailed here in later releases of
the code.
* Check into RTF image handling with a view to adding support for the insertion
of images into a Document.
* Provide a complete implementation for the headers and footers.
=== Some Examples
Okay, so how is the library used. Well lets look at some examples to see if we
can cast a little light on the matter. The examples provided here assume that
you are already familiar with the Ruby language. So, for a start, consider...
require 'rubygems'
require 'rtf'
The first thing to look at here at the are the first two lines. The RTF library
is provided as a Ruby gem and these two lines load the libraries functionality
into the script. The third line of code includes the RTF module into the current
name space. This is a convenience mechanism that saves on specifically having
to refer to the module when accessing the RTF library. Next we want to create
an RTF document and that is done like this...
document = RTF::Document.new(RTF::Font.new(RTF::Font::ROMAN, 'Times New Roman'))
This line of code creates a new Document object, specifying that the default
font for the document will the the Times New Roman font. So we have a document,
what can we do with it. Well, lets add a short paragraph of text...
document.paragraph << "This is a short paragraph of text."
That's fine, but what if we wanted to extend that paragraph or we simply wanted
to add more text than we've added here? Well, the paragraph method accepts a
block to which it passes the actual paragraph object, so we could do something
like the following...
document.paragraph do |p|
p << "This is the first sentence in the paragraph. "
p << "This is the second sentence in the paragraph. "
p << "And this is the third sentence in the paragraph."
end
This is a common approach used by the RTF library, allowing a block to define
the scope of a document element. Lets see a more complicated example of this
in which we apply a number of document effects. Lets say that we want to insert
some code into the document. We want the code to appear in the document slightly
indented on the left hand side, in a non-proportionately space font and we want
it in bold text. Heres the code that shows how to do that...
01 code_para = ParagraphStyle.new
02 code_para.left_indent = 200
03
04 code_char = CharacterStyle.new
05 code_char.font = RTF::Font::MODERN
06 code_char.bold = true
07
08 document.paragraph(code_para) do |p|
09 p.apply(code_char) do |c|
10 c << "count = 0"
11 c.line_break
12 c << "File.open('file.txt', 'r') do |file|"
13 c.line_break
14 c << " file.each_line {|line| count += 1}"
15 c.line_break
16 c << "end"
17 c.line_break
18 c << "puts \"File contains \#{count} lines.\""
19 end
20 end
This is a much larger piece of code and covers a number of topics that need to
be addressed. I have included line numbers with code so that individual elements
can be referenced. Lines 1 to 6 are the first new elements. Here we create
two style objects, one that can be applied to paragraphs and one that applies
to characters.
On line 2 we set the left indentation value of the paragraph style to 200 *twips*.
A twip is a type setting measurement that equates to one twentieth of a point
(about a fifty seventh of a millimetre or one seventy second of an inch). This is
the measurement scale used by RTF documents.
On lines 5 and 6 we update the character style to use a courier font and to
apply bold styling to the text.
On line 8 we start a new paragraph in our document. This differs from our previous
use of this method in that we specify a style that will be applied to the paragraph
using the one we prepared earlier.
The block accompanying the paragraph method takes the single parameter that we
have seen previously. At this point its probably a good idea to point out that
the elements that make up an RTF document created with the library are all
stored as nodes in a tree.
Within the block, the +apply+ method applies a character style, and we're using
the one we prepared earlier.
Like the call to the paragraph method, the apply method is passed a block. All
text added to the blocks node will have the styling we've defined (bold courier
font) applied to it.
Note, that within the apply block we could still use the previous (p) node. Any
text we added to this would appear in the paragraph but wouldn't be styled and,
it should be noted, will appear before any text added to c, as the c node only
becomes part of the document when the apply block completes.
Within the apply method block we add some lines of text to the c node. Note
that, as this is all encompassed within the parapgraph block, all the text is
part of a single paragraph. To get each of the lines of code to appear on a
line of their own we have used the line_break method which inserts a carriage
return into the document. Note you should use this method to insert line breaks
rather than trying to add a string containing "\n". RTF is a text based standard
and won't treat "\n" as you're expecting.
Okay, so we've seen have the basics of creating a document and adding elements
to that document. How do we get what we've created to a file. Well thats
actually quite straight forward. As was mentioned previously, RTF is a text
based standard so you simply generate the RTF and write it to a file. Heres an
example...
File.open('my_document.rtf') {|file| file.write(document.to_rtf)}
There you have it. You've been given a quick overview of the basics of using
the library. For more information consult the HTML based API documentation that
is installed with the library gem (if you're reading this you may already be
looking at this documentation). Another source of information is the examples
directory, so check that out too.
== CONTRIBUTORS
* Marcello Barnaba
* Claudio Bustos
* Sam Mullen
* Chris O'Sullivan
== COPYRIGHT
Copyright (c) 2009-2012 Peter Wood. See LICENSE for details.