#include "BiblioInfo.h"
#include "Buffer.h"
+#include "Cursor.h"
#include "buffer_funcs.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "FuncRequest.h"
#include "InsetIterator.h"
#include "InsetList.h"
-#include "Language.h"
+#include "Language.h"
#include "Lexer.h"
#include "output_xhtml.h"
#include "OutputParams.h"
namespace lyx {
+// FIXME THREAD
int InsetBibitem::key_counter = 0;
docstring const key_prefix = from_ascii("key-");
InsetBibitem::InsetBibitem(Buffer * buf, InsetCommandParams const & p)
- : InsetCommand(buf, p, "bibitem")
+ : InsetCommand(buf, p)
{
- buffer_->invalidateBibinfoCache();
+ buffer().invalidateBibinfoCache();
if (getParam("key").empty())
setParam("key", key_prefix + convert<docstring>(++key_counter));
}
InsetBibitem::~InsetBibitem()
{
if (isBufferLoaded())
- buffer_->invalidateBibinfoCache();
+ buffer().invalidateBibinfoCache();
}
void InsetBibitem::updateCommand(docstring const & new_key, bool)
{
docstring key = new_key;
-
vector<docstring> bibkeys = buffer().masterBibInfo().getKeys();
- int i = 1;
-
if (find(bibkeys.begin(), bibkeys.end(), key) != bibkeys.end()) {
+ int i = 1;
// generate unique label
key = new_key + '-' + convert<docstring>(i);
while (find(bibkeys.begin(), bibkeys.end(), key) != bibkeys.end()) {
"it will be changed to %2$s."), new_key, key));
}
setParam("key", key);
-
- buffer().updateBuffer();
+ buffer().invalidateBibinfoCache();
}
void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
{
- switch (cmd.action) {
+ switch (cmd.action()) {
case LFUN_INSET_MODIFY: {
InsetCommandParams p(BIBITEM_CODE);
- InsetCommand::string2params("bibitem", to_utf8(cmd.argument()), p);
+ InsetCommand::string2params(to_utf8(cmd.argument()), p);
if (p.getCmdName().empty()) {
- cur.noUpdate();
+ cur.noScreenUpdate();
break;
}
+
+ cur.recordUndo();
+
docstring const & old_key = params()["key"];
+ docstring const & old_label = params()["label"];
+ docstring label = p["label"];
+
+ // definitions for escaping
+ static docstring const backslash = from_ascii("\\");
+ static docstring const lbrace = from_ascii("{");
+ static docstring const rbrace = from_ascii("}");
+ static char_type const chars_escape[6] = {
+ '&', '_', '$', '%', '#', '^'};
+ static char_type const brackets_escape[2] = {'[', ']'};
+
+ if (!label.empty()) {
+ int previous;
+ // The characters in chars_name[] need to be changed to a command when
+ // they are in the name field.
+ for (int k = 0; k < 6; k++)
+ for (size_t i = 0, pos;
+ (pos = label.find(chars_escape[k], i)) != string::npos;
+ i = pos + 2) {
+ if (pos == 0)
+ previous = 0;
+ else
+ previous = pos - 1;
+ // only if not already escaped
+ if (label[previous] != '\\')
+ label.replace(pos, 1, backslash + chars_escape[k] + lbrace + rbrace);
+ }
+ // The characters '[' and ']' need to be put into braces
+ for (int k = 0; k < 2; k++)
+ for (size_t i = 0, pos;
+ (pos = label.find(brackets_escape[k], i)) != string::npos;
+ i = pos + 2) {
+ if (pos == 0)
+ previous = 0;
+ else
+ previous = pos - 1;
+ // only if not already escaped
+ if (label[previous] != '{')
+ label.replace(pos, 1, lbrace + brackets_escape[k] + rbrace);
+ }
+ }
+
+ if (old_label != label) {
+ p["label"] = label;
+ cur.forceBufferUpdate();
+ buffer().invalidateBibinfoCache();
+ }
+
setParam("label", p["label"]);
if (p["key"] != old_key) {
updateCommand(p["key"]);
- cur.bv().buffer().changeRefsIfUnique(old_key,
- params()["key"], CITE_CODE);
+ cur.bv().buffer().changeRefsIfUnique(old_key, params()["key"]);
+ cur.forceBufferUpdate();
+ buffer().invalidateBibinfoCache();
}
- buffer_->invalidateBibinfoCache();
break;
}
docstring InsetBibitem::bibLabel() const
{
+ BufferParams const & bp = buffer().masterBuffer()->params();
+ if (bp.citeEngineType() == ENGINE_TYPE_NUMERICAL)
+ return autolabel_;
docstring const & label = getParam("label");
return label.empty() ? autolabel_ : label;
}
}
-int InsetBibitem::plaintext(odocstream & os, OutputParams const &) const
+int InsetBibitem::plaintext(odocstringstream & os,
+ OutputParams const &, size_t) const
{
odocstringstream oss;
oss << '[' << bibLabel() << "] ";
// ale070405
docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
{
+ BufferParams const & bp = buffer.masterBuffer()->params();
+ if (bp.citeEngineType() == ENGINE_TYPE_NUMERICAL)
+ return from_ascii("99");
+
int w = 0;
InsetBibitem const * bitem = 0;
}
if (!lbl.empty()) {
- docstring latex_lbl;
- for (size_t n = 0; n < lbl.size(); ++n) {
- try {
- latex_lbl += runparams.encoding->latexChar(lbl[n]);
- } catch (EncodingException & /* e */) {
- if (runparams.dryrun) {
- latex_lbl += "<" + _("LyX Warning: ")
- + _("uncodable character") + " '";
- latex_lbl += docstring(1, lbl[n]);
- latex_lbl += "'>";
- }
- }
- }
- return latex_lbl;
+ pair<docstring, docstring> latex_lbl =
+ runparams.encoding->latexString(lbl, runparams.dryrun);
+ return latex_lbl.first;
}
return from_ascii("99");
}
-void InsetBibitem::fillWithBibKeys(BiblioInfo & keys, InsetIterator const & it) const
+void InsetBibitem::collectBibKeys(InsetIterator const & it) const
{
docstring const key = getParam("key");
+ docstring const label = getParam("label");
BibTeXInfo keyvalmap(false);
- keyvalmap.label(bibLabel());
- DocIterator doc_it(it);
+ keyvalmap.key(key);
+ keyvalmap.label(label);
+
+ BufferParams const & bp = buffer().masterBuffer()->params();
+ Counters & counters = bp.documentClass().counters();
+ docstring const bibitem = from_ascii("bibitem");
+ if (bp.citeEngineType() == ENGINE_TYPE_NUMERICAL || getParam("label").empty()) {
+ if (counters.hasCounter(bibitem))
+ counters.step(bibitem, InternalUpdate);
+ string const & lang = it.paragraph().getParLanguage(bp)->code();
+ keyvalmap.setCiteNumber(counters.theCounter(bibitem, lang));
+ }
+
+ DocIterator doc_it(it);
doc_it.forwardPos();
- keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString();
- keys[key] = keyvalmap;
+ keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(
+ AS_STR_INSETS | AS_STR_SKIPDELETE);
+ buffer().addBibTeXInfo(key, keyvalmap);
}
BufferParams const & bp = buffer().masterBuffer()->params();
Counters & counters = bp.documentClass().counters();
docstring const bibitem = from_ascii("bibitem");
- if (counters.hasCounter(bibitem) && getParam("label").empty()) {
- counters.step(bibitem, utype);
+ if (bp.citeEngineType() == ENGINE_TYPE_NUMERICAL || getParam("label").empty()) {
+ if (counters.hasCounter(bibitem))
+ counters.step(bibitem, utype);
string const & lang = it.paragraph().getParLanguage(bp)->code();
autolabel_ = counters.theCounter(bibitem, lang);
} else {
// need to use "name" anyway, eventually, because some browsers do not
// handle jumping to ids. If we don't do that, though, we can just put the
// id into the span tag.
- string const attrs = "id='" + to_utf8(getParam("key")) + "'";
+ string const attrs =
+ "id='LyXCite-" + to_utf8(html::cleanAttr(getParam("key"))) + "'";
xs << html::CompTag("a", attrs);
xs << html::StartTag("span", "class='bibitemlabel'");
xs << bibLabel();