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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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#undef TRACE
50#define TRACE(a) do {} while (0)
51#endif
52
53static void TextClass ();
54static void ControlClass ();
55static void Destination ();
56static void SpecialChar ();
57static void PutStdChar ();
58static void PutLitChar ();
59static void PutLitStr ();
60
61static char *outMap[rtfSC_MaxChar];
62
63static CHARLIST charlist = {0, NULL, NULL};
64
65int RTFToBuffer(char* pBuffer, int nBufferSize);
66int RTFToBuffer(char* pBuffer, int nBufferSize)
67{
68
69 /* check if the buffer is big enough to hold all characters */
70 /* we require one more for the '\0' */
71
72 TRACE("\n");
73
74 if(nBufferSize < charlist.nCount + 1) {
75 return charlist.nCount + CHARLIST_CountChar(&charlist, '\n') + 1;
76 }
77
78 while(charlist.nCount)
79 {
80 *pBuffer = CHARLIST_Dequeue(&charlist);
81 if(*pBuffer=='\n')
82 {
83 *pBuffer = '\r';
84 pBuffer++;
85 *pBuffer = '\n';
86 }
87 pBuffer++;
88 }
89 *pBuffer = '\0';
90
91 return 0;
92}
93
94
95/*
96 * Initialize the writer.
97 */
98
99void
100WriterInit ()
101{
102 RTFReadOutputMap (outMap,1);
103}
104
105
106int
107BeginFile ()
108{
109 /* install class callbacks */
110
111 RTFSetClassCallback (rtfText, TextClass);
112 RTFSetClassCallback (rtfControl, ControlClass);
113
114 return (1);
115}
116
117
118/*
119 * Write out a character. rtfMajor contains the input character, rtfMinor
120 * contains the corresponding standard character code.
121 *
122 * If the input character isn't in the charset map, try to print some
123 * representation of it.
124 */
125
126static void
127TextClass ()
128{
129char buf[rtfBufSiz];
130
131 TRACE("\n");
132
133 if (rtfFormat == SF_TEXT)
134 PutLitChar (rtfMajor);
135 else if (rtfMinor != rtfSC_nothing)
136 PutStdChar (rtfMinor);
137 else
138 {
139 if (rtfMajor < 128) /* in ASCII range */
140 sprintf (buf, "[[%c]]", rtfMajor);
141 else
142 sprintf (buf, "[[\\'%02x]]", rtfMajor);
143 PutLitStr (buf);
144 }
145}
146
147
148static void
149ControlClass ()
150{
151 TRACE("\n");
152 switch (rtfMajor)
153 {
154 case rtfDestination:
155 Destination ();
156 break;
157 case rtfSpecialChar:
158 SpecialChar ();
159 break;
160 }
161}
162
163
164/*
165 * This function notices destinations that should be ignored
166 * and skips to their ends. This keeps, for instance, picture
167 * data from being considered as plain text.
168 */
169
170static void
171Destination ()
172{
173
174 TRACE("\n");
175
176 switch (rtfMinor)
177 {
178 case rtfPict:
179 case rtfFNContSep:
180 case rtfFNContNotice:
181 case rtfInfo:
182 case rtfIndexRange:
183 case rtfITitle:
184 case rtfISubject:
185 case rtfIAuthor:
186 case rtfIOperator:
187 case rtfIKeywords:
188 case rtfIComment:
189 case rtfIVersion:
190 case rtfIDoccomm:
191 RTFSkipGroup ();
192 break;
193 }
194}
195
196
197/*
198 * The reason these use the rtfSC_xxx thingies instead of just writing
199 * out ' ', '-', '"', etc., is so that the mapping for these characters
200 * can be controlled by the text-map file.
201 */
202
203void SpecialChar ()
204{
205
206 TRACE("\n");
207
208 switch (rtfMinor)
209 {
210 case rtfPage:
211 case rtfSect:
212 case rtfRow:
213 case rtfLine:
214 case rtfPar:
215 PutLitChar ('\n');
216 break;
217 case rtfCell:
218 PutStdChar (rtfSC_space); /* make sure cells are separated */
219 break;
220 case rtfNoBrkSpace:
221 PutStdChar (rtfSC_nobrkspace);
222 break;
223 case rtfTab:
224 PutLitChar ('\t');
225 break;
226 case rtfNoBrkHyphen:
227 PutStdChar (rtfSC_nobrkhyphen);
228 break;
229 case rtfBullet:
230 PutStdChar (rtfSC_bullet);
231 break;
232 case rtfEmDash:
233 PutStdChar (rtfSC_emdash);
234 break;
235 case rtfEnDash:
236 PutStdChar (rtfSC_endash);
237 break;
238 case rtfLQuote:
239 PutStdChar (rtfSC_quoteleft);
240 break;
241 case rtfRQuote:
242 PutStdChar (rtfSC_quoteright);
243 break;
244 case rtfLDblQuote:
245 PutStdChar (rtfSC_quotedblleft);
246 break;
247 case rtfRDblQuote:
248 PutStdChar (rtfSC_quotedblright);
249 break;
250 }
251}
252
253
254/*
255 * Eventually this should keep track of the destination of the
256 * current state and only write text when in the initial state.
257 *
258 * If the output sequence is unspecified in the output map, write
259 * the character's standard name instead. This makes map deficiencies
260 * obvious and provides incentive to fix it. :-)
261 */
262
263void PutStdChar (int stdCode)
264{
265
266 char *oStr = (char *) NULL;
267 char buf[rtfBufSiz];
268
269/* if (stdCode == rtfSC_nothing)
270 RTFPanic ("Unknown character code, logic error\n");
271*/
272 TRACE("\n");
273
274 oStr = outMap[stdCode];
275 if (oStr == (char *) NULL) /* no output sequence in map */
276 {
277 sprintf (buf, "[[%s]]", RTFStdCharName (stdCode));
278 oStr = buf;
279 }
280 PutLitStr (oStr);
281}
282
283
284void PutLitChar (int c)
285{
286 CHARLIST_Enqueue(&charlist, (char) c);
287 /* fputc (c, ostream); */
288}
289
290
291static void PutLitStr (char *s)
292{
293 for(;*s;s++)
294 {
295 CHARLIST_Enqueue(&charlist, *s);
296 }
297 /* fputs (s, ostream); */
298}
Note: See TracBrowser for help on using the repository browser.