]> git.lyx.org Git - lyx.git/blob - src/counters.C
Replace 'using namespace abc;' with 'using abc::xyz;'
[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  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "counters.h"
15
16 #include "debug.h"
17
18 #include "support/lstrings.h"
19
20 #include <boost/assert.hpp>
21
22 #include "support/std_sstream.h"
23
24 using std::endl;
25
26 using std::ostringstream;
27
28
29 Counter::Counter()
30 {
31         reset();
32 }
33
34
35 void Counter::set(int v)
36 {
37         value_ = v;
38 }
39
40
41 void Counter::addto(int v)
42 {
43         value_ += v;
44 }
45
46
47 int Counter::value() const
48 {
49         return value_;
50 }
51
52
53 void Counter::step()
54 {
55         ++value_;
56 }
57
58
59 void Counter::reset()
60 {
61         value_ = 0;
62 }
63
64
65 string Counter::master() const
66 {
67         return master_;
68 }
69
70
71 void Counter::setMaster(string const & m)
72 {
73         master_ = m;
74 }
75
76
77
78 void Counters::newCounter(string const & newc)
79 {
80         // First check if newc already exist
81         CounterList::iterator cit = counterList.find(newc);
82         // if already exist give warning and return
83         if (cit != counterList.end()) {
84                 lyxerr << "The new counter already exists." << 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 cit = counterList.find(newc);
95         // if already existant give warning and return
96         if (cit != counterList.end()) {
97                 lyxerr << "The new counter already exists." << endl;
98                 return;
99         }
100         // then check if masterc exists
101         CounterList::iterator it = counterList.find(masterc);
102         // if not give warning and return
103         if (it == counterList.end()) {
104                 lyxerr << "The master counter does not exist." << endl;
105                 return;
106         }
107
108         counterList[newc].setMaster(masterc);
109 }
110
111
112 void Counters::set(string const & ctr, int val)
113 {
114         CounterList::iterator 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 val)
124 {
125         CounterList::iterator 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 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 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 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 inline
202 char loweralphaCounter(int n)
203 {
204         if (n < 1 || n > 26)
205                 return '?';
206         else
207                 return 'a' + n - 1;
208 }
209
210
211 inline
212 char alphaCounter(int n)
213 {
214         if (n < 1 || n > 26)
215                 return '?';
216         else
217                 return 'A' + n - 1;
218 }
219
220
221 inline
222 char hebrewCounter(int n)
223 {
224         static const char hebrew[22] = {
225                 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è',
226                 'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö',
227                 '÷', 'ø', 'ù', 'ú'
228         };
229         if (n < 1 || n > 22)
230                 return '?';
231         else
232                 return hebrew[n-1];
233 }
234
235
236 inline
237 string const romanCounter(int n)
238 {
239         static char const * roman[20] = {
240                 "i",   "ii",  "iii", "iv", "v",
241                 "vi",  "vii", "viii", "ix", "x",
242                 "xi",  "xii", "xiii", "xiv", "xv",
243                 "xvi", "xvii", "xviii", "xix", "xx"
244         };
245         if (n < 1 || n > 20)
246                 return "??";
247         else
248                 return roman[n-1];
249 }
250
251 } // namespace anon
252
253
254 string Counters::labelItem(string const & ctr,
255                            string const & numbertype,
256                            string const & langtype,
257                            bool first)
258 {
259         ostringstream s;
260         ostringstream o;
261
262         CounterList::iterator it = counterList.find(ctr);
263         if (it == counterList.end()) {
264                 lyxerr << "Counter does not exist." << endl;
265                 return string();
266         }
267
268         if (!first) {
269                 s << '.' << value(ctr);
270         } else {
271                 if (numbertype == "sectioning" || numbertype == "appendix") {
272                         if (numbertype == "appendix") {
273                                 if (langtype == "hebrew") {
274                                         o << hebrewCounter(value(ctr));
275                                 } else {
276                                         o << alphaCounter(value(ctr));
277                                 }
278                         } else o << value(ctr);
279                 }
280                 s << o.str();
281         }
282
283         return STRCONV(s.str());
284 }
285
286
287 string Counters::numberLabel(string const & ctr,
288                              string const & numbertype,
289                              string const & langtype,
290                              int head)
291 {
292         ostringstream s;
293
294         if (numbertype == "sectioning" || numbertype == "appendix") {
295                 if (ctr == "chapter" && head == 0) {
296                         s << labelItem("chapter", numbertype, langtype, true);
297                 } else if (ctr == "section" && head <= 1) {
298                         s << numberLabel("chapter", numbertype, langtype, head)
299                           << labelItem("section", numbertype, langtype, head == 1);
300                 } else if (ctr == "subsection" && head <= 2) {
301                         s << numberLabel("section", numbertype, langtype, head)
302                           << labelItem("subsection", numbertype, langtype, head == 2);
303                 } else if (ctr == "subsubsection" && head <= 3) {
304                         s << numberLabel("subsection", numbertype, langtype, head)
305                           << labelItem("subsubsection", numbertype, langtype, head == 3);
306                 } else if (ctr == "paragraph" && head <= 4) {
307                         s << numberLabel("subsubsection", numbertype, langtype, head)
308                           << labelItem("paragraph", numbertype, langtype, head == 4);
309                 } else if (ctr == "subparagraph" && head <= 5) {
310                         s << numberLabel("paragraph", numbertype, langtype, head)
311                           << labelItem("subparagraph", numbertype, langtype, head == 5);
312                 } else if (ctr == "figure" || ctr == "table") {
313                         // figure, table, ...
314                         lyxerr << "Counter:" << ctr << endl;
315                         s << numberLabel("chapter", numbertype, langtype, head)
316                           << labelItem(ctr, numbertype, langtype, head == 1);
317                 }
318
319         } else if (numbertype == "enumeration") {
320                 ostringstream ei;
321                 ostringstream eii;
322                 ostringstream eiii;
323                 ostringstream eiv;
324
325                 if (langtype == "hebrew") {
326                         ei << '.' << value("enumi");
327                         eii << '(' << hebrewCounter(value("enumii")) << ')';
328                         eiii << '.' << romanCounter(value("enumiii"));
329                         eiv << '.' << alphaCounter(value("enumiv"));
330                 } else {
331                         ei << value("enumi") << '.';
332                         eii << '(' << loweralphaCounter(value("enumii")) << ')';
333                         eiii << romanCounter(value("enumiii")) << '.';
334                         eiv << alphaCounter(value("enumiv")) << '.';
335                 }
336                 if (ctr == "enumii") {
337                         s << eii.str();
338                 } else if (ctr == "enumi") {
339                         s << ei.str();
340                 } else if (ctr == "enumiii") {
341                         s << eiii.str();
342                 } else if (ctr == "enumiv") {
343                         s << eiv.str();
344                 }
345         }
346
347         return STRCONV(s.str());
348 }