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