2 * text-writer -- RTF-to-text translation writer code.
4 * Read RTF input, write text of document (text extraction).
6 * Wrapper must call WriterInit() once before processing any files,
7 * then set up input and call BeginFile() for each input file.
9 * This installs callbacks for the text and control token classes.
10 * The control class is necessary so that special characters such as
11 * \par, \tab, \sect, etc. can be converted.
13 * It's problematic what to do with text in headers and footers, and
14 * what to do about tables.
16 * This really is quite a stupid program, for instance, it could keep
17 * track of the current leader character and dump that out when a tab
20 * 04 Feb 91 Paul DuBois dubois@primate.wisc.edu
22 * This software may be redistributed without restriction and used for
23 * any purpose whatsoever.
28 * - Updated for distribution 1.05.
30 * - Updated to compile under THINK C 6.0.
32 * - Added Mike Sendall's entries for Macintosh char map.
34 * - Uses charset map and output sequence map for character translation.
36 * - Updated for 1.10 distribution.
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(richedit
);
47 static void TextClass (RTF_Info
*info
);
48 static void ControlClass (RTF_Info
*info
);
49 static void Destination (RTF_Info
*info
);
50 static void SpecialChar (RTF_Info
*info
);
51 static void PutStdChar (RTF_Info
*info
, int stdCode
);
52 static void PutLitChar (RTF_Info
*info
, int c
);
53 static void PutLitStr (RTF_Info
*info
, char *s
);
56 * Initialize the writer.
60 WriterInit (RTF_Info
*info
)
62 RTFReadOutputMap (info
, info
->outMap
,1);
67 BeginFile (RTF_Info
*info
)
69 /* install class callbacks */
71 RTFSetClassCallback (info
, rtfText
, TextClass
);
72 RTFSetClassCallback (info
, rtfControl
, ControlClass
);
79 * Write out a character. rtfMajor contains the input character, rtfMinor
80 * contains the corresponding standard character code.
82 * If the input character isn't in the charset map, try to print some
83 * representation of it.
87 TextClass (RTF_Info
*info
)
93 if (info
->rtfFormat
== SF_TEXT
)
94 PutLitChar (info
, info
->rtfMajor
);
95 else if (info
->rtfMinor
!= rtfSC_nothing
)
96 PutStdChar (info
, info
->rtfMinor
);
99 if (info
->rtfMajor
< 128) /* in ASCII range */
100 sprintf (buf
, "[[%c]]", info
->rtfMajor
);
102 sprintf (buf
, "[[\\'%02x]]", info
->rtfMajor
);
103 PutLitStr (info
, buf
);
109 ControlClass (RTF_Info
*info
)
112 switch (info
->rtfMajor
)
125 * This function notices destinations that should be ignored
126 * and skips to their ends. This keeps, for instance, picture
127 * data from being considered as plain text.
131 Destination (RTF_Info
*info
)
136 switch (info
->rtfMinor
)
140 case rtfFNContNotice
:
158 * The reason these use the rtfSC_xxx thingies instead of just writing
159 * out ' ', '-', '"', etc., is so that the mapping for these characters
160 * can be controlled by the text-map file.
163 void SpecialChar (RTF_Info
*info
)
168 switch (info
->rtfMinor
)
175 PutLitChar (info
, '\n');
178 PutStdChar (info
, rtfSC_space
); /* make sure cells are separated */
181 PutStdChar (info
, rtfSC_nobrkspace
);
184 PutLitChar (info
, '\t');
187 PutStdChar (info
, rtfSC_nobrkhyphen
);
190 PutStdChar (info
, rtfSC_bullet
);
193 PutStdChar (info
, rtfSC_emdash
);
196 PutStdChar (info
, rtfSC_endash
);
199 PutStdChar (info
, rtfSC_quoteleft
);
202 PutStdChar (info
, rtfSC_quoteright
);
205 PutStdChar (info
, rtfSC_quotedblleft
);
208 PutStdChar (info
, rtfSC_quotedblright
);
215 * Eventually this should keep track of the destination of the
216 * current state and only write text when in the initial state.
218 * If the output sequence is unspecified in the output map, write
219 * the character's standard name instead. This makes map deficiencies
220 * obvious and provides incentive to fix it. :-)
223 void PutStdChar (RTF_Info
*info
, int stdCode
)
226 char *oStr
= (char *) NULL
;
229 /* if (stdCode == rtfSC_nothing)
230 RTFPanic ("Unknown character code, logic error\n");
234 oStr
= info
->outMap
[stdCode
];
235 if (oStr
== (char *) NULL
) /* no output sequence in map */
237 sprintf (buf
, "[[%s]]", RTFStdCharName (info
, stdCode
));
240 PutLitStr (info
, oStr
);
243 void PutLitChar (RTF_Info
*info
, int c
)
245 if( info
->dwOutputCount
>= ( sizeof info
->OutputBuffer
- 1 ) )
246 RTFFlushOutputBuffer( info
);
247 info
->OutputBuffer
[info
->dwOutputCount
++] = c
;
250 void RTFFlushOutputBuffer( RTF_Info
*info
)
252 info
->OutputBuffer
[info
->dwOutputCount
] = 0;
253 SendMessageA( info
->hwndEdit
, EM_REPLACESEL
, FALSE
, (LPARAM
) info
->OutputBuffer
);
254 info
->dwOutputCount
= 0;
257 static void PutLitStr (RTF_Info
*info
, char *str
)
259 int len
= strlen( str
);
260 if( ( len
+ info
->dwOutputCount
+ 1 ) > sizeof info
->OutputBuffer
)
261 RTFFlushOutputBuffer( info
);
262 if( ( len
+ 1 ) >= sizeof info
->OutputBuffer
)
264 SendMessageA( info
->hwndEdit
, EM_REPLACESEL
, FALSE
, (LPARAM
) str
);
267 strcpy( &info
->OutputBuffer
[info
->dwOutputCount
], str
);
268 info
->dwOutputCount
+= len
;