picture of Sujith Nair
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:
  1. The whole RTF file is enclosed in braces that is, with in "{" and "}".
  2. "{" is followed by the header part. Basic syntax for it is - \rtf <charset> \deff <fonttbl> <filetbl> <colortbl> <stylesheet> <listtables> <revtbl>
  3. Now after the header part, comes the info part. It is embedded in "{\info" and "}". Within this we have "\title", "\author", "\operator" etc.
  4. 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.
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