source: trunk/gsdl/src/mgpp/text/TextEl.cpp@ 879

Last change on this file since 879 was 855, checked in by sjboddie, 24 years ago

Rodgers new C++ mg

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
RevLine 
[855]1/**************************************************************************
2 *
3 * TextEl.cpp -- Data structures for parsed documents
4 * Copyright (C) 1999 Rodger McNab
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: TextEl.cpp 855 2000-01-14 02:17:52Z sjboddie $
21 *
22 **************************************************************************/
23
24#include "TextEl.h"
25#include "ctype.h"
26
27#define REC_TERM '\002'
28#define PARA_TERM '\003'
29
30
31void TextEl::Clear () {
32 elType = TextE;
33 tagName.erase (tagName.begin(), tagName.end());
34 text.erase (text.begin(), text.end());
35}
36
37
38static bool ReadTextTag (FileBuf &buf, TextEl &el) {
39 // we must have some sort of tag
40 unsigned char c;
41 if (!buf.Peek(c)) return false;
42
43 // get the '<'
44 if (c != '<') return false;
45 el.text.push_back (c);
46 if (!buf.Next() || !buf.Peek (c)) return false;
47
48 // see if we have a '/'
49 if (c == '/') {
50 // we have a closing tag
51 el.text.push_back (c);
52 if (!buf.Next() || !buf.Peek (c)) return false;
53 el.elType = CloseTagE;
54 } else {
55 // we have an opening tag
56 el.elType = OpenTagE;
57 }
58
59 // get the tag name
60 while (isalnum(c)) {
61 el.text.push_back (c);
62 el.tagName.push_back (c);
63 if (!buf.Next() || !buf.Peek (c)) return false;
64 }
65
66 // get everything up to the closing '>'
67 while (c != '>') {
68 el.text.push_back (c);
69 if (!buf.Next() || !buf.Peek (c)) return false;
70 }
71
72 // get the closing '>'
73 el.text.push_back (c);
74 buf.Next();
75
76 // if there is no tag name then make this a text element
77 if (el.tagName.empty()) el.elType = TextE;
78
79 return true;
80}
81
82static void ToggleParaTag (TextEl &el, bool &compatInPara) {
83 SetCStr (el.tagName, "Paragraph");
84 el.text.erase (el.text.begin(), el.text.end());
85 if (compatInPara) {
86 el.elType = CloseTagE;
87 el.text.push_back (PARA_TERM);
88 } else el.elType = OpenTagE;
89 compatInPara = !compatInPara;
90}
91
92static void SetRecTag (TextEl &el, TextElType elType) {
93 el.elType = elType;
94 SetCStr (el.tagName, "Document");
95 el.text.erase (el.text.begin(), el.text.end());
96 if (elType == CloseTagE)
97 el.text.push_back (REC_TERM);
98}
99
100
101bool ReadTextEl (FileBuf &buf, TextEl &el,
102 bool compatMode, bool &compatInPara) {
103 el.Clear();
104
105 unsigned char c;
106 if (!buf.Peek (c)) return false;
107
108 if (compatMode) {
109 if (c == PARA_TERM) {
110 ToggleParaTag (el, compatInPara);
111 if (!compatInPara) buf.Next();
112 return true;
113 }
114 if (c == REC_TERM) {
115 if (compatInPara) {
116 // need to close this paragraph
117 ToggleParaTag (el, compatInPara);
118 return true;
119 }
120 // can close this document
121 buf.Next();
122 SetRecTag (el, CloseTagE);
123 return true;
124 }
125 if (!compatInPara) {
126 // need to open a paragraph
127 ToggleParaTag (el, compatInPara);
128 return true;
129 }
130 }
131
132 // see if we have some sort of tag
133 if (c == '<') return ReadTextTag (buf, el);
134
135 // read in a text element
136 el.elType = TextE;
137 while (c != '<' && !(compatMode && (c == PARA_TERM || c == REC_TERM))) {
138 el.text.push_back (c);
139 if (!buf.Next() || !buf.Peek (c)) break;
140 }
141
142 return true;
143}
144
145static void AddTextEl (TextElArray &doc, unsigned long &docLen,
146 const TextEl &el) {
147 doc.push_back (el);
148 docLen += el.text.size();
149
150// cout << "elType: " << el.elType << "\n";
151// cout << "tagName: " << el.tagName << "\n";
152// cout << "text: \"" << el.text << "\"\n\n";
153}
154
155
156bool ReadDoc (FileBuf &buf, const UCArray &docTag,
157 TextElArray &doc, unsigned long &docLen,
158 bool compatMode) {
159 bool compatInPara = false;
160 bool foundDocEl = false;
161 TextEl el;
162
163 doc.erase (doc.begin(), doc.end());
164 docLen = 0;
165
166 if (compatMode) {
167 // add <Document><Paragraph>
168 SetRecTag (el, OpenTagE);
169 AddTextEl (doc, docLen, el);
170 ToggleParaTag (el, compatInPara);
171 AddTextEl (doc, docLen, el);
172
173 } else {
174 // look for an opening docTag
175 do {
176 if (!ReadTextEl (buf, el, compatMode, compatInPara)) return false;
177 } while (el.elType != OpenTagE || el.tagName != docTag);
178
179 AddTextEl (doc, docLen, el);
180 }
181
182
183 // get all elements until the closing docTag
184 while (ReadTextEl (buf, el, compatMode, compatInPara)) {
185 foundDocEl = true;
186 AddTextEl (doc, docLen, el);
187 if (el.elType == CloseTagE && el.tagName == docTag)
188 return true;
189 }
190
191
192 if (compatMode) {
193 if (!foundDocEl) { // end of text
194 doc.erase (doc.begin(), doc.end());
195 return false;
196 }
197
198 // if we got here then the eof was encountered before
199 // the closing document tag
200 if (compatInPara) {
201 // need to close this paragraph
202 ToggleParaTag (el, compatInPara);
203 AddTextEl (doc, docLen, el);
204 }
205 // close this document
206 SetRecTag (el, CloseTagE);
207 AddTextEl (doc, docLen, el);
208 }
209
210 return true;
211}
212
213
Note: See TracBrowser for help on using the repository browser.