]> git.lyx.org Git - features.git/blob - src/insets/InsetNomencl.cpp
InsetNomencl: calculate the needed symbol width for \printnomenclature, fixes #5909
[features.git] / src / insets / InsetNomencl.cpp
1 /**
2  * \file InsetNomencl.cpp
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 O. U. Baran
8  * \author Uwe Stöhr
9  * \author Jürgen Spitzmüller
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13 #include <config.h>
14
15 #include "InsetNomencl.h"
16 #include "InsetNote.h"
17
18 #include "Buffer.h"
19 #include "DispatchResult.h"
20 #include "FuncRequest.h"
21 #include "InsetIterator.h"
22 #include "InsetList.h"
23 #include "LaTeXFeatures.h"
24 #include "MetricsInfo.h"
25 #include "sgml.h"
26
27 #include "support/docstream.h"
28 #include "support/gettext.h"
29 #include "support/lstrings.h"
30
31 using namespace std;
32 using namespace lyx::support;
33
34 namespace lyx {
35
36
37 /////////////////////////////////////////////////////////////////////
38 //
39 // InsetNomencl
40 //
41 /////////////////////////////////////////////////////////////////////
42
43 InsetNomencl::InsetNomencl(InsetCommandParams const & p)
44         : InsetCommand(p, "nomenclature"),
45           nomenclature_entry_id(sgml::uniqueID(from_ascii("nomen")))
46 {}
47
48
49 ParamInfo const & InsetNomencl::findInfo(string const & /* cmdName */)
50 {
51         static ParamInfo param_info_;
52         if (param_info_.empty()) {
53                 param_info_.add("prefix", ParamInfo::LATEX_OPTIONAL);
54                 param_info_.add("symbol", ParamInfo::LATEX_REQUIRED);
55                 param_info_.add("description", ParamInfo::LATEX_REQUIRED);
56         }
57         return param_info_;
58 }
59
60
61 docstring InsetNomencl::screenLabel() const
62 {
63         size_t const maxLabelChars = 25;
64
65         docstring label = _("Nom: ") + getParam("symbol");
66         if (label.size() > maxLabelChars) {
67                 label.erase(maxLabelChars - 3);
68                 label += "...";
69         }
70         return label;
71 }
72
73
74 docstring InsetNomencl::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y*/) const
75 {
76         docstring tip = _("Nomenclature Symbol: ") + getParam("symbol") + "\n";
77         tip += _("Description: ") + "\t"
78                 + subst(getParam("description"), from_ascii("\\\\"), from_ascii("\n\t"));
79         if (!getParam("prefix").empty())
80                 tip += "\n" + _("Sorting: ") + getParam("prefix");
81         return tip;
82 }
83
84
85
86 int InsetNomencl::docbook(odocstream & os, OutputParams const &) const
87 {
88         os << "<glossterm linkend=\"" << nomenclature_entry_id << "\">"
89            << sgml::escapeString(getParam("symbol"))
90            << "</glossterm>";
91         return 0;
92 }
93
94
95 int InsetNomencl::docbookGlossary(odocstream & os) const
96 {
97         os << "<glossentry id=\"" << nomenclature_entry_id << "\">\n"
98            << "<glossterm>"
99            << sgml::escapeString(getParam("symbol"))
100            << "</glossterm>\n"
101            << "<glossdef><para>"
102            << sgml::escapeString(getParam("description"))
103            << "</para></glossdef>\n"
104            <<"</glossentry>\n";
105         return 4;
106 }
107
108
109 void InsetNomencl::validate(LaTeXFeatures & features) const
110 {
111         features.require("nomencl");
112 }
113
114
115 /////////////////////////////////////////////////////////////////////
116 //
117 // InsetPrintNomencl
118 //
119 /////////////////////////////////////////////////////////////////////
120
121 InsetPrintNomencl::InsetPrintNomencl(InsetCommandParams const & p)
122         : InsetCommand(p, "printnomenclature")
123 {}
124
125
126 ParamInfo const & InsetPrintNomencl::findInfo(string const & /* cmdName */)
127 {
128         // there are no parameters to give because the symbol width is set via
129         // nomencl's \nomlabelwidth in InsetPrintNomencl::latex and not as
130         // optional parameter of \printnomenclature
131         static ParamInfo param_info_;
132         return param_info_;
133 }
134
135
136 docstring InsetPrintNomencl::screenLabel() const
137 {
138         return _("Nomenclature");
139 }
140
141
142 int InsetPrintNomencl::docbook(odocstream & os, OutputParams const &) const
143 {
144         os << "<glossary>\n";
145         int newlines = 2;
146         InsetIterator it = inset_iterator_begin(buffer().inset());
147         while (it) {
148                 if (it->lyxCode() == NOMENCL_CODE) {
149                         newlines += static_cast<InsetNomencl const &>(*it).docbookGlossary(os);
150                         ++it;
151                 } else if (!it->producesOutput()) {
152                         // Ignore contents of insets that are not in output
153                         size_t const depth = it.depth();
154                         ++it;
155                         while (it.depth() > depth)
156                                 ++it;
157                 } else {
158                         ++it;
159                 }
160         }
161         os << "</glossary>\n";
162         return newlines;
163 }
164
165
166 docstring nomenclWidest(Buffer const & buffer)
167 {
168         // nomenclWidest() determines and returns the widest used nomenclature
169         // symbol in the document
170
171         int w = 0;
172         docstring symb;
173         InsetNomencl const * nomencl = 0;
174
175         ParagraphList::const_iterator it = buffer.paragraphs().begin();
176         ParagraphList::const_iterator end = buffer.paragraphs().end();
177
178         for (; it != end; ++it) {
179                 if (it->insetList().empty())
180                         continue;
181                 InsetList::const_iterator iit = it->insetList().begin();
182                 InsetList::const_iterator eend = it->insetList().end();
183                 for (; iit != eend; ++iit) {
184                         Inset * inset = iit->inset;
185                         if (inset->lyxCode() != NOMENCL_CODE)
186                                 continue;
187                         nomencl = static_cast<InsetNomencl const *>(inset);
188                         docstring const symbol = nomencl->getParam("symbol");
189                         int const wx = symbol.size();
190                         if (wx > w) {
191                                 w = wx;
192                                 symb = symbol;
193                         }
194                 }
195         }
196
197         // return the widest symbol
198         return symb;
199 }
200
201
202 int InsetPrintNomencl::latex(odocstream & os, OutputParams const &) const
203 {
204         int lines = 0;
205         // this must be output before the command \printnomenclature
206         docstring widest = nomenclWidest(buffer());
207         if (!widest.empty()) {
208                 // set the label width via nomencl's command \nomlabelwidth
209                 os << "\\settowidth{\\nomlabelwidth}{";
210                 os << widest <<"}\n";
211                 ++lines;
212         }
213         // output the command \printnomenclature
214         os << getCommand();
215         return lines;
216 }
217
218
219 void InsetPrintNomencl::validate(LaTeXFeatures & features) const
220 {
221         features.require("nomencl");
222 }
223
224
225 InsetCode InsetPrintNomencl::lyxCode() const
226 {
227         return NOMENCL_PRINT_CODE;
228 }
229
230
231 } // namespace lyx