]> git.lyx.org Git - features.git/blob - src/mathed/array.C
write \mathrm{x}\mathrm{y} as \mathrm{xy} again
[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 MathArray::MathArray()
19 {}
20
21
22 MathArray::MathArray(MathArray const & array, size_type from, size_type to)
23         : bf_(array.begin() + from, array.begin() + to)
24 {}
25
26
27 void MathArray::substitute(MathMacro const & m)
28 {
29         for (iterator it = begin(); it != end(); ++it)
30                 it->nucleus()->substitute(m);
31 }
32
33
34 MathScriptInset const * MathArray::asScript(const_iterator it) const
35 {
36         if (it->nucleus()->asScriptInset())
37                 return 0;
38         const_iterator jt = it + 1;
39         if (jt == end())
40                 return 0;
41         return jt->nucleus()->asScriptInset();
42 }
43
44
45 MathAtom & MathArray::at(size_type pos)
46 {
47         lyx::Assert(pos < size());
48         return bf_[pos];
49 }
50
51
52 MathAtom const & MathArray::at(size_type pos) const
53 {
54         lyx::Assert(pos < size());
55         return bf_[pos];
56 }
57
58
59 void MathArray::insert(size_type pos, MathAtom const & t)
60 {
61         bf_.insert(begin() + pos, t);
62 }
63
64
65 void MathArray::insert(size_type pos, MathArray const & array)
66 {
67         bf_.insert(begin() + pos, array.begin(), array.end());
68 }
69
70
71 void MathArray::push_back(MathAtom const & t)
72 {       
73         bf_.push_back(t);
74 }
75
76
77 void MathArray::push_back(MathArray const & array)
78 {
79         insert(size(), array);
80 }
81
82
83 void MathArray::clear()
84 {
85         erase();
86 }
87
88
89 void MathArray::swap(MathArray & array)
90 {
91         if (this != &array) 
92                 bf_.swap(array.bf_);
93 }
94
95
96 bool MathArray::empty() const
97 {
98         return bf_.empty();
99 }
100
101
102 MathArray::size_type MathArray::size() const
103 {
104         return bf_.size();
105 }
106
107
108 void MathArray::erase()
109 {
110         erase(0, size());
111 }
112
113
114 void MathArray::erase(size_type pos)
115 {
116         if (pos < size())
117                 erase(pos, pos + 1);
118 }
119
120
121 void MathArray::erase(size_type pos1, size_type pos2)
122 {
123         bf_.erase(begin() + pos1, begin() + pos2);
124 }
125
126
127 MathAtom & MathArray::back()
128 {
129         return bf_.back();
130 }
131
132
133 void MathArray::dump2(ostream & os) const
134 {
135         for (const_iterator it = begin(); it != end(); ++it)
136                 os << it->nucleus() << ' ';
137 }
138
139
140 void MathArray::dump(ostream & os) const
141 {
142         for (const_iterator it = begin(); it != end(); ++it)
143                 os << "<" << it->nucleus() << ">";
144 }
145
146
147 std::ostream & operator<<(std::ostream & os, MathArray const & ar)
148 {
149         ar.dump2(os);
150         return os;
151 }
152
153
154 // returns sequence of char with same code starting at it up to end
155 // it might be less, though...
156 string charSequence(MathArray::const_iterator it, MathArray::const_iterator end)
157 {
158         string s;
159         MathCharInset const * p = it->nucleus()->asCharInset();
160         if (!p)
161                 return s;
162
163         for (MathTextCodes c = p->code(); it != end; ++it) {
164                 if (!it->nucleus())
165                         break;
166                 p = it->nucleus()->asCharInset();
167                 if (!p || p->code() != c)
168                         break;
169                 s += p->getChar();
170         }
171         return s;
172 }
173
174
175 MathArray MathArray::glueChars() const
176 {
177         MathArray ar;
178         const_iterator it = begin();
179         while (it != end()) {
180                 if (it->nucleus() && it->nucleus()->asCharInset()) {
181                         string s = charSequence(it, end());
182                         MathTextCodes c = it->nucleus()->asCharInset()->code();
183                         ar.push_back(MathAtom(new MathStringInset(s, c)));
184                         it += s.size();
185                 } else {
186                         ar.push_back(*it);
187                         ++it;
188                 }
189         }
190         return ar;
191 }
192
193
194 void MathArray::write(MathWriteInfo & wi) const
195 {
196         glueChars().write1(wi);
197 }
198
199
200 void MathArray::write1(MathWriteInfo & wi) const
201 {
202         for (const_iterator it = begin(); it != end(); ++it) {  
203                 MathInset * p = it->nucleus();
204                 if (!p)
205                         continue;
206                 if (MathScriptInset const * q = asScript(it)) {
207                         q->write(p, wi);
208                         ++it;
209                 } else {
210                         p->write(wi);
211                 }
212         }
213 }
214
215
216 void MathArray::writeNormal(ostream & os) const
217 {
218         for (const_iterator it = begin(); it != end(); ++it) {  
219                 MathInset * p = it->nucleus();
220                 if (!p)
221                         continue;
222                 if (MathScriptInset const * q = asScript(it)) {
223                         q->writeNormal(p, os);
224                         ++it;
225                 } else {
226                         p->writeNormal(os);
227                 }
228         }
229 }
230
231
232 void MathArray::validate(LaTeXFeatures & features) const
233 {
234         for (const_iterator it = begin(); it != end(); ++it)
235                 it->nucleus()->validate(features);
236 }
237
238
239 void MathArray::pop_back()
240 {       
241         if (!size()) {
242                 lyxerr << "pop_back from empty array!\n";
243                 return;
244         }
245         bf_.pop_back();
246 }
247
248
249 MathArray::const_iterator MathArray::begin() const
250 {
251         return bf_.begin();
252 }
253
254
255 MathArray::const_iterator MathArray::end() const
256 {
257         return bf_.end();
258 }
259
260
261 MathArray::iterator MathArray::begin()
262 {
263         return bf_.begin();
264 }
265
266
267 MathArray::iterator MathArray::end()
268 {
269         return bf_.end();
270 }