]> git.lyx.org Git - lyx.git/blob - src/insets/InsetIndex.cpp
Move isMultiCell() to Cursor, and use it.
[lyx.git] / src / insets / InsetIndex.cpp
1 /**
2  * \file InsetIndex.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  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include <config.h>
11
12 #include "InsetIndex.h"
13
14 #include "Buffer.h"
15 #include "DispatchResult.h"
16 #include "FuncRequest.h"
17 #include "FuncStatus.h"
18 #include "LaTeXFeatures.h"
19 #include "MetricsInfo.h"
20 #include "sgml.h"
21 #include "TocBackend.h"
22
23 #include "support/debug.h"
24 #include "support/docstream.h"
25 #include "support/gettext.h"
26 #include "support/lstrings.h"
27
28 #include <ostream>
29
30 using namespace std;
31 using namespace lyx::support;
32
33 namespace lyx {
34
35 /////////////////////////////////////////////////////////////////////
36 //
37 // InsetIndex
38 //
39 ///////////////////////////////////////////////////////////////////////
40
41
42 InsetIndex::InsetIndex(Buffer const & buf)
43         : InsetCollapsable(buf)
44 {}
45
46
47 int InsetIndex::latex(odocstream & os,
48                       OutputParams const & runparams) const
49 {
50         os << "\\index";
51         os << '{';
52         int i = 7;
53
54         // get contents of InsetText as LaTeX and plaintext
55         odocstringstream ourlatex;
56         InsetText::latex(ourlatex, runparams);
57         odocstringstream ourplain;
58         InsetText::plaintext(ourplain, runparams);
59         docstring latexstr = ourlatex.str();
60         docstring plainstr = ourplain.str();
61
62         // this will get what follows | if anything does
63         docstring cmd;
64
65         // check for the | separator
66         // FIXME This would go wrong on an escaped "|", but
67         // how far do we want to go here?
68         size_t pos = latexstr.find(from_ascii("|"));
69         if (pos != docstring::npos) {
70                 // put the bit after "|" into cmd...
71                 cmd = latexstr.substr(pos + 1);
72                 // ...and erase that stuff from latexstr
73                 latexstr = latexstr.erase(pos);
74                 // ...and similarly from plainstr
75                 size_t ppos = plainstr.find(from_ascii("|"));
76                 if (ppos < plainstr.size())
77                         plainstr.erase(ppos);
78                 else
79                         LYXERR0("The `|' separator was not found in the plaintext version!");
80         }
81
82         // Separate the entires and subentries, i.e., split on "!"
83         // FIXME This would do the wrong thing with escaped ! characters
84         std::vector<docstring> const levels =
85                 getVectorFromString(latexstr, from_ascii("!"), true);
86         std::vector<docstring> const levels_plain =
87                 getVectorFromString(plainstr, from_ascii("!"), true);
88
89         vector<docstring>::const_iterator it = levels.begin();
90         vector<docstring>::const_iterator end = levels.end();
91         vector<docstring>::const_iterator it2 = levels_plain.begin();
92         bool first = true;
93         for (; it != end; ++it) {
94                 // write the separator except the first time
95                 if (!first) {
96                         os << '!';
97                         i += 1;
98                 } else
99                         first = false;
100
101                 // correctly sort macros and formatted strings
102                 // if we do find a command, prepend a plain text
103                 // version of the content to get sorting right,
104                 // e.g. \index{LyX@\LyX}, \index{text@\textbf{text}}
105                 // Don't do that if the user entered '@' himself, though.
106                 if (contains(*it, '\\') && !contains(*it, '@')) {
107                         // Plaintext might return nothing (e.g. for ERTs)
108                         docstring const spart = 
109                                 (it2 < levels_plain.end() && !(*it2).empty()) ? *it2 : *it;
110                         // remove remaining \'s for the sorting part
111                         docstring const ppart =
112                                 subst(spart, from_ascii("\\"), docstring());
113                         os << ppart;
114                         os << '@';
115                         i += ppart.size() + 1;
116                 }
117                 docstring const tpart = *it;
118                 os << tpart;
119                 i += tpart.size();
120                 if (it2 < levels_plain.end())
121                         ++it2;
122         }
123         // write the bit that followed "|"
124         if (!cmd.empty()) {
125                 os << "|" << cmd;
126                 i += cmd.size() + 1;
127         }
128         os << '}';
129         i += 1;
130         return i;
131 }
132
133
134 int InsetIndex::docbook(odocstream & os, OutputParams const & runparams) const
135 {
136         os << "<indexterm><primary>";
137         int const i = InsetText::docbook(os, runparams);
138         os << "</primary></indexterm>";
139         return i;
140 }
141
142
143 void InsetIndex::write(ostream & os) const
144 {
145         os << to_utf8(name()) << "\n";
146         InsetCollapsable::write(os);
147 }
148
149
150 void InsetIndex::addToToc(DocIterator const & cpit)
151 {
152         DocIterator pit = cpit;
153         pit.push_back(CursorSlice(*this));
154
155         Toc & toc = buffer().tocBackend().toc("index");
156         docstring str;
157         str = getNewLabel(str);
158         toc.push_back(TocItem(pit, 0, str));
159         // Proceed with the rest of the inset.
160         InsetCollapsable::addToToc(cpit);
161 }
162
163
164 /////////////////////////////////////////////////////////////////////
165 //
166 // InsetPrintIndex
167 //
168 ///////////////////////////////////////////////////////////////////////
169
170 InsetPrintIndex::InsetPrintIndex(InsetCommandParams const & p)
171         : InsetCommand(p, string())
172 {}
173
174
175 ParamInfo const & InsetPrintIndex::findInfo(string const & /* cmdName */)
176 {
177         static ParamInfo param_info_;
178         if (param_info_.empty())
179                 param_info_.add("name", ParamInfo::LATEX_REQUIRED);
180         return param_info_;
181 }
182
183
184 docstring InsetPrintIndex::screenLabel() const
185 {
186         return _("Index");
187 }
188
189
190 void InsetPrintIndex::validate(LaTeXFeatures & features) const
191 {
192         features.require("makeidx");
193 }
194
195
196 InsetCode InsetPrintIndex::lyxCode() const
197 {
198         return INDEX_PRINT_CODE;
199 }
200
201 } // namespace lyx