Rtfactn.c contains the tables describing the properties and control words, and the routines to evaluate properties (ecApplyPropChange) and to dispatch control words (ecTranslateKeyword).
The tables are the keys to understanding the RTF dispatch routines. The following are some sample entries from both tables, along with a brief explanation of each entry.
The Property Table. This table must have an entry for every iprop.
actnByte, propChp, offsetof(CHP, fBold), // ipropBold
This property says that the ipropBold property is a byte parameter bound to chp.fBold.
actnWord, propPap, offsetof(PAP, xaRight), // ipropRightInd
This property says that ipropRightInd is a word parameter bound to pap.xaRight.
actnWord, propSep, offsetof(SEP, cCols), // ipropCols
This property says that ipropCols is a word parameter bound to sep.cCols.
actnSpec, propChp, 0, // ipropPlain
This property says that ipropPlain is a special parameter. Instead of directly evaluating it, ecApplyPropChange will run some custom C code to apply a property change.
The Control Word Table.
"b", 1, fFalse, kwdProp, ipropBold,
This structure says that the control \b sets the ipropBold property. Because fPassDflt is False, the reader only uses the default value if the control does not have a parameter. If no parameter is provided, the reader uses a value of 1.
"sbknone", sbkNon, fTrue, kwdProp, ipropSbk,
This entry says that the control \sbknone sets the ipropSbk property. Because fPassDflt is True, the reader always uses the default value of sbkNon, even if the control has a parameter.
"par", 0, fFalse, kwdChar, 0x0a,
This entry says that the control \par is equivalent to a 0x0a (linefeed) character.
"tab", 0, fFalse, kwdChar, 0x09,
This entry says that the control \tab is equivalent to a 0x09 (tab) character.
"bin", 0, fFalse, kwdSpec, ipfnBin,
This entry says that the control \bin should run some C code. The particular piece of C code can be located by the ipfnBin parameter.
"fonttbl", 0, fFalse, kwdDest, idestSkip,
This entry says that the control \fonttbl should change to the destination idestSkip.