]> git.lyx.org Git - features.git/blob - src/insets/InsetNomencl.cpp
InsetNomencl.cpp: assure that the label width is never below the predefined value...
[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         ParagraphList::const_iterator it = buffer.paragraphs().begin();
175         ParagraphList::const_iterator end = buffer.paragraphs().end();
176
177         for (; it != end; ++it) {
178                 if (it->insetList().empty())
179                         continue;
180                 InsetList::const_iterator iit = it->insetList().begin();
181                 InsetList::const_iterator eend = it->insetList().end();
182                 for (; iit != eend; ++iit) {
183                         Inset * inset = iit->inset;
184                         if (inset->lyxCode() != NOMENCL_CODE)
185                                 continue;
186                         nomencl = static_cast<InsetNomencl const *>(inset);
187                         docstring const symbol = nomencl->getParam("symbol");
188                         // we can only check for the number of characters, since it is
189                         // impossible to get the info that "iiiii" is smaller than "WW"
190                         // we therefore output w times "W" as string ("W" is always the
191                         // widest character)
192                         int const wx = symbol.size();
193                         if (wx > w)
194                                 w = wx;
195                 }
196         }
197         // return the widest symbol as w times a "W"
198         for (int n = 1; n <= w; ++n)
199                 symb = symb + "W";
200         return symb;
201 }
202
203
204 int InsetPrintNomencl::latex(odocstream & os, OutputParams const &) const
205 {
206         int lines = 0;
207         docstring widest = nomenclWidest(buffer());
208         // set the label width via nomencl's command \nomlabelwidth
209         // this must be output before the command \printnomenclature
210         if (!widest.empty()) {
211                 // assure that the width is never below the predefined value of 1 cm
212                 os << "\\settowidth{\\nomlabelwidth}{" << widest <<"}\n";
213                 os << "\\ifthenelse{%\n  \\lengthtest{\\nomlabelwidth < 1cm}}\n";
214                 os << " {\\setlength{\\nomlabelwidth}{1cm}}\n {}\n";
215                 ++lines;
216         }
217         // output the command \printnomenclature
218         os << getCommand();
219         return lines;
220 }
221
222
223 void InsetPrintNomencl::validate(LaTeXFeatures & features) const
224 {
225         features.require("nomencl");
226         // needed for InsetPrintNomencl::latex
227         features.require("ifthen");
228 }
229
230
231 InsetCode InsetPrintNomencl::lyxCode() const
232 {
233         return NOMENCL_PRINT_CODE;
234 }
235
236
237 } // namespace lyx