]> git.lyx.org Git - lyx.git/blob - src/insets/InsetCounter.cpp
Use LaTeXName of counter in LaTeX output.
[lyx.git] / src / insets / InsetCounter.cpp
1 /**
2  * \file InsetCounter.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Richard Kimberly Heck
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include <config.h>
11
12 #include "InsetCounter.h"
13
14 #include "Buffer.h"
15 #include "BufferParams.h"
16 #include "Counters.h"
17 #include "LaTeXFeatures.h"
18 #include "output_xhtml.h"
19 #include "xml.h"
20 #include "texstream.h"
21 #include "TextClass.h"
22
23 #include "support/convert.h"
24 #include "support/counter_reps.h"
25 #include "support/docstream.h"
26 #include "support/gettext.h"
27 #include "support/lassert.h"
28 #include "support/lstrings.h"
29
30 #include <map>
31
32 /*
33 #include "Cursor.h"
34 #include "DispatchResult.h"
35 #include "Language.h"
36 #include "LyX.h"
37 #include "ParIterator.h"
38 #include "TocBackend.h"
39
40 #include "support/debug.h"
41 #include "support/textutils.h"
42 */
43
44 using namespace lyx::support;
45 using namespace std;
46
47 namespace lyx {
48
49
50 InsetCounter::InsetCounter(Buffer * buf, InsetCommandParams const & p)
51         : InsetCommand(buf, p)
52 {}
53
54
55 InsetCounter::InsetCounter(InsetCounter const & ir)
56         : InsetCommand(ir)
57 {}
58
59
60 const vector<pair<string, string>> InsetCounter::counterTable =
61 {
62         {"set", N_("Set counter to ...")},
63         {"addto", N_("Increase counter by ...")},
64         {"reset", N_("Reset counter to 0")},
65         {"save", N_("Save current counter value")},
66         {"restore", N_("Restore saved counter value")},
67 };
68
69
70 bool InsetCounter::isCompatibleCommand(string const & s)
71 {
72         for (auto & i : counterTable) {
73                 if (i.first == s)
74                         return true;
75         }
76         return false;
77 }
78
79
80 ParamInfo const & InsetCounter::findInfo(string const & /* cmdName */)
81 {
82         static ParamInfo param_info_;
83         if (param_info_.empty()) {
84                 param_info_.add("counter", ParamInfo::LYX_INTERNAL);
85                 param_info_.add("value", ParamInfo::LYX_INTERNAL);
86                 param_info_.add("lyxonly", ParamInfo::LYX_INTERNAL);
87         }
88         return param_info_;
89 }
90
91
92 void InsetCounter::latex(otexstream & os, OutputParams const &) const
93 {
94         bool const lyxonly = lowercase(getParam("lyxonly")) == "true";
95         if (lyxonly)
96                 return;
97
98         string const cmd = getCmdName();
99         docstring const & cntr = getParam("counter");
100         Counters & cnts = buffer().params().documentClass().counters();
101         docstring const & latexname = cnts.latexName(cntr);
102
103         if (cmd == "set") {
104                 docstring const & val = getParam("value");
105                 os << "\\setcounter{" << latexname << "}{" << val << "}";
106         } else if (cmd == "addto") {
107                 docstring const & val = getParam("value");
108                 os << "\\addtocounter{" << latexname << "}{" << val << "}";
109         } else if (cmd == "reset") {
110                 os << "\\setcounter{" << latexname << "}{0}";
111         } else if (cmd == "save") {
112                 cnts.saveValue(cntr);
113                 os << "\\setcounter{" << lyxSaveCounter()
114                    << "}{\\value{" << latexname << "}}";
115         } else if (cmd == "restore") {
116                 cnts.restoreValue(cntr);
117                 os << "\\setcounter{" << latexname
118                    << "}{\\value{" << lyxSaveCounter() << "}}";
119         }
120 }
121
122
123 void InsetCounter::toString(odocstream & os) const
124 {
125         os << "[Counter " << from_utf8(getCmdName()) << ": "
126            <<  getParam("counter") << "]";
127 }
128
129
130 int InsetCounter::plaintext(odocstringstream & os,
131         OutputParams const &, size_t) const
132 {
133         toString(os);
134         return 0;
135 }
136
137
138 #if 0
139 // save this code until we get it working in InsetInfo
140 const map<string, string> InsetCounter::valueTable =
141 {
142         {"Roman", N_("Roman Uppercase")},
143         {"roman", N_("Roman Lowercase")},
144         {"Alpha", N_("Uppercase Letter")},
145         {"alpha", N_("Lowercase Letter")},
146         {"arabic", N_("Arabic Numeral")}
147 };
148
149
150 docstring InsetCounter::value() const {
151         docstring const & cnt = getParam("counter");
152         string const & vtype = getCmdName();
153         int const val = buffer().params().documentClass().counters().value(cnt);
154         if (vtype   == "Roman")
155                 return romanCounter(val);
156         if (vtype   == "roman")
157                 return lowerromanCounter(val);
158         if (vtype   == "Alpha")
159                 return docstring(1, alphaCounter(val));
160         if (vtype   == "alpha")
161                 return docstring(1, loweralphaCounter(val));
162         if (vtype   == "arabic")
163                 return convert<docstring>(val);
164         LATTEST(false);
165         return empty_docstring();
166 }
167 #endif
168
169 void InsetCounter::trackCounters(string const & cmd) const
170 {
171         Counters & cnts = buffer().params().documentClass().counters();
172         docstring cntr = getParam("counter");
173         if (cmd == "set") {
174                 docstring const & val = getParam("value");
175                 cnts.set(cntr, convert<int>(val));
176         } else if (cmd == "addto") {
177                 docstring const & val = getParam("value");
178                 cnts.addto(cntr, convert<int>(val));
179         } else if (cmd == "reset") {
180                 cnts.reset(cntr);
181         } else if (cmd == "save") {
182                 cnts.saveValue(cntr);
183         } else if (cmd == "restore") {
184                 cnts.restoreValue(cntr);
185         }
186 }
187
188 void InsetCounter::docbook(XMLStream &, OutputParams const &) const
189 {
190         // Here, we need to track counter values ourselves,
191         // since unlike in the LaTeX case, there is no external
192         // mechanism for doing that.
193         trackCounters(getCmdName());
194 }
195
196
197 docstring InsetCounter::xhtml(XMLStream &, OutputParams const &) const
198 {
199         // Here, we need to track counter values ourselves,
200         // since unlike in the LaTeX case, there is no external
201         // mechanism for doing that.
202         trackCounters(getCmdName());
203         return docstring();
204 }
205
206
207 void InsetCounter::updateBuffer(ParIterator const &, UpdateType, bool const)
208 {
209         string const cmd = getCmdName();
210         docstring cntr = getParam("counter");
211         Counters & cnts = buffer().params().documentClass().counters();
212         string label;
213         for (auto & i : counterTable) {
214                 if (i.first == cmd)
215                         label = i.second;
216         }
217         LASSERT(!label.empty(), return);
218         docstring const tlabel = translateIfPossible(from_ascii(label));
219
220         docstring guiname = translateIfPossible(cnts.guiName(cntr));
221         if (cmd == "set") {
222                 docstring const & val = getParam("value");
223                 cnts.set(cntr, convert<int>(val));
224                 screen_label_ = bformat(_("Counter: Set %1$s"), guiname);
225                 tooltip_ = bformat(_("Set value of counter %1$s to %2$s"), cntr, val);
226         } else if (cmd == "addto") {
227                 docstring const & val = getParam("value");
228                 cnts.addto(cntr, convert<int>(val));
229                 screen_label_ = bformat(_("Counter: Add to %1$s"), guiname);
230                 tooltip_ = bformat(_("Add %1$s to value of counter %2$s"), val, cntr);
231         } else if (cmd == "reset") {
232                 cnts.reset(cntr);
233                 screen_label_ = bformat(_("Counter: Reset %1$s"), guiname);
234                 tooltip_ = bformat(_("Reset value of counter %1$s"), cntr);
235         } else if (cmd == "save") {
236                 cnts.saveValue(cntr);
237                 screen_label_ = bformat(_("Counter: Save %1$s"), guiname);
238                 tooltip_ = bformat(_("Save value of counter %1$s"), cntr);
239         } else if (cmd == "restore") {
240                 cnts.restoreValue(cntr);
241                 screen_label_ = bformat(_("Counter: Restore %1$s"), guiname);
242                 tooltip_ = bformat(_("Restore value of counter %1$s"), cntr);
243         }
244 }
245
246
247 docstring InsetCounter::lyxSaveCounter() const
248 {
249         docstring cntr = getParam("counter");
250         return from_ascii("LyXSave") + cntr;
251 }
252
253
254 void InsetCounter::validate(LaTeXFeatures & features) const
255 {
256         // create save counter if needed
257         string const cmd = getCmdName();
258         docstring const lyxonly = getParam("lyxonly");
259         if ((cmd == "save" || cmd == "restore") && lyxonly != "true") {
260                 features.addPreambleSnippet(from_ascii("\\newcounter{") + lyxSaveCounter() + "}");
261         }
262     InsetCommand::validate(features);
263 }
264
265
266 string InsetCounter::contextMenuName() const
267 {
268     return "context-counter";
269 }
270 } // namespace lyx