]> git.lyx.org Git - features.git/blob - src/insets/InsetNomencl.cpp
file format change due to r29770.
[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         // The symbol width is set via nomencl's \nomlabelwidth in 
129         // InsetPrintNomencl::latex and not as optional parameter of
130         // \printnomenclature
131         static ParamInfo param_info_;
132         if (param_info_.empty()) {
133                 // how is the width set?
134                 // values: none|auto
135                 param_info_.add("set_width", ParamInfo::LYX_INTERNAL);
136         }
137         return param_info_;
138 }
139
140
141 docstring InsetPrintNomencl::screenLabel() const
142 {
143         return _("Nomenclature");
144 }
145
146
147 int InsetPrintNomencl::docbook(odocstream & os, OutputParams const &) const
148 {
149         os << "<glossary>\n";
150         int newlines = 2;
151         InsetIterator it = inset_iterator_begin(buffer().inset());
152         while (it) {
153                 if (it->lyxCode() == NOMENCL_CODE) {
154                         newlines += static_cast<InsetNomencl const &>(*it).docbookGlossary(os);
155                         ++it;
156                 } else if (!it->producesOutput()) {
157                         // Ignore contents of insets that are not in output
158                         size_t const depth = it.depth();
159                         ++it;
160                         while (it.depth() > depth)
161                                 ++it;
162                 } else {
163                         ++it;
164                 }
165         }
166         os << "</glossary>\n";
167         return newlines;
168 }
169
170
171 namespace {
172 docstring nomenclWidest(Buffer const & buffer)
173 {
174         // nomenclWidest() determines and returns the widest used
175         // nomenclature symbol in the document
176
177         int w = 0;
178         docstring symb;
179         InsetNomencl const * nomencl = 0;
180         ParagraphList::const_iterator it = buffer.paragraphs().begin();
181         ParagraphList::const_iterator end = buffer.paragraphs().end();
182
183         for (; it != end; ++it) {
184                 if (it->insetList().empty())
185                         continue;
186                 InsetList::const_iterator iit = it->insetList().begin();
187                 InsetList::const_iterator eend = it->insetList().end();
188                 for (; iit != eend; ++iit) {
189                         Inset * inset = iit->inset;
190                         if (inset->lyxCode() != NOMENCL_CODE)
191                                 continue;
192                         nomencl = static_cast<InsetNomencl const *>(inset);
193                         docstring const symbol = nomencl->getParam("symbol");
194                         // we can only check for the number of characters, since it is
195                         // impossible to get the info that "iiiii" is smaller than "WW"
196                         // we therefore output w times "W" as string ("W" is always the
197                         // widest character)
198                         int const wx = symbol.size();
199                         if (wx > w)
200                                 w = wx;
201                 }
202         }
203         // return the widest symbol as w times a "W"
204         for (int n = 1; n <= w; ++n)
205                 symb = symb + "W";
206         return symb;
207 }
208 }
209
210
211 int InsetPrintNomencl::latex(odocstream & os, OutputParams const &) const
212 {
213         int lines = 0;
214         if (getParam("set_width") == "auto") {
215                 docstring widest = nomenclWidest(buffer());
216                 // set the label width via nomencl's command
217                 // \nomlabelwidth. This must be output before the command
218                 // \printnomenclature
219                 if (!widest.empty()) {
220                         // assure that the width is never below the
221                         // predefined value of 1 cm
222                         os << "\\settowidth{\\nomlabelwidth}{"
223                            << widest
224                            << "}\n";
225                         os << "\\ifthenelse{%\n";
226                         os << "\\lengthtest{\\nomlabelwidth < 1cm}}\n";
227                         os << " {\\setlength{\\nomlabelwidth}{1cm}}\n";
228                         os << " {}\n";
229                         lines += 5;
230                 }
231         }
232         // output the command \printnomenclature
233         os << getCommand();
234         return lines;
235 }
236
237
238 void InsetPrintNomencl::validate(LaTeXFeatures & features) const
239 {
240         features.require("nomencl");
241         // needed for InsetPrintNomencl::latex
242         features.require("ifthen");
243 }
244
245
246 InsetCode InsetPrintNomencl::lyxCode() const
247 {
248         return NOMENCL_PRINT_CODE;
249 }
250
251
252 } // namespace lyx