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