Make the standard create_file request handle serial ports too, and
[wine.git] / dlls / richedit / text-writer.c
blob272a7e859e58b42eac23cfb74f46c8612c2b5ba1
1 /*
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
18 * is encountered.
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.
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.
39 #include <stdio.h>
41 #include "rtf.h"
42 #include "rtf2text.h"
43 #include "charlist.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
48 static void TextClass (RTF_Info *info);
49 static void ControlClass (RTF_Info *info);
50 static void Destination (RTF_Info *info);
51 static void SpecialChar (RTF_Info *info);
52 static void PutStdChar (RTF_Info *info, int stdCode);
53 static void PutLitChar (RTF_Info *info, int c);
54 static void PutLitStr (RTF_Info *info, char *s);
56 #if 0
57 static char *outMap[rtfSC_MaxChar];
59 static CHARLIST charlist = {0, NULL, NULL};
60 #endif
62 /*int RTFToBuffer(char* pBuffer, int nBufferSize); */
63 int RTFToBuffer(RTF_Info *info, char* pBuffer, int nBufferSize)
66 /* check if the buffer is big enough to hold all characters */
67 /* we require one more for the '\0' */
69 TRACE("\n");
71 if(nBufferSize < info->charlist.nCount + 1) {
72 return info->charlist.nCount + CHARLIST_CountChar(&info->charlist, '\n') + 1;
75 while(info->charlist.nCount)
77 *pBuffer = CHARLIST_Dequeue(&info->charlist);
78 if(*pBuffer=='\n')
80 *pBuffer = '\r';
81 pBuffer++;
82 *pBuffer = '\n';
84 pBuffer++;
86 *pBuffer = '\0';
88 return 0;
93 * Initialize the writer.
96 void
97 WriterInit (RTF_Info *info )
99 RTFReadOutputMap (info, info->outMap,1);
104 BeginFile (RTF_Info *info )
106 /* install class callbacks */
108 RTFSetClassCallback (info, rtfText, TextClass);
109 RTFSetClassCallback (info, rtfControl, ControlClass);
111 return (1);
116 * Write out a character. rtfMajor contains the input character, rtfMinor
117 * contains the corresponding standard character code.
119 * If the input character isn't in the charset map, try to print some
120 * representation of it.
123 static void
124 TextClass (RTF_Info *info)
126 char buf[rtfBufSiz];
128 TRACE("\n");
130 if (info->rtfFormat == SF_TEXT)
131 PutLitChar (info, info->rtfMajor);
132 else if (info->rtfMinor != rtfSC_nothing)
133 PutStdChar (info, info->rtfMinor);
134 else
136 if (info->rtfMajor < 128) /* in ASCII range */
137 sprintf (buf, "[[%c]]", info->rtfMajor);
138 else
139 sprintf (buf, "[[\\'%02x]]", info->rtfMajor);
140 PutLitStr (info, buf);
145 static void
146 ControlClass (RTF_Info *info)
148 TRACE("\n");
149 switch (info->rtfMajor)
151 case rtfDestination:
152 Destination (info);
153 break;
154 case rtfSpecialChar:
155 SpecialChar (info);
156 break;
162 * This function notices destinations that should be ignored
163 * and skips to their ends. This keeps, for instance, picture
164 * data from being considered as plain text.
167 static void
168 Destination (RTF_Info *info)
171 TRACE("\n");
173 switch (info->rtfMinor)
175 case rtfPict:
176 case rtfFNContSep:
177 case rtfFNContNotice:
178 case rtfInfo:
179 case rtfIndexRange:
180 case rtfITitle:
181 case rtfISubject:
182 case rtfIAuthor:
183 case rtfIOperator:
184 case rtfIKeywords:
185 case rtfIComment:
186 case rtfIVersion:
187 case rtfIDoccomm:
188 RTFSkipGroup (info);
189 break;
195 * The reason these use the rtfSC_xxx thingies instead of just writing
196 * out ' ', '-', '"', etc., is so that the mapping for these characters
197 * can be controlled by the text-map file.
200 void SpecialChar (RTF_Info *info)
203 TRACE("\n");
205 switch (info->rtfMinor)
207 case rtfPage:
208 case rtfSect:
209 case rtfRow:
210 case rtfLine:
211 case rtfPar:
212 PutLitChar (info, '\n');
213 break;
214 case rtfCell:
215 PutStdChar (info, rtfSC_space); /* make sure cells are separated */
216 break;
217 case rtfNoBrkSpace:
218 PutStdChar (info, rtfSC_nobrkspace);
219 break;
220 case rtfTab:
221 PutLitChar (info, '\t');
222 break;
223 case rtfNoBrkHyphen:
224 PutStdChar (info, rtfSC_nobrkhyphen);
225 break;
226 case rtfBullet:
227 PutStdChar (info, rtfSC_bullet);
228 break;
229 case rtfEmDash:
230 PutStdChar (info, rtfSC_emdash);
231 break;
232 case rtfEnDash:
233 PutStdChar (info, rtfSC_endash);
234 break;
235 case rtfLQuote:
236 PutStdChar (info, rtfSC_quoteleft);
237 break;
238 case rtfRQuote:
239 PutStdChar (info, rtfSC_quoteright);
240 break;
241 case rtfLDblQuote:
242 PutStdChar (info, rtfSC_quotedblleft);
243 break;
244 case rtfRDblQuote:
245 PutStdChar (info, rtfSC_quotedblright);
246 break;
252 * Eventually this should keep track of the destination of the
253 * current state and only write text when in the initial state.
255 * If the output sequence is unspecified in the output map, write
256 * the character's standard name instead. This makes map deficiencies
257 * obvious and provides incentive to fix it. :-)
260 void PutStdChar (RTF_Info *info, int stdCode)
263 char *oStr = (char *) NULL;
264 char buf[rtfBufSiz];
266 /* if (stdCode == rtfSC_nothing)
267 RTFPanic ("Unknown character code, logic error\n");
269 TRACE("\n");
271 oStr = info->outMap[stdCode];
272 if (oStr == (char *) NULL) /* no output sequence in map */
274 sprintf (buf, "[[%s]]", RTFStdCharName (info, stdCode));
275 oStr = buf;
277 PutLitStr (info, oStr);
281 void PutLitChar (RTF_Info *info, int c)
283 CHARLIST_Enqueue(&info->charlist, (char) c);
284 /* fputc (c, ostream); */
288 static void PutLitStr (RTF_Info *info, char *s)
290 for(;*s;s++)
292 CHARLIST_Enqueue(&info->charlist, *s);
294 /* fputs (s, ostream); */