1 /************************************************************************/
2 /* */
3 /* Read an RTF text file into a BufferDocument */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <stdio.h>
10 # include <ctype.h>
11
12 # include <appDebugon.h>
13
14 # include "docRtfReaderImpl.h"
15 # include "docRtfReadWrite.h"
16 # include "docRtfTagEnum.h"
17 # include "docRtfFlags.h"
18 # include <docRecalculateFields.h>
19 # include <docTreeType.h>
20 # include <docTreeNode.h>
21 # include <docNotes.h>
22 # include <docDebug.h>
23
24 /************************************************************************/
25
26 const char DOC_RTF_LENIENT_MESSAGE[]= "Use lenientRtf setting";
27
28 /************************************************************************/
29 /* */
30 /* Groups (Most of them handeled at the document level). */
31 /* */
32 /************************************************************************/
33
34 RtfControlWord docRtfDocumentGroups[]=
35 {
36 RTF_DEST_XX( "tc", DOCfkTC, docRtfLookupEntry ),
37 RTF_DEST_XX( "tcn", DOCfkTCN, docRtfLookupEntry ),
38
39 RTF_DEST_XX( "nonesttables", 1, docRtfSkipGroup ),
40
41 RTF_DEST_XX( "trowd", DOClevROW, docRtfReadRowProperties ),
42
43 { (char *)0, 0, 0 }
44 };
45
46 /************************************************************************/
47 /* */
48 /* Read a document as a whole. */
49 /* */
50 /************************************************************************/
51
docRtfReadDoc(const RtfControlWord * rcw,int arg,RtfReader * rrc)52 static int docRtfReadDoc( const RtfControlWord * rcw,
53 int arg,
54 RtfReader * rrc )
55 {
56 int rval= 0;
57 int changed= 0;
58
59 rrc->rrcSelectionScope.ssTreeType= DOCinBODY;
60
61 rval= docRtfReadGroup( rcw, 0, 0, rrc,
62 docRtfDocumentGroups,
63 docRtfTextParticule,
64 docRtfFinishCurrentNode );
65 if ( rval )
66 { SLDEB(rcw->rcwWord,rval); }
67
68 docRenumberSeqFields( &changed, rrc->rrcTree, rrc->rrDocument );
69
70 return rval;
71 }
72
73 /************************************************************************/
74 /* */
75 /* Read a whole document. */
76 /* */
77 /* As at least MS-Word 2000 crashes on lists without an override, */
78 /* and on the other hand staroffice/openoffice creates them under */
79 /* certain circumstances: Make an empty override for lists without */
80 /* overrides. */
81 /* */
82 /************************************************************************/
83
84 static RtfControlWord docRtfOutsideGroups[]=
85 {
86 RTF_DEST_XX( "rtf", 0, docRtfReadDoc ),
87
88 { (char *)0, 0, 0 }
89 };
90
docRtfReadFile(SimpleInputStream * sis,unsigned int flags)91 BufferDocument * docRtfReadFile( SimpleInputStream * sis,
92 unsigned int flags )
93 {
94 BufferDocument * rval= (BufferDocument *)0;
95 BufferDocument * bd= (BufferDocument *)0;
96 RtfReader * rr= (RtfReader *)0;
97
98 int res;
99 const RtfControlWord * rcw;
100
101 char controlWord[TEDszRTFCONTROL+1];
102 int gotArg;
103 int arg= -1;
104 int c;
105
106 const DocumentField * dfNote;
107 struct DocumentNote * dn;
108 int changed;
109
110 bd= docNewDocument( (BufferDocument *)0 );
111 if ( ! bd )
112 { XDEB(bd); goto ready; }
113
114 rr= docRtfOpenReader( sis, bd, flags );
115 if ( ! rr )
116 { XDEB(rr); goto ready; }
117
118 rr->rrcTree= &(rr->rrDocument->bdBody);
119 rr->rrcNode= rr->rrcTree->dtRoot;
120 rr->rrcLevel= DOClevBODY;
121
122 res= docRtfFindControl( rr, &c, controlWord, &gotArg, &arg );
123 if ( res != RTFfiCTRLGROUP )
124 { goto ready; }
125
126 rcw= docRtfFindWord( controlWord, docRtfOutsideGroups );
127 if ( ! rcw )
128 { LDEB(1); goto ready; }
129 if ( rcw->rcwType != RTCtypeDEST )
130 { SLDEB(rcw->rcwWord,rcw->rcwType); goto ready; }
131
132 res= docRtfApplyControlWord( rcw, gotArg, arg, rr );
133 if ( res )
134 { LDEB(1); goto ready; }
135
136 /* Check against trailing garbage. Spaces are not allowed either, */
137 /* but we do not want to scare the user with invisible things. */
138
139 if ( ! ( rr->rrReadFlags & RTFflagLENIENT ) )
140 {
141 c= sioInGetByte( sis );
142 while( c != EOF )
143 {
144 if ( c != '\r' && c != '\n' && c != '\0' && c != ' ' )
145 {
146 const char * message= DOC_RTF_LENIENT_MESSAGE;
147 LCSDEB(rr->rrCurrentLine,c,message); goto ready;
148 }
149
150 c= sioInGetByte( sis );
151 }
152 }
153
154 if ( ! rr->rrcGotDocGeometry &&
155 bd->bdBody.dtRoot->biChildCount > 0 )
156 {
157 bd->bdProperties.dpGeometry=
158 bd->bdBody.dtRoot->biChildren[0]->biSectDocumentGeometry;
159 }
160
161 docRenumberNotes( &changed, bd );
162
163 dfNote= docGetFirstNoteOfDocument( &dn, bd, DOCinFOOTNOTE );
164 if ( dfNote )
165 {
166 if ( docCheckSeparatorItemForNoteType( bd, DOCinFOOTNOTE ) )
167 { LDEB(DOCinFTNSEP); goto ready; }
168 }
169
170 dfNote= docGetFirstNoteOfDocument( &dn, bd, DOCinENDNOTE );
171 if ( dfNote )
172 {
173 if ( docCheckSeparatorItemForNoteType( bd, DOCinENDNOTE ) )
174 { LDEB(DOCinAFTNSEP); goto ready; }
175 }
176
177 if ( docMakeOverrideForEveryList( bd->bdProperties.dpListAdmin ) )
178 { LDEB(1); goto ready; }
179
180 if ( docGetCharsUsed( bd ) )
181 { LDEB(1); goto ready; }
182
183 rval= bd; bd= (BufferDocument *)0; /* steal */
184
185 /* LDEB(1); docListNode(0,rval->bdBody.dtRoot,0); */
186
187 ready:
188
189 if ( rr )
190 { docRtfCloseReader( rr ); }
191
192 if ( bd )
193 { docFreeDocument( bd ); }
194
195 return rval;
196 }
197
198 /************************************************************************/
199 /* */
200 /* Remember properties to be used subsequently. */
201 /* */
202 /* References are to be replaced with feature specific routine */
203 /* refrerences. */
204 /* */
205 /************************************************************************/
206
docRtfRememberProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)207 int docRtfRememberProperty( const RtfControlWord * rcw,
208 int arg,
209 RtfReader * rrc )
210 {
211 RtfReadingState * rrs= rrc->rrcState;
212
213 switch( rcw->rcwID )
214 {
215 case RTFidUC:
216 if ( rrc->rrcState )
217 { rrc->rrcState->rrsBytesPerUnicode= arg; }
218 break;
219 /****************************************/
220 /* Set/Unset Text Attributes. */
221 /****************************************/
222 case RTFidULNONE:
223 rrs->rrsTextAttribute.taTextIsUnderlined= 0;
224 break;
225 /****************************************/
226 /* Set/Unset Text Attributes. */
227 /* In Paragraph Numbering. */
228 /****************************************/
229 case RTFidPNULNONE:
230 rrc->rrcParagraphNumber.pnTextAttribute.taTextIsUnderlined= 0;
231 break;
232
233 /****************************************/
234 /* Paragraph Numbering. */
235 /****************************************/
236 case RTFidPNHANG:
237 rrc->rrcParagraphNumber.pnUseHangingIndent= 1;
238 break;
239 /****************************************/
240 /* Unknown */
241 /****************************************/
242 default:
243 /*SLDEB(rcw->rcwWord,rcw->rcwID);*/
244 break;
245 }
246
247 return 0;
248 }
249