Recently, I had a brief stint with RTF (Rich Text Format)
files. I had to write an RTF file
and send an RTF file as attachment in mail. Initially it was a pain to understand the RTF
file format. Its header
part was apparently the most confusing part. But when I had some
understanding of the header,
the remaining task was not that difficult. Here, I am not going to
provide you with codes for
writing an RTF, but I'll help you understand how this can be achieved.
Once this is clear, you
can write your own class to write an RTF, or for that matter convert a
file to RTF.
First, I wished to have a first hand idea of how an RTF source looks
like for a simple string like,
"PHP for rich text format". Hold your breath, here it is....
{\rtf1\ansi\ansicpg1252\uc1
\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2
{\*\panose 02020603050405020304}Times New
Roman;}{\f16\froman\fcharset238\fprq2 Times New Roman CE;}
{\f17\froman\fcharset204\fprq2 Times New Roman
Cyr;}{\f19\froman\fcharset161\fprq2 Times New Roman Greek;}
{\f20\froman\fcharset162\fprq2 Times New Roman
Tur;}{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;
\red0\green255\blue0;
\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
\red255\green255\blue255;
\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
\red128\green0\blue128;
\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
\red192\green192\blue192;}
{\stylesheet{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}{\*\cs10
\additive Default Paragraph Font;}}
{\info{\title PHP for rich text format}{\author sujith nair}{\operator
naukri.com}
{\creatim\yr2002\mo5\dy3\hr17\min21}{\revtim\yr2002\mo5\dy3\hr17\min21}
{\version1}{\edmins0}{\nofpages1}
{\nofwords0}{\nofchars0}{\*\company Info Edge (I) Pvt
Ltd}{\nofcharsws0}{\vern89}}
\widowctrl\ftnbj\aenddoc\formshade\viewkind1\viewscale100
\pgbrdrhead\pgbrdrfoot
\fet0\sectd
\linex0\endnhere\sectdefaultcl
{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}
{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta
.}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang
{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta
)}}{\*\pnseclvl5\pndec\pnstart1
\pnindent720\pnhang{\pntxtb (}{\pntxta
)}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb
(}{\pntxta )}}{\*\pnseclvl8\pnlcltr
\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta
)}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang
{\pntxtb (}{\pntxta )}}\pard\plain \widctlpar\adjustright \fs20\cgrid
{PHP for rich text format\par }}
(Please note that I have purposely added line brakes in the above RTF
source
for formatting.)
I was interested only in
the generic syntax of header
and the document part, I decided to ignore the rest of it.
What I
understood from this was:
- The whole RTF file is enclosed in braces that is, with in "{" and
"}".
- "{" is followed by the header part. Basic syntax for it is -
\rtf <charset> \deff <fonttbl> <filetbl> <colortbl> <stylesheet>
<listtables> <revtbl>
- Now after the header part, comes the info part. It is embedded in
"{\info" and "}".
Within this we have "\title", "\author", "\operator" etc.
- After the general information comes the data or content, like "{PHP
for rich text format\par }".
Now I was ready to play with RTF. I had to write RTF files on the fly
based an search results
from a database. I thought, it would be easy for me to develop a
template for an RTF file. After
having the template in place I would simply insert the variables before
writing the whole stuff
to an RTF file. I was happy and content. But it didn't last long. My
clients further demanded
that they should be able to do simple text formatting, on the fly.
Ahm..now what ? I discovered
that formatting in RTF isn't difficult either. Like for <bold> letter,
all we have to do is insert
"\b" before the text you wish to see in bold. But, we have to be careful
about the scope of these
actions. For instance, if I have to see "PHP" of the string "PHP for
rich text format" in bold, all
I have to do is, modify it as:
\cgrid {\b PHP }{ for rich text format
Again, if I have to make "PHP" bold and red as well, all I will do is
modify it as:
\cgrid {\b\cf6 PHP }{ for rich text format
Here "\cf6"
represents red colour. One thing that
is to be taken care of is the scope for every control (viz, \b). It
should be well defined within braces.
Another alternative for defining the scope is by closing the control
with a '0'. That is,
when such a control word (like \b) has no parameter or has a nonzero
parameter (like \b1), it is assumed
that the control word turns on the property. When such a control word
has a parameter of 0 (like \b0),
it is assumed that the control word turns off the property. For example,
\b turns on bold, whereas \b0
turns off bold. It's not over yet. The most important part is, we have to
take care of all the "\n", "\r"
and "\t"s in the document. Best way to deal with it is to escape all
"\"s preceding 'r','n' and 't' before
writing to a file. For newlines we can make use of "\par".
Now I was left with only one thing: to send email attachment of RTF
files. After I
was able to write an RTF file, it didn't seem difficult. All I did
was define a
Content-Type of "multipart/mixed" as parent, "text/plain" for message
and "text/rtf" for
the attachment. I will show you how.
<?php
// the preceding part of the mail remains as same as that of a normal
// mail.
fputs($fd, "Content-Type: multipart/mixed; boundary=$boundry \n\n");
fputs($fd, "Content-Transfer-Encoding: 7bit \n");
fputs($fd, "This is a multi-part message in MIME format \n\n");
fputs($fd, "--$boundry \n");
fputs($fd, "Content-type: text/plain; charset=us-ascii \n");
fputs($fd, "Content-Transfer-Encoding: 7bit \n");
fputs($fd, "\n");
fputs($fd, " message is this\n"); // message goes here
fputs($fd, "--$boundry \n");
fputs($fd, "Content-type: application/rtf; charset=us-ascii \n");
fputs($fd, "Content-Transfer-Encoding: 7bit \n");
fputs($fd, "Content-Disposition: inline; filename=\"mailer.rtf\" \n");
fputs($fd, "Content-Base: \"file///c|/temp/mailer.rtf\" \r\n\r\n");
// the succeeding part of the mail remains as same as that of a normal
// mail.
?>
Here are some of the syntaxes for formatting text.
- \b = Bold
- \caps = All capitals.
- \i = Italic.
- \outl = Outline.
- \scaps = Small capitals.
- \strike = Strikethrough.
- \ul = Continuous underline.
- \ul0 = turns off all underlining.
- \ulnone = Stops all underlining.
- \cfN = Foreground color (the default is 0).
- \cbN = Background color (the default is 0).
- \rtlch = The character data following this control word will be treated
as a right-to-left run.
- \ltrch = The character data following this control word will be treated
as a left-to-right run (the default).
- \csN = Designates character style. If a character style is specified,
style properties must be specified with
the character run. N refers to an entry in the style table.
- \cchsN = Indicates any characters not belonging to the default document
character set and tells
which character set they do belong to. Macintosh character sets are
represented by values greater than 255.
The values for N correspond to the values for the \ fcharset control
word.
- \langN = Applies a language to a character. N is a number corresponding
to a language. The \plain control
word resets the language property to the language defined by \deflangN
in the document properties.
There are more of them, but for this I would suggest you go through an
RTF tutorial.
It's easy ... isn't it? Only if you don't have to complete all this in a
couple of hours ;-)
Many of you will conclude that its not worth going through the RTF
source. Best way to go
about it is to develop predefined templates. But what about flexibility.
What if the client
asks for changes in format, or flexibility in format. I think there is
no harm in spending a
little time understanding the very basics of your work before you start
with it, rather than
revisiting it after most of it has been done. Then it becomes really
difficult to work over
it or do the research work in a short span of time.
--Sujith Nair