source: trunk/src/riched32/textwriter.c@ 21308

Last change on this file since 21308 was 21308, checked in by ydario, 16 years ago

Minor updates, backout imm changes.

File size: 5.7 KB
Line 
1/*
2 * text-writer -- RTF-to-text translation writer code.
3 *
4 * Read RTF input, write text of document (text extraction).
5 *
6 * Wrapper must call WriterInit() once before processing any files,
7 * then set up input and call BeginFile() for each input file.
8 *
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.
12 *
13 * It's problematic what to do with text in headers and footers, and
14 * what to do about tables.
15 *
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
18 * is encountered.
19 *
20 * 04 Feb 91 Paul DuBois dubois@primate.wisc.edu
21 *
22 * This software may be redistributed without restriction and used for
23 * any purpose whatsoever.
24 *
25 * 04 Feb 91
26 * -Created.
27 * 27 Feb 91
28 * - Updated for distribution 1.05.
29 * 13 Jul 93
30 * - Updated to compile under THINK C 6.0.
31 * 31 Aug 93
32 * - Added Mike Sendall's entries for Macintosh char map.
33 * 07 Sep 93
34 * - Uses charset map and output sequence map for character translation.
35 * 11 Mar 94
36 * - Updated for 1.10 distribution.
37 */
38
39#include <stdio.h>
40
41#include "rtf.h"
42#include "rtf2text.h"
43#include "charlist.h"
44#include "wine/debug.h"
45
46WINE_DEFAULT_DEBUG_CHANNEL(richedit);
47
48#ifdef __WIN32OS2__ /* no useful trace in this file! */
49#define TRACE(a) do {} while (0)
50#endif
51
52static void TextClass ();
53static void ControlClass ();
54static void Destination ();
55static void SpecialChar ();
56static void PutStdChar ();
57static void PutLitChar ();
58static void PutLitStr ();
59
60static char *outMap[rtfSC_MaxChar];
61
62static CHARLIST charlist = {0, NULL, NULL};
63
64int RTFToBuffer(char* pBuffer, int nBufferSize);
65int RTFToBuffer(char* pBuffer, int nBufferSize)
66{
67
68 /* check if the buffer is big enough to hold all characters */
69 /* we require one more for the '\0' */
70
71 TRACE("\n");
72
73 if(nBufferSize < charlist.nCount + 1) {
74 return charlist.nCount + CHARLIST_CountChar(&charlist, '\n') + 1;
75 }
76
77 while(charlist.nCount)
78 {
79 *pBuffer = CHARLIST_Dequeue(&charlist);
80 if(*pBuffer=='\n')
81 {
82 *pBuffer = '\r';
83 pBuffer++;
84 *pBuffer = '\n';
85 }
86 pBuffer++;
87 }
88 *pBuffer = '\0';
89
90 return 0;
91}
92
93
94/*
95 * Initialize the writer.
96 */
97
98void
99WriterInit ()
100{
101 RTFReadOutputMap (outMap,1);
102}
103
104
105int
106BeginFile ()
107{
108 /* install class callbacks */
109
110 RTFSetClassCallback (rtfText, TextClass);
111 RTFSetClassCallback (rtfControl, ControlClass);
112
113 return (1);
114}
115
116
117/*
118 * Write out a character. rtfMajor contains the input character, rtfMinor
119 * contains the corresponding standard character code.
120 *
121 * If the input character isn't in the charset map, try to print some
122 * representation of it.
123 */
124
125static void
126TextClass ()
127{
128char buf[rtfBufSiz];
129
130 TRACE("\n");
131
132 if (rtfFormat == SF_TEXT)
133 PutLitChar (rtfMajor);
134 else if (rtfMinor != rtfSC_nothing)
135 PutStdChar (rtfMinor);
136 else
137 {
138 if (rtfMajor < 128) /* in ASCII range */
139 sprintf (buf, "[[%c]]", rtfMajor);
140 else
141 sprintf (buf, "[[\\'%02x]]", rtfMajor);
142 PutLitStr (buf);
143 }
144}
145
146
147static void
148ControlClass ()
149{
150 TRACE("\n");
151 switch (rtfMajor)
152 {
153 case rtfDestination:
154 Destination ();
155 break;
156 case rtfSpecialChar:
157 SpecialChar ();
158 break;
159 }
160}
161
162
163/*
164 * This function notices destinations that should be ignored
165 * and skips to their ends. This keeps, for instance, picture
166 * data from being considered as plain text.
167 */
168
169static void
170Destination ()
171{
172
173 TRACE("\n");
174
175 switch (rtfMinor)
176 {
177 case rtfPict:
178 case rtfFNContSep:
179 case rtfFNContNotice:
180 case rtfInfo:
181 case rtfIndexRange:
182 case rtfITitle:
183 case rtfISubject:
184 case rtfIAuthor:
185 case rtfIOperator:
186 case rtfIKeywords:
187 case rtfIComment:
188 case rtfIVersion:
189 case rtfIDoccomm:
190 RTFSkipGroup ();
191 break;
192 }
193}
194
195
196/*
197 * The reason these use the rtfSC_xxx thingies instead of just writing
198 * out ' ', '-', '"', etc., is so that the mapping for these characters
199 * can be controlled by the text-map file.
200 */
201
202void SpecialChar ()
203{
204
205 TRACE("\n");
206
207 switch (rtfMinor)
208 {
209 case rtfPage:
210 case rtfSect:
211 case rtfRow:
212 case rtfLine:
213 case rtfPar:
214 PutLitChar ('\n');
215 break;
216 case rtfCell:
217 PutStdChar (rtfSC_space); /* make sure cells are separated */
218 break;
219 case rtfNoBrkSpace:
220 PutStdChar (rtfSC_nobrkspace);
221 break;
222 case rtfTab:
223 PutLitChar ('\t');
224 break;
225 case rtfNoBrkHyphen:
226 PutStdChar (rtfSC_nobrkhyphen);
227 break;
228 case rtfBullet:
229 PutStdChar (rtfSC_bullet);
230 break;
231 case rtfEmDash:
232 PutStdChar (rtfSC_emdash);
233 break;
234 case rtfEnDash:
235 PutStdChar (rtfSC_endash);
236 break;
237 case rtfLQuote:
238 PutStdChar (rtfSC_quoteleft);
239 break;
240 case rtfRQuote:
241 PutStdChar (rtfSC_quoteright);
242 break;
243 case rtfLDblQuote:
244 PutStdChar (rtfSC_quotedblleft);
245 break;
246 case rtfRDblQuote:
247 PutStdChar (rtfSC_quotedblright);
248 break;
249 }
250}
251
252
253/*
254 * Eventually this should keep track of the destination of the
255 * current state and only write text when in the initial state.
256 *
257 * If the output sequence is unspecified in the output map, write
258 * the character's standard name instead. This makes map deficiencies
259 * obvious and provides incentive to fix it. :-)
260 */
261
262void PutStdChar (int stdCode)
263{
264
265 char *oStr = (char *) NULL;
266 char buf[rtfBufSiz];
267
268/* if (stdCode == rtfSC_nothing)
269 RTFPanic ("Unknown character code, logic error\n");
270*/
271 TRACE("\n");
272
273 oStr = outMap[stdCode];
274 if (oStr == (char *) NULL) /* no output sequence in map */
275 {
276 sprintf (buf, "[[%s]]", RTFStdCharName (stdCode));
277 oStr = buf;
278 }
279 PutLitStr (oStr);
280}
281
282
283void PutLitChar (int c)
284{
285 CHARLIST_Enqueue(&charlist, (char) c);
286 /* fputc (c, ostream); */
287}
288
289
290static void PutLitStr (char *s)
291{
292 for(;*s;s++)
293 {
294 CHARLIST_Enqueue(&charlist, *s);
295 }
296 /* fputs (s, ostream); */
297}
Note: See TracBrowser for help on using the repository browser.