]> git.lyx.org Git - features.git/blob - src/mathed/array.C
change output to uses streams instead of strings
[features.git] / src / mathed / array.C
1 #ifdef __GNUG__
2 #pragma implementation
3 #endif
4
5 #include "math_inset.h"
6 #include "math_charinset.h"
7 #include "math_scriptinset.h"
8 #include "math_stringinset.h"
9 #include "debug.h"
10 #include "array.h"
11 #include "mathed/support.h"
12 #include "support/LAssert.h"
13
14 using std::ostream;
15 using std::endl;
16
17
18
19 MathArray::MathArray()
20 {}
21
22
23 MathArray::MathArray(MathArray const & array, size_type from, size_type to)
24         : bf_(array.begin() + from, array.begin() + to)
25 {}
26
27
28 void MathArray::substitute(MathMacro const & m)
29 {
30         for (iterator it = begin(); it != end(); ++it)
31                 it->nucleus()->substitute(m);
32 }
33
34
35 MathScriptInset const * MathArray::asScript(const_iterator it) const
36 {
37         if (it->nucleus()->asScriptInset())
38                 return 0;
39         const_iterator jt = it + 1;
40         if (jt == end())
41                 return 0;
42         if (!jt->nucleus())
43                 return 0;
44         return jt->nucleus()->asScriptInset();
45 }
46
47
48 MathAtom & MathArray::at(size_type pos)
49 {
50         lyx::Assert(pos < size());
51         return bf_[pos];
52 }
53
54
55 MathAtom const & MathArray::at(size_type pos) const
56 {
57         lyx::Assert(pos < size());
58         return bf_[pos];
59 }
60
61
62 void MathArray::insert(size_type pos, MathAtom const & t)
63 {
64         bf_.insert(begin() + pos, t);
65 }
66
67
68 void MathArray::insert(size_type pos, MathArray const & array)
69 {
70         bf_.insert(begin() + pos, array.begin(), array.end());
71 }
72
73
74 void MathArray::push_back(MathAtom const & t)
75 {       
76         bf_.push_back(t);
77 }
78
79
80 void MathArray::push_back(MathArray const & array)
81 {
82         insert(size(), array);
83 }
84
85
86 void MathArray::clear()
87 {
88         erase();
89 }
90
91
92 void MathArray::swap(MathArray & array)
93 {
94         if (this != &array) 
95                 bf_.swap(array.bf_);
96 }
97
98
99 bool MathArray::empty() const
100 {
101         return bf_.empty();
102 }
103
104
105 MathArray::size_type MathArray::size() const
106 {
107         return bf_.size();
108 }
109
110
111 void MathArray::erase()
112 {
113         erase(0, size());
114 }
115
116
117 void MathArray::erase(size_type pos)
118 {
119         if (pos < size())
120                 erase(pos, pos + 1);
121 }
122
123
124 void MathArray::erase(size_type pos1, size_type pos2)
125 {
126         bf_.erase(begin() + pos1, begin() + pos2);
127 }
128
129
130 MathAtom & MathArray::back()
131 {
132         return bf_.back();
133 }
134
135
136 void MathArray::dump2(ostream & os) const
137 {
138         for (const_iterator it = begin(); it != end(); ++it)
139                 os << it->nucleus() << ' ';
140 }
141
142
143 void MathArray::dump(ostream & os) const
144 {
145         for (const_iterator it = begin(); it != end(); ++it)
146                 os << "<" << it->nucleus() << ">";
147 }
148
149
150 std::ostream & operator<<(std::ostream & os, MathArray const & ar)
151 {
152         ar.dump2(os);
153         return os;
154 }
155
156
157 // returns sequence of char with same code starting at it up to end
158 // it might be less, though...
159 string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
160 {
161         string s;
162         MathCharInset const * p = it->nucleus()->asCharInset();
163         if (!p)
164                 return s;
165
166         for (MathTextCodes c = p->code(); it != end; ++it) {
167                 if (!it->nucleus())
168                         break;
169                 p = it->nucleus()->asCharInset();
170                 if (!p || p->code() != c)
171                         break;
172                 s += p->getChar();
173         }
174         return s;
175 }
176
177
178 MathArray MathArray::glueChars() const
179 {
180         MathArray ar;
181         const_iterator it = begin();
182         while (it != end()) {
183                 if (it->nucleus() && it->nucleus()->asCharInset()) {
184                         string s = charSequence(it, end());
185                         MathTextCodes c = it->nucleus()->asCharInset()->code();
186                         ar.push_back(MathAtom(new MathStringInset(s, c)));
187                         it += s.size();
188                 } else {
189                         ar.push_back(*it);
190                         ++it;
191                 }
192         }
193         return ar;
194 }
195
196
197 bool needAsterisk(MathAtom const &, MathAtom const &)
198 {
199         return false;
200 }
201
202
203 MathArray MathArray::guessAsterisks() const
204 {
205         if (size() <= 1)
206                 return *this;
207         MathArray ar;
208         ar.push_back(*begin());
209         for (const_iterator it = begin(), jt = begin()+1 ; jt != end(); ++it, ++jt) {
210                 if (needAsterisk(*it, *jt))
211                         ar.push_back(MathAtom(new MathCharInset('*')));
212                 ar.push_back(*it);
213         }
214         ar.push_back(*end());
215         return ar;
216 }
217
218
219 void MathArray::write(MathWriteInfo & wi) const
220 {
221         MathArray ar = glueChars();
222         for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
223                 MathInset const * p = it->nucleus();
224                 if (MathScriptInset const * q = ar.asScript(it)) {
225                         q->write(p, wi);
226                         ++it;
227                 } else {
228                         p->write(wi);
229                 }
230         }
231 }
232
233
234 void MathArray::writeNormal(ostream & os) const
235 {
236         MathArray ar = glueChars();
237         for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
238                 MathInset const * p = it->nucleus();
239                 if (MathScriptInset const * q = ar.asScript(it)) {
240                         q->writeNormal(p, os);
241                         ++it;
242                 } else 
243                         p->writeNormal(os);
244         }
245 }
246
247
248 void MathArray::octavize(OctaveStream & os) const
249 {
250         MathArray ar = glueChars();
251         for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
252                 MathInset const * p = it->nucleus();
253                 if (MathScriptInset const * q = ar.asScript(it)) {
254                         q->octavize(p, os);
255                         ++it;
256                 } else 
257                         p->octavize(os);
258         }
259 }
260
261
262 void MathArray::maplize(MapleStream & os) const
263 {
264         MathArray ar = glueChars();
265         for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
266                 MathInset const * p = it->nucleus();
267                 if (MathScriptInset const * q = ar.asScript(it)) {
268                         q->maplize(p, os);
269                         ++it;
270                 } else 
271                         p->maplize(os);
272         }
273 }
274
275
276 void MathArray::mathmlize(MathMLStream & os) const
277 {
278         MathArray ar = glueChars();
279         os << "<mrow>";
280         for (const_iterator it = ar.begin(); it != ar.end(); ++it) {
281                 MathInset const * p = it->nucleus();
282                 if (MathScriptInset const * q = ar.asScript(it)) {
283                         q->mathmlize(p, os);
284                         ++it;
285                 } else 
286                         p->mathmlize(os);
287         }
288         os << "</mrow>";
289 }
290
291
292 void MathArray::validate(LaTeXFeatures & features) const
293 {
294         for (const_iterator it = begin(); it != end(); ++it)
295                 if (it->nucleus())
296                         it->nucleus()->validate(features);
297 }
298
299
300 void MathArray::pop_back()
301 {       
302         if (!size()) {
303                 lyxerr << "pop_back from empty array!\n";
304                 return;
305         }
306         bf_.pop_back();
307 }
308
309
310 MathArray::const_iterator MathArray::begin() const
311 {
312         return bf_.begin();
313 }
314
315
316 MathArray::const_iterator MathArray::end() const
317 {
318         return bf_.end();
319 }
320
321
322 MathArray::iterator MathArray::begin()
323 {
324         return bf_.begin();
325 }
326
327
328 MathArray::iterator MathArray::end()
329 {
330         return bf_.end();
331 }
332
333
334 bool MathArray::isMatrix() const
335 {
336         return size() == 1 && begin()->nucleus() && begin()->nucleus()->isMatrix();
337 }
338
339