]> git.lyx.org Git - lyx.git/blob - src/counters.C
cleanup some debug messages
[lyx.git] / src / counters.C
1 /**
2  * \file counters.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Martin Vermeer
8  * \author André Pönitz
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "counters.h"
16 #include "debug.h"
17
18 #include "support/lstrings.h"
19 #include "support/convert.h"
20
21 #include <boost/assert.hpp>
22
23 #include <sstream>
24
25 using std::endl;
26 using std::ostringstream;
27 using std::string;
28
29
30 Counter::Counter()
31 {
32         reset();
33 }
34
35
36 void Counter::set(int v)
37 {
38         value_ = v;
39 }
40
41
42 void Counter::addto(int v)
43 {
44         value_ += v;
45 }
46
47
48 int Counter::value() const
49 {
50         return value_;
51 }
52
53
54 void Counter::step()
55 {
56         ++value_;
57 }
58
59
60 void Counter::reset()
61 {
62         value_ = 0;
63 }
64
65
66 string Counter::master() const
67 {
68         return master_;
69 }
70
71
72 void Counter::setMaster(string const & m)
73 {
74         master_ = m;
75 }
76
77
78 void Counters::newCounter(string const & newc)
79 {
80         // First check if newc already exist
81         CounterList::iterator const cit = counterList.find(newc);
82         // if already exist give warning and return
83         if (cit != counterList.end()) {
84                 lyxerr << "New counter already exists: " << newc << endl;
85                 return;
86         }
87         counterList[newc];
88 }
89
90
91 void Counters::newCounter(string const & newc, string const & masterc)
92 {
93         // First check if newc already exists
94         CounterList::iterator const cit = counterList.find(newc);
95         // if already existant give warning and return
96         if (cit != counterList.end()) {
97                 lyxerr << "New counter already exists: " << newc << endl;
98                 return;
99         }
100         // then check if masterc exists
101         CounterList::iterator const it = counterList.find(masterc);
102         // if not give warning and return
103         if (it == counterList.end()) {
104                 lyxerr << "Master counter does not exist: " << masterc << endl;
105                 return;
106         }
107
108         counterList[newc].setMaster(masterc);
109 }
110
111
112 void Counters::set(string const & ctr, int const val)
113 {
114         CounterList::iterator const it = counterList.find(ctr);
115         if (it == counterList.end()) {
116                 lyxerr << "set: Counter does not exist: " << ctr << endl;
117                 return;
118         }
119         it->second.set(val);
120 }
121
122
123 void Counters::addto(string const & ctr, int const val)
124 {
125         CounterList::iterator const it = counterList.find(ctr);
126         if (it == counterList.end()) {
127                 lyxerr << "addto: Counter does not exist: " << ctr << endl;
128                 return;
129         }
130         it->second.addto(val);
131 }
132
133
134 int Counters::value(string const & ctr) const
135 {
136         CounterList::const_iterator const cit = counterList.find(ctr);
137         if (cit == counterList.end()) {
138                 lyxerr << "value: Counter does not exist: " << ctr << endl;
139                 return 0;
140         }
141         return cit->second.value();
142 }
143
144
145 void Counters::step(string const & ctr)
146 {
147         CounterList::iterator it = counterList.find(ctr);
148         if (it == counterList.end()) {
149                 lyxerr << "step: Counter does not exist: " << ctr << endl;
150                 return;
151         }
152
153         it->second.step();
154         it = counterList.begin();
155         CounterList::iterator const end = counterList.end();
156         for (; it != end; ++it) {
157                 if (it->second.master() == ctr) {
158                         it->second.reset();
159                 }
160         }
161 }
162
163
164 void Counters::reset()
165 {
166         CounterList::iterator it = counterList.begin();
167         CounterList::iterator const end = counterList.end();
168         for (; it != end; ++it) {
169                 it->second.reset();
170         }
171 }
172
173
174 void Counters::reset(string const & match)
175 {
176         BOOST_ASSERT(!match.empty());
177
178         CounterList::iterator it = counterList.begin();
179         CounterList::iterator end = counterList.end();
180         for (; it != end; ++it) {
181                 if (it->first.find(match) != string::npos)
182                         it->second.reset();
183         }
184 }
185
186
187 void Counters::copy(Counters & from, Counters & to, string const & match)
188 {
189         CounterList::iterator it = counterList.begin();
190         CounterList::iterator end = counterList.end();
191         for (; it != end; ++it) {
192                 if (it->first.find(match) != string::npos || match == "") {
193                         to.set(it->first, from.value(it->first));
194                 }
195         }
196 }
197
198
199 namespace {
200
201 char loweralphaCounter(int const n)
202 {
203         if (n < 1 || n > 26)
204                 return '?';
205         return 'a' + n - 1;
206 }
207
208
209 char alphaCounter(int const n)
210 {
211         if (n < 1 || n > 26)
212                 return '?';
213         return 'A' + n - 1;
214 }
215
216
217 char hebrewCounter(int const n)
218 {
219         static const char hebrew[22] = {
220                 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è',
221                 'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö',
222                 '÷', 'ø', 'ù', 'ú'
223         };
224
225         if (n < 1 || n > 22)
226                 return '?';
227         return hebrew[n - 1];
228 }
229
230
231 string const lowerromanCounter(int const n)
232 {
233         static char const * const roman[20] = {
234                 "i",   "ii",  "iii", "iv", "v",
235                 "vi",  "vii", "viii", "ix", "x",
236                 "xi",  "xii", "xiii", "xiv", "xv",
237                 "xvi", "xvii", "xviii", "xix", "xx"
238         };
239
240         if (n < 1 || n > 20)
241                 return "??";
242         return roman[n - 1];
243 }
244
245
246 string const romanCounter(int const n)
247 {
248         static char const * const roman[20] = {
249                 "I",   "II",  "III", "IV", "V",
250                 "VI",  "VII", "VIII", "IX", "X",
251                 "XI",  "XII", "XIII", "XIV", "XV",
252                 "XVI", "XVII", "XVIII", "XIX", "XX"
253         };
254
255         if (n < 1 || n > 20)
256                 return "??";
257         return roman[n - 1];
258 }
259
260 } // namespace anon
261
262
263 string Counters::labelItem(string const & ctr, string const & numbertype)
264 {
265         if (counterList.find(ctr) == counterList.end()) {
266                 lyxerr << "Counter " << ctr << " does not exist." << endl;
267                 return string();
268         }
269
270         if (numbertype == "hebrew")
271                 return string(1, hebrewCounter(value(ctr)));
272
273         if (numbertype == "alph")
274                 return string(1, loweralphaCounter(value(ctr)));
275
276         if (numbertype == "Alph")
277                 return string(1, alphaCounter(value(ctr)));
278
279         if (numbertype == "roman")
280                 return lowerromanCounter(value(ctr));
281
282         if (numbertype == "Roman")
283                 return romanCounter(value(ctr));
284
285         return convert<string>(value(ctr));
286 }
287
288
289 string Counters::counterLabel(string const & format)
290 {
291         string label = format;
292         while (true) {
293 #ifdef WITH_WARNINGS
294 #warning Using boost::regex or boost::spirit would make this code a lot simpler... (Lgb)
295 #endif
296
297                 size_t const i = label.find('\\', 0);
298                 if (i == string::npos)
299                         break;
300                 size_t const j = label.find('{', i + 1);
301                 if (j == string::npos)
302                         break;
303                 size_t const k = label.find('}', j + 1);
304                 if (k == string::npos)
305                         break;
306                 string const numbertype(label, i + 1, j - i - 1);
307                 string const counter(label, j + 1, k - j - 1);
308                 string const rep = labelItem(counter, numbertype);
309                 label = string(label, 0, i) + rep + string(label, k + 1, string::npos);
310                 //lyxerr << "  : " << " (" << counter  << ","
311                 //      << numbertype << ") -> " << label << endl;
312         }
313         //lyxerr << "counterLabel: " << format  << " -> "       << label << endl;
314         return label;
315 }