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