]> git.lyx.org Git - lyx.git/blob - src/insets/InsetRef.cpp
82821a61b1ee4ec827b0b721b4a6be3db03d88b8
[lyx.git] / src / insets / InsetRef.cpp
1 /**
2  * \file InsetRef.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author José Matos
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include <config.h>
11
12 #include "InsetRef.h"
13
14 #include "Buffer.h"
15 #include "buffer_funcs.h"
16 #include "Cursor.h"
17 #include "DispatchResult.h"
18 #include "FuncRequest.h"
19 #include "LaTeXFeatures.h"
20 #include "LyXFunc.h"
21 #include "OutputParams.h"
22 #include "ParIterator.h"
23 #include "sgml.h"
24 #include "TocBackend.h"
25
26 #include "support/docstream.h"
27 #include "support/gettext.h"
28 #include "support/lstrings.h"
29
30 using namespace lyx::support;
31 using namespace std;
32
33 namespace lyx {
34
35
36 InsetRef::InsetRef(Buffer const & buf, InsetCommandParams const & p)
37         : InsetCommand(p, "ref"), isLatex(buf.isLatex())
38 {}
39
40
41 InsetRef::InsetRef(InsetRef const & ir)
42         : InsetCommand(ir), isLatex(ir.isLatex)
43 {}
44
45
46 void InsetRef::initView()
47 {
48         // We need an update of the Buffer reference cache. This is achieved by
49         // updateLabel().
50         lyx::updateLabels(buffer());
51 }
52
53
54 bool InsetRef::isCompatibleCommand(string const & s) {
55         //FIXME This is likely not the best way to handle this.
56         //But this stuff is hardcoded elsewhere already.
57         return s == "ref" 
58                 || s == "pageref"
59                 || s == "vref" 
60                 || s == "vpageref"
61                 || s == "prettyref"
62                 || s == "eqref";
63 }
64
65
66 ParamInfo const & InsetRef::findInfo(string const & /* cmdName */)
67 {
68         static ParamInfo param_info_;
69         if (param_info_.empty()) {
70                 param_info_.add("name", ParamInfo::LATEX_OPTIONAL);
71                 param_info_.add("reference", ParamInfo::LATEX_REQUIRED);
72         }
73         return param_info_;
74 }
75
76
77 docstring InsetRef::screenLabel() const
78 {
79         return screen_label_;
80 }
81
82
83 int InsetRef::latex(odocstream & os, OutputParams const &) const
84 {
85         // We don't want to output p_["name"], since that is only used 
86         // in docbook. So we construct new params, without it, and use that.
87         InsetCommandParams p(REF_CODE, getCmdName());
88         p["reference"] = getParam("reference");
89         os << escape(p.getCommand());
90         return 0;
91 }
92
93
94 int InsetRef::plaintext(odocstream & os, OutputParams const &) const
95 {
96         docstring const str = getParam("reference");
97         os << '[' << str << ']';
98         return 2 + str.size();
99 }
100
101
102 int InsetRef::docbook(odocstream & os, OutputParams const & runparams) const
103 {
104         docstring const & name = getParam("name");
105         if (name.empty()) {
106                 if (runparams.flavor == OutputParams::XML) {
107                         os << "<xref linkend=\""
108                            << sgml::cleanID(buffer(), runparams, getParam("reference"))
109                            << "\" />";
110                 } else {
111                         os << "<xref linkend=\""
112                            << sgml::cleanID(buffer(), runparams, getParam("reference"))
113                            << "\">";
114                 }
115         } else {
116                 os << "<link linkend=\""
117                    << sgml::cleanID(buffer(), runparams, getParam("reference"))
118                    << "\">"
119                    << getParam("name")
120                    << "</link>";
121         }
122
123         return 0;
124 }
125
126
127 void InsetRef::textString(odocstream & os) const
128 {
129         plaintext(os, OutputParams(0));
130 }
131
132
133 void InsetRef::updateLabels(ParIterator const & it)
134 {
135         docstring const & label = getParam("reference");
136         // register this inset into the buffer reference cache.
137         buffer().references(label).push_back(make_pair(this, it));
138
139         for (int i = 0; !types[i].latex_name.empty(); ++i) {
140                 if (getCmdName() == types[i].latex_name) {
141                         screen_label_ = _(types[i].short_gui_name);
142                         break;
143                 }
144         }
145         screen_label_ += getParam("reference");
146
147         if (!isLatex && !getParam("name").empty()) {
148                 screen_label_ += "||";
149                 screen_label_ += getParam("name");
150         }
151 }
152
153
154 void InsetRef::addToToc(ParConstIterator const & cpit) const
155 {
156         docstring const & label = getParam("reference");
157         if (buffer().insetLabel(label))
158                 // This InsetRef has already been taken care of in InsetLabel::addToToc().
159                 return;
160
161         // It seems that this reference does not point to any valid label.
162         screen_label_ = _("BROKEN: ") + screen_label_;
163         Toc & toc = buffer().tocBackend().toc("label");
164         toc.push_back(TocItem(cpit, 0, screen_label_));
165 }
166
167
168 void InsetRef::validate(LaTeXFeatures & features) const
169 {
170         if (getCmdName() == "vref" || getCmdName() == "vpageref")
171                 features.require("varioref");
172         else if (getCmdName() == "prettyref")
173                 features.require("prettyref");
174         else if (getCmdName() == "eqref")
175                 features.require("amsmath");
176 }
177
178
179 InsetRef::type_info InsetRef::types[] = {
180         { "ref",       N_("Standard"),              N_("Ref: ")},
181         { "eqref",     N_("Equation"),              N_("EqRef: ")},
182         { "pageref",   N_("Page Number"),           N_("Page: ")},
183         { "vpageref",  N_("Textual Page Number"),   N_("TextPage: ")},
184         { "vref",      N_("Standard+Textual Page"), N_("Ref+Text: ")},
185         { "prettyref", N_("PrettyRef"),             N_("FormatRef: ")},
186         { "", "", "" }
187 };
188
189
190 int InsetRef::getType(string const & name)
191 {
192         for (int i = 0; !types[i].latex_name.empty(); ++i)
193                 if (name == types[i].latex_name)
194                         return i;
195         return 0;
196 }
197
198
199 string const & InsetRef::getName(int type)
200 {
201         return types[type].latex_name;
202 }
203
204
205 } // namespace lyx