]> git.lyx.org Git - lyx.git/blob - src/counters.C
Alfredo's second patch
[lyx.git] / src / counters.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2001 The LyX Team.
8  *
9  *
10  * ====================================================== */
11
12 #include <config.h>
13
14 #include "counters.h"
15 #include "debug.h"
16
17 #include "support/lstrings.h"
18 #include "support/LAssert.h"
19
20 using std::endl;
21 using std::vector;
22
23
24 Counter::Counter()
25 {
26         reset();
27 }
28
29
30 void Counter::set(int v)
31 {
32         value_ = v;
33 }
34
35
36 void Counter::addto(int v)
37 {
38         value_ += v;
39 }
40
41
42 int Counter::value() const
43 {
44         return value_;
45 }
46
47
48 void Counter::step()
49 {
50         ++value_;
51 }
52
53
54 void Counter::reset()
55 {
56         value_ = 0;
57 }
58
59
60 string Counter::master() const
61 {
62         return master_;
63 }
64
65
66 void Counter::setMaster(string const & m)
67 {
68         master_ = m;
69 }
70
71
72
73 void Counters::newCounter(string const & newc)
74 {
75         // First check if newc already exist
76         CounterList::iterator cit = counterList.find(newc);
77         // if already exist give warning and return
78         if (cit != counterList.end()) {
79                 lyxerr << "The new counter already exists." << endl;
80                 return;
81         }
82         counterList[newc];
83 }
84
85
86 void Counters::newCounter(string const & newc, string const & masterc)
87 {
88         // First check if newc already exists
89         CounterList::iterator cit = counterList.find(newc);
90         // if already existant give warning and return
91         if (cit != counterList.end()) {
92                 lyxerr << "The new counter already exists." << endl;
93                 return;
94         }
95         // then check if masterc exists
96         CounterList::iterator it = counterList.find(masterc);
97         // if not give warning and return
98         if (it == counterList.end()) {
99                 lyxerr << "The master counter does not exist." << endl;
100                 return;
101         }
102
103         counterList[newc].setMaster(masterc);
104 }
105
106
107 void Counters::set(string const & ctr, int val)
108 {
109         CounterList::iterator it = counterList.find(ctr);
110         if (it == counterList.end()) {
111                 lyxerr << "set: Counter does not exist: " << ctr << endl;
112                 return;
113         }
114         it->second.set(val);
115 }
116
117
118 void Counters::addto(string const & ctr, int val)
119 {
120         CounterList::iterator it = counterList.find(ctr);
121         if (it == counterList.end()) {
122                 lyxerr << "addto: Counter does not exist: " << ctr << endl;
123                 return;
124         }
125         it->second.addto(val);
126 }
127
128
129 int Counters::value(string const & ctr) const
130 {
131         CounterList::const_iterator cit = counterList.find(ctr);
132         if (cit == counterList.end()) {
133                 lyxerr << "value: Counter does not exist: " << ctr << endl;
134                 return 0;
135         }
136         return cit->second.value();
137 }
138
139
140 void Counters::step(string const & ctr)
141 {
142         CounterList::iterator it = counterList.find(ctr);
143         if (it == counterList.end()) {
144                 lyxerr << "step: Counter does not exist: " << ctr << endl;
145                 return;
146         }
147
148         it->second.step();
149         it = counterList.begin();
150         CounterList::iterator end = counterList.end();
151         for (; it != end; ++it) {
152                 if (it->second.master() == ctr) {
153                         it->second.reset();
154                 }
155         }
156 }
157
158
159 void Counters::reset()
160 {
161         CounterList::iterator it = counterList.begin();
162         CounterList::iterator end = counterList.end();
163         for (; it != end; ++it) {
164                 it->second.reset();
165         }
166 }
167
168
169 void Counters::reset(string const & match)
170 {
171         lyx::Assert(!match.empty());
172
173         CounterList::iterator it = counterList.begin();
174         CounterList::iterator end = counterList.end();
175         for (; it != end; ++it) {
176                 if (it->first.find(match) != string::npos)
177                         it->second.reset();
178         }
179 }
180
181
182 void Counters::copy(Counters & from, Counters & to, string const & match)
183 {
184         CounterList::iterator it = counterList.begin();
185         CounterList::iterator end = counterList.end();
186         for (; it != end; ++it) {
187                 if (it->first.find(match) != string::npos || match == "") {
188                         to.set(it->first, from.value(it->first));
189                 }
190         }
191 }
192
193
194 namespace {
195
196 inline
197 char loweralphaCounter(int n)
198 {
199         if (n < 1 || n > 26)
200                 return '?';
201         else
202                 return 'a' + n - 1;
203 }
204
205
206 inline
207 char alphaCounter(int n)
208 {
209         if (n < 1 || n > 26)
210                 return '?';
211         else
212                 return 'A' + n - 1;
213 }
214
215
216 inline
217 char hebrewCounter(int n)
218 {
219         static const char hebrew[22] = {
220                 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è',
221                 'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö',
222                 '÷', 'ø', 'ù', 'ú'
223         };
224         if (n < 1 || n > 22)
225                 return '?';
226         else
227                 return hebrew[n-1];
228 }
229
230
231 inline
232 string const romanCounter(int n)
233 {
234         static char const * roman[20] = {
235                 "i",   "ii",  "iii", "iv", "v",
236                 "vi",  "vii", "viii", "ix", "x",
237                 "xi",  "xii", "xiii", "xiv", "xv",
238                 "xvi", "xvii", "xviii", "xix", "xx"
239         };
240         if (n < 1 || n > 20)
241                 return "??";
242         else
243                 return roman[n-1];
244 }
245
246 } // namespace anon
247
248
249 string Counters::labelItem(string const & ctr,
250                            string const & numbertype,
251                            string const & langtype,
252                            bool first)
253 {
254         ostringstream s;
255         ostringstream o;
256
257         CounterList::iterator it = counterList.find(ctr);
258         if (it == counterList.end()) {
259                 lyxerr << "Counter does not exist." << endl;
260                 return string();
261         }
262
263         if (!first) {
264                 s << '.' << value(ctr);
265         } else {
266                 if (numbertype == "sectioning" || numbertype == "appendix") {
267                         if (numbertype == "appendix") {
268                                 if (langtype == "hebrew") {
269                                         o << hebrewCounter(value(ctr));
270                                 } else {
271                                         o << alphaCounter(value(ctr));
272                                 }
273                         } else o << value(ctr);
274                 }
275                 s << o.str();
276         }
277
278         return STRCONV(s.str());
279 }
280
281
282 string Counters::numberLabel(string const & ctr,
283                              string const & numbertype,
284                              string const & langtype,
285                              int head)
286 {
287         ostringstream s;
288
289         if (numbertype == "sectioning" || numbertype == "appendix") {
290                 if (ctr == "chapter" && head == 0) {
291                         s << labelItem("chapter", numbertype, langtype, true);
292                 } else if (ctr == "section" && head <= 1) {
293                         s << numberLabel("chapter", numbertype, langtype, head)
294                           << labelItem("section", numbertype, langtype, head == 1);
295                 } else if (ctr == "subsection" && head <= 2) {
296                         s << numberLabel("section", numbertype, langtype, head)
297                           << labelItem("subsection", numbertype, langtype, head == 2);
298                 } else if (ctr == "subsubsection" && head <= 3) {
299                         s << numberLabel("subsection", numbertype, langtype, head)
300                           << labelItem("subsubsection", numbertype, langtype, head == 3);
301                 } else if (ctr == "paragraph" && head <= 4) {
302                         s << numberLabel("subsubsection", numbertype, langtype, head)
303                           << labelItem("paragraph", numbertype, langtype, head == 4);
304                 } else if (ctr == "subparagraph" && head <= 5) {
305                         s << numberLabel("paragraph", numbertype, langtype, head)
306                           << labelItem("subparagraph", numbertype, langtype, head == 5);
307                 } else if (ctr == "figure" || ctr == "table") {
308                         // figure, table, ...
309                         lyxerr << "Counter:" << ctr << endl;
310                         s << numberLabel("chapter", numbertype, langtype, head)
311                           << labelItem(ctr, numbertype, langtype, head == 1);
312                 }
313
314         } else if (numbertype == "enumeration") {
315                 ostringstream ei;
316                 ostringstream eii;
317                 ostringstream eiii;
318                 ostringstream eiv;
319
320                 if (langtype == "hebrew") {
321                         ei << '.' << value("enumi");
322                         eii << '(' << hebrewCounter(value("enumii")) << ')';
323                         eiii << '.' << romanCounter(value("enumiii"));
324                         eiv << '.' << alphaCounter(value("enumiv"));
325                 } else {
326                         ei << value("enumi") << '.';
327                         eii << '(' << loweralphaCounter(value("enumii")) << ')';
328                         eiii << romanCounter(value("enumiii")) << '.';
329                         eiv << alphaCounter(value("enumiv")) << '.';
330                 }
331                 if (ctr == "enumii") {
332                         s << eii.str();
333                 } else if (ctr == "enumi") {
334                         s << ei.str();
335                 } else if (ctr == "enumiii") {
336                         s << eiii.str();
337                 } else if (ctr == "enumiv") {
338                         s << eiv.str();
339                 }
340         }
341
342         return STRCONV(s.str());
343 }