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/docstream.h"
30 #include "support/convert.h"
36 int InsetBibitem::key_counter = 0;
39 docstring const key_prefix = from_ascii("key-");
42 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
43 : InsetCommand(p, "bibitem")
45 if (getParam("key").empty())
46 setParam("key", key_prefix + convert<docstring>(++key_counter));
50 CommandInfo const * InsetBibitem::findInfo(std::string const & /* cmdName */)
52 static const char * const paramnames[] = {"label", "key", ""};
53 static const bool isoptional[] = {true, false};
54 static const CommandInfo info = {2, paramnames, isoptional};
59 Inset * InsetBibitem::clone() const
61 InsetBibitem * b = new InsetBibitem(params());
62 b->autolabel_ = autolabel_;
67 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
71 case LFUN_INSET_MODIFY: {
72 InsetCommandParams p(BIBITEM_CODE);
73 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
74 if (p.getCmdName().empty()) {
78 if (p["key"] != params()["key"])
79 cur.bv().buffer().changeRefsIfUnique(params()["key"],
85 InsetCommand::doDispatch(cur, cmd);
91 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
93 InsetCommand::read(buf, lex);
95 if (support::prefixIs(getParam("key"), key_prefix)) {
96 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
97 key_counter = std::max(key_counter, key);
102 docstring const InsetBibitem::getBibLabel() const
104 docstring const & label = getParam("label");
105 return label.empty() ? autolabel_ : label;
109 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
111 return getParam("key") + " [" + getBibLabel() + ']';
115 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
116 OutputParams const &) const
118 odocstringstream oss;
119 oss << '[' << getBibLabel() << "] ";
121 docstring const str = oss.str();
129 docstring const bibitemWidest(Buffer const & buffer)
133 InsetBibitem const * bitem = 0;
135 // FIXME: this font is used unitialized for now but should be set to
136 // a proportional font. Here is what Georg Baum has to say about it:
138 bibitemWidest() is supposed to find the bibitem with the widest label in the
139 output, because that is needed as an argument of the bibliography
140 environment to dtermine the correct indentation. To be 100% correct we
141 would need the metrics of the font that is used in the output, but usually
142 we don't have access to these.
143 In practice, any proportional font is probably good enough, since we don't
144 need to know the final with, we only need to know the which label is the
146 Unless there is an easy way to get the metrics of the output font I suggest
147 to use a hardcoded font like "Times" or so.
149 It is very important that the result of this function is the same both with
150 and without GUI. After thinking about this it is clear that no Font
151 metrics should be used here, since these come from the gui. If we can't
152 easily get the LaTeX font metrics we should make our own poor mans font
153 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
157 ParagraphList::const_iterator it = buffer.paragraphs().begin();
158 ParagraphList::const_iterator end = buffer.paragraphs().end();
160 for (; it != end; ++it) {
161 if (it->insetList().empty())
163 Inset * inset = it->insetList().begin()->inset;
164 if (inset->lyxCode() != BIBITEM_CODE)
167 bitem = static_cast<InsetBibitem const *>(inset);
168 docstring const label = bitem->getBibLabel();
170 // FIXME: we can't be sure using the following that the GUI
171 // version and the command-line version will give the same
174 //int const wx = use_gui?
175 // theFontMetrics(font).width(label): label.size();
177 // So for now we just use the label size in order to be sure
178 // that GUI and no-GUI gives the same bibitem (even if that is
179 // potentially the wrong one.
180 int const wx = label.size();
186 if (bitem && !bitem->getBibLabel().empty())
187 return bitem->getBibLabel();
189 return from_ascii("99");
193 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
194 BiblioInfo & keys, InsetIterator const & it) const
196 docstring const key = getParam("key");
197 BibTeXInfo keyvalmap;
198 keyvalmap[from_ascii("label")] = getParam("label");
199 DocIterator doc_it(it);
201 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
202 keyvalmap.isBibTeX = false;
203 keys[key] = keyvalmap;
207 /// Update the counters of this inset and of its contents
208 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
210 Counters & counters = buf.params().getTextClass().counters();
211 docstring const bibitem = from_ascii("bibitem");
212 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
213 counters.step(bibitem);
214 autolabel_ = counters.theCounter(bibitem);
216 autolabel_ = from_ascii("??");