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

Last change on this file since 10367 was 9410, checked in by sandervl, 23 years ago

update

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