2 * \file InsetBibitem.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
8 * Full author contact details are available in file CREDITS.
13 #include "InsetBibitem.h"
16 #include "BufferParams.h"
17 #include "BufferView.h"
19 #include "DispatchResult.h"
20 #include "FuncRequest.h"
21 #include "InsetIterator.h"
22 #include "InsetList.h"
24 #include "Paragraph.h"
25 #include "ParagraphList.h"
27 #include "support/lstrings.h"
28 #include "support/std_ostream.h"
29 #include "support/convert.h"
35 int InsetBibitem::key_counter = 0;
38 docstring const key_prefix = from_ascii("key-");
41 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
42 : InsetCommand(p, "bibitem")
44 if (getParam("key").empty())
45 setParam("key", key_prefix + convert<docstring>(++key_counter));
49 CommandInfo const * InsetBibitem::findInfo(std::string const & /* cmdName */)
51 static const char * const paramnames[] = {"label", "key", ""};
52 static const bool isoptional[] = {true, false};
53 static const CommandInfo info = {2, paramnames, isoptional};
58 Inset * InsetBibitem::clone() const
60 InsetBibitem * b = new InsetBibitem(params());
61 b->autolabel_ = autolabel_;
66 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
70 case LFUN_INSET_MODIFY: {
71 InsetCommandParams p(BIBITEM_CODE);
72 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
73 if (p.getCmdName().empty()) {
77 if (p["key"] != params()["key"])
78 cur.bv().buffer().changeRefsIfUnique(params()["key"],
84 InsetCommand::doDispatch(cur, cmd);
90 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
92 InsetCommand::read(buf, lex);
94 if (support::prefixIs(getParam("key"), key_prefix)) {
95 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
96 key_counter = std::max(key_counter, key);
101 docstring const InsetBibitem::getBibLabel() const
103 docstring const & label = getParam("label");
104 return label.empty() ? autolabel_ : label;
108 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
110 return getParam("key") + " [" + getBibLabel() + ']';
114 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
115 OutputParams const &) const
117 odocstringstream oss;
118 oss << '[' << getBibLabel() << "] ";
120 docstring const str = oss.str();
128 docstring const bibitemWidest(Buffer const & buffer)
132 InsetBibitem const * bitem = 0;
134 // FIXME: this font is used unitialized for now but should be set to
135 // a proportional font. Here is what Georg Baum has to say about it:
137 bibitemWidest() is supposed to find the bibitem with the widest label in the
138 output, because that is needed as an argument of the bibliography
139 environment to dtermine the correct indentation. To be 100% correct we
140 would need the metrics of the font that is used in the output, but usually
141 we don't have access to these.
142 In practice, any proportional font is probably good enough, since we don't
143 need to know the final with, we only need to know the which label is the
145 Unless there is an easy way to get the metrics of the output font I suggest
146 to use a hardcoded font like "Times" or so.
148 It is very important that the result of this function is the same both with
149 and without GUI. After thinking about this it is clear that no Font
150 metrics should be used here, since these come from the gui. If we can't
151 easily get the LaTeX font metrics we should make our own poor mans font
152 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
156 ParagraphList::const_iterator it = buffer.paragraphs().begin();
157 ParagraphList::const_iterator end = buffer.paragraphs().end();
159 for (; it != end; ++it) {
160 if (it->insetList().empty())
162 Inset * inset = it->insetList().begin()->inset;
163 if (inset->lyxCode() != BIBITEM_CODE)
166 bitem = static_cast<InsetBibitem const *>(inset);
167 docstring const label = bitem->getBibLabel();
169 // FIXME: we can't be sure using the following that the GUI
170 // version and the command-line version will give the same
173 //int const wx = use_gui?
174 // theFontMetrics(font).width(label): label.size();
176 // So for now we just use the label size in order to be sure
177 // that GUI and no-GUI gives the same bibitem (even if that is
178 // potentially the wrong one.
179 int const wx = label.size();
185 if (bitem && !bitem->getBibLabel().empty())
186 return bitem->getBibLabel();
188 return from_ascii("99");
192 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
193 BiblioInfo & keys, InsetIterator const & it) const
195 docstring const key = getParam("key");
196 BibTeXInfo keyvalmap;
197 keyvalmap[from_ascii("label")] = getParam("label");
198 DocIterator doc_it(it);
200 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
201 keyvalmap.isBibTeX = false;
202 keys[key] = keyvalmap;
206 /// Update the counters of this inset and of its contents
207 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
209 Counters & counters = buf.params().getTextClass().counters();
210 docstring const bibitem = from_ascii("bibitem");
211 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
212 counters.step(bibitem);
213 autolabel_ = counters.theCounter(bibitem);
215 autolabel_ = from_ascii("??");