1 /************************************************************************/
2 /* */
3 /* Save a BufferDocument into an RTF file. */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <stdio.h>
10 # include <ctype.h>
11
12 # include <bitmap.h>
13
14 # include <appDebugon.h>
15
16 # include "docRtfFlags.h"
17 # include "docRtfTags.h"
18 # include <docField.h>
19 # include <docTreeType.h>
20 # include <docTreeNode.h>
21 # include <docNotes.h>
22 # include "docRtfWriterImpl.h"
23 # include <docBookmarkField.h>
24 # include <docTextParticule.h>
25 # include <docDocumentNote.h>
26
27 /************************************************************************/
28 /* */
29 /* Finish/Begin writing a field. */
30 /* */
31 /************************************************************************/
32
docRtfFinishFldrslt(RtfWriter * rwc)33 static void docRtfFinishFldrslt( RtfWriter * rwc )
34 {
35 docRtfWriteDestinationEnd( rwc );
36 docRtfWriteDestinationEnd( rwc );
37 docRtfWriteDestinationEnd( rwc );
38
39 rwc->rwcInFldrslt--;
40
41 if ( docRtfPopAttribute( rwc ) )
42 { LDEB(1); }
43
44 return;
45 }
46
docRtfWriteWriteComponent(RtfWriter * rwc,const InstructionsComponent * ic)47 static void docRtfWriteWriteComponent( RtfWriter * rwc,
48 const InstructionsComponent * ic )
49 {
50 if ( ic->icIsQuoted )
51 { docRtfWriteDocEncodedString( rwc, "\"", 1 ); }
52
53 docRtfWriteDocEncodedString( rwc,
54 (const char *)ic->icBuffer.mbBytes,
55 ic->icBuffer.mbSize );
56 if ( ic->icIsQuoted )
57 { docRtfWriteDocEncodedString( rwc, "\"", 1 ); }
58
59 return;
60 }
61
docRtfWriteFieldInstructions(RtfWriter * rwc,const FieldInstructions * fi)62 static void docRtfWriteFieldInstructions( RtfWriter * rwc,
63 const FieldInstructions * fi )
64 {
65 const InstructionsComponent * ic;
66 int byteCount= 0;
67 int i;
68
69 ic= fi->fiComponents;
70 for ( i= 0; i < fi->fiComponentCount; i++ )
71 {
72 if ( ic->icIsQuoted )
73 { byteCount += 2; }
74 ic++;
75 }
76
77 if ( fi->fiComponentCount > 1 )
78 { byteCount += fi->fiComponentCount- 1; }
79
80 docRtfReserveColumns( rwc, byteCount );
81
82 ic= fi->fiComponents;
83 if ( fi->fiComponentCount > 0 )
84 { docRtfWriteWriteComponent( rwc, ic++ ); }
85 for ( i= 1; i < fi->fiComponentCount; i++ )
86 {
87 docRtfWriteDocEncodedString( rwc, " ", 1 );
88 docRtfWriteWriteComponent( rwc, ic++ );
89 }
90
91 return;
92 }
93
docRtfWriteStartField(RtfWriter * rwc,const DocumentField * df)94 static void docRtfWriteStartField( RtfWriter * rwc,
95 const DocumentField * df )
96 {
97 docRtfWriteDestinationBegin( rwc, "field" );
98 docRtfWriteDestinationBegin( rwc, "*\\fldinst" );
99 docRtfWriteDestinationBegin( rwc, "" );
100
101 docRtfWriteFieldInstructions( rwc, &(df->dfInstructions) );
102
103 /*?
104 docRtfWriteDocEncodedString( rwc, " ", 1 );
105 */
106
107 docRtfWriteDestinationEnd( rwc );
108 docRtfWriteDestinationEnd( rwc );
109
110 docRtfWriteDestinationBegin( rwc, "fldrslt" );
111 docRtfWriteDestinationBegin( rwc, "" );
112
113 rwc->rwcInFldrslt++;
114
115 if ( docRtfPushAttribute( rwc ) )
116 { LDEB(1); }
117
118 return;
119 }
120
docRtfBookmarkTag(RtfWriter * rwc,const char * tag,const DocumentField * df)121 static void docRtfBookmarkTag( RtfWriter * rwc,
122 const char * tag,
123 const DocumentField * df )
124 {
125 const int addSemicolon= 0;
126
127 const MemoryBuffer * mbBookmark;
128
129 if ( ! docFieldGetBookmark( &mbBookmark, df ) )
130 {
131 docRtfWriteDocEncodedStringDestination( rwc, tag,
132 (const char *)mbBookmark->mbBytes,
133 mbBookmark->mbSize, addSemicolon );
134 }
135
136 return;
137 }
138
docRtfStartTc(RtfWriter * rwc,const DocumentField * df)139 static void docRtfStartTc( RtfWriter * rwc,
140 const DocumentField * df )
141 {
142 const FieldKindInformation * fki= DOC_FieldKinds+ df->dfKind;
143
144 docRtfWriteDestinationBegin( rwc, fki->fkiRtfTag );
145
146 docRtfWriteFieldInstructions( rwc, &(df->dfInstructions) );
147
148 /* The field instructions actually contain tags */
149 rwc->rwcAfter= RTFafterTAG;
150
151 return;
152 }
153
154 /************************************************************************/
155 /* */
156 /* Save a note. */
157 /* */
158 /************************************************************************/
159
docRtfSaveNoteField(RtfWriter * rw,int * pCount,const BufferItem * paraNode,const int part,const TextParticule * tp,const DocumentField * df)160 static int docRtfSaveNoteField( RtfWriter * rw,
161 int * pCount,
162 const BufferItem * paraNode,
163 const int part,
164 const TextParticule * tp,
165 const DocumentField * df )
166 {
167 const DocumentNote * dn;
168 const NoteProperties * np;
169 int count;
170 int closed;
171
172 const char * first= (const char *)0;
173 int attrNr= -1;
174 const int paralen= docParaStrlen( paraNode );
175 int stroff= paralen;
176
177 count= docCountParticulesInField( paraNode, &closed, part,
178 paraNode->biParaParticuleCount );
179
180 /* Prefer the attributes of the field result */
181 if ( count > 0 && tp[1].tpKind == DOCkindSPAN )
182 {
183 stroff= tp[1].tpStroff;
184 attrNr= tp[1].tpTextAttrNr;
185 }
186 else{
187 stroff= tp[0].tpStroff+ tp[0].tpStrlen;
188 attrNr= tp[0].tpTextAttrNr;
189 }
190
191 if ( stroff < paralen )
192 { first= (const char *)docParaString( paraNode, stroff ); }
193
194 docRtfWriteSwitchTextAttributes( rw, attrNr, first );
195
196 dn= docGetNoteOfField( df, rw->rwDocument );
197 if ( ! dn )
198 { XDEB(dn); return -1; }
199 np= &(dn->dnNoteProperties);
200
201 if ( np->npAutoNumber )
202 {
203 docRtfWriteTag( rw, RTFtag_chftn );
204
205 if ( paraNode->biTreeType == DOCinBODY &&
206 rw->rwTextAttribute.taSuperSub != TEXTvaREGULAR )
207 {
208 docRtfWriteTag( rw, RTFtag_nosupersub );
209 rw->rwTextAttribute.taSuperSub= TEXTvaREGULAR;
210 }
211 }
212 else{
213 docRtfWriteFontEncodedString( rw,
214 (const char *)np->npFixedText.mbBytes,
215 np->npFixedText.mbSize );
216 }
217
218 if ( df->dfNoteIndex >= 0 && dn->dnDocumentTree.dtRoot )
219 {
220 const int evenIfAbsent= 0;
221 const int forcePar= 0;
222
223 if ( paraNode->biTreeType == DOCinFOOTNOTE ||
224 paraNode->biTreeType == DOCinENDNOTE )
225 { SDEB(docTreeTypeStr(paraNode->biTreeType)); }
226 else{
227 switch( np->npTreeType )
228 {
229 case DOCinFOOTNOTE:
230 if ( docRtfSaveDocumentTree( rw, RTFtag_footnote,
231 &(dn->dnDocumentTree), evenIfAbsent, forcePar ) )
232 { LDEB(np->npTreeType); return -1; }
233 break;
234
235 case DOCinENDNOTE:
236 if ( docRtfSaveDocumentTree( rw, "footnote\\ftnalt",
237 &(dn->dnDocumentTree), evenIfAbsent, forcePar ) )
238 { LDEB(np->npTreeType); return -1; }
239 break;
240
241 default:
242 LDEB(np->npTreeType);
243 break;
244 }
245 }
246 }
247
248 *pCount= count;
249 return 0;
250 }
251
252 /************************************************************************/
253 /* */
254 /* Save a field head particule */
255 /* */
256 /************************************************************************/
257
docRtfSaveFieldHead(RtfWriter * rwc,const BufferItem * paraNode,int part)258 int docRtfSaveFieldHead( RtfWriter * rwc,
259 const BufferItem * paraNode,
260 int part )
261 {
262 const DocumentField * df;
263 const FieldKindInformation * fki;
264 const TextParticule * tp= paraNode->biParaParticules+ part;
265
266 df= docGetFieldByNumber( &(rwc->rwDocument->bdFieldList),
267 tp->tpObjectNumber );
268 if ( ! df )
269 { LPDEB(tp->tpObjectNumber,df); return 0; }
270
271 fki= DOC_FieldKinds+ df->dfKind;
272
273 if ( fki->fkiIsFieldInRtf )
274 {
275 if ( df->dfKind != DOCfkMERGEFIELD ||
276 ! ( rwc->rwSaveFlags & RTFflagNO_MERGEFIELDS ) )
277 { docRtfWriteStartField( rwc, df ); }
278 }
279
280 if ( df->dfKind == DOCfkBOOKMARK &&
281 ! ( rwc->rwSaveFlags & RTFflagNO_BOOKMARKS ) )
282 { docRtfBookmarkTag( rwc, "*\\bkmkstart", df ); }
283
284 if ( df->dfKind == DOCfkTC || df->dfKind == DOCfkTCN )
285 { docRtfStartTc( rwc, df ); }
286
287 if ( df->dfKind == DOCfkCHFTN )
288 {
289 int count= 0;
290
291 if ( docRtfSaveNoteField( rwc, &count, paraNode, part, tp, df ) )
292 { LDEB(df->dfKind); return -1; }
293
294 return count;
295 }
296
297 if ( df->dfKind == DOCfkLISTTEXT &&
298 paraNode->biParaListOverride > 0 )
299 {
300 if ( docRtfPushAttribute( rwc ) )
301 { LDEB(1); }
302
303 docRtfWriteDestinationBegin( rwc, "listtext" );
304 }
305
306 if ( fki->fkiIsDestinationInRtf &&
307 fki->fkiRtfTag )
308 {
309 docRtfWriteDestinationBegin( rwc, fki->fkiRtfTag );
310
311 docRtfWriteDocEncodedString( rwc,
312 (char *)df->dfData.mbBytes, df->dfData.mbSize );
313
314 docRtfWriteDestinationBegin( rwc, "" );
315
316 docRtfWriteFieldInstructions( rwc, &(df->dfInstructions) );
317
318 docRtfWriteDestinationEnd( rwc );
319 docRtfWriteDestinationEnd( rwc );
320 }
321
322 return 0;
323 }
324
325 /************************************************************************/
326 /* */
327 /* Save a field tail particule */
328 /* */
329 /************************************************************************/
330
docRtfSaveFieldTail(RtfWriter * rwc,const BufferItem * paraNode,int part)331 int docRtfSaveFieldTail( RtfWriter * rwc,
332 const BufferItem * paraNode,
333 int part )
334 {
335 const DocumentField * df;
336 const FieldKindInformation * fki;
337 const TextParticule * tp= paraNode->biParaParticules+ part;
338
339 if ( tp->tpObjectNumber < 0 )
340 { LDEB(tp->tpObjectNumber); return 0; }
341
342 df= docGetFieldByNumber( &(rwc->rwDocument->bdFieldList),
343 tp->tpObjectNumber );
344 if ( ! df )
345 { LPDEB(tp->tpObjectNumber,df); return 0; }
346
347 fki= DOC_FieldKinds+ df->dfKind;
348
349 if ( df->dfKind == DOCfkBOOKMARK &&
350 ! ( rwc->rwSaveFlags & RTFflagNO_BOOKMARKS ) )
351 { docRtfBookmarkTag( rwc, "*\\bkmkend", df ); }
352
353 if ( df->dfKind == DOCfkTC || df->dfKind == DOCfkTCN )
354 { docRtfWriteDestinationEnd( rwc ); }
355
356 if ( fki->fkiIsFieldInRtf )
357 {
358 if ( df->dfKind != DOCfkMERGEFIELD ||
359 ! ( rwc->rwSaveFlags & RTFflagNO_MERGEFIELDS ) )
360 {
361 if ( rwc->rwcInFldrslt )
362 { docRtfFinishFldrslt( rwc ); }
363 }
364 }
365
366 if ( df->dfKind == DOCfkLISTTEXT &&
367 paraNode->biParaListOverride > 0 )
368 {
369 docRtfWriteDestinationEnd( rwc );
370
371 if ( docRtfPopAttribute( rwc ) )
372 { LDEB(1); }
373 }
374
375 return 0;
376 }
377
378