]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetBibitem.cpp
Whitespace.
[lyx.git] / src / insets / InsetBibitem.cpp
index fc158a02334c3ef7c14263e24cc1aa1fa380becf..a05b21d28b00deb14564f7e11247a629fd7abceb 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "BiblioInfo.h"
 #include "Buffer.h"
+#include "Cursor.h"
 #include "buffer_funcs.h"
 #include "BufferParams.h"
 #include "BufferView.h"
@@ -24,7 +25,7 @@
 #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"
@@ -52,9 +53,9 @@ 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));
 }
@@ -62,8 +63,8 @@ InsetBibitem::InsetBibitem(Buffer * buf, InsetCommandParams const & p)
 
 InsetBibitem::~InsetBibitem()
 {
-       if (isBufferValid())
-               buffer_->invalidateBibinfoCache();
+       if (isBufferLoaded())
+               buffer().invalidateBibinfoCache();
 }
 
 
@@ -75,7 +76,6 @@ void InsetBibitem::initView()
 
 void InsetBibitem::updateCommand(docstring const & new_key, bool)
 {
-       docstring const old_key = getParam("key");
        docstring key = new_key;
 
        vector<docstring> bibkeys = buffer().masterBibInfo().getKeys();
@@ -94,8 +94,7 @@ void InsetBibitem::updateCommand(docstring const & new_key, bool)
                        "it will be changed to %2$s."), new_key, key));
        }
        setParam("key", key);
-
-       buffer().updateLabels();
+       buffer().invalidateBibinfoCache();
 }
 
 
@@ -103,8 +102,10 @@ ParamInfo const & InsetBibitem::findInfo(string const & /* cmdName */)
 {
        static ParamInfo param_info_;
        if (param_info_.empty()) {
-               param_info_.add("label", ParamInfo::LATEX_OPTIONAL);
-               param_info_.add("key", ParamInfo::LATEX_REQUIRED);
+               param_info_.add("label", ParamInfo::LATEX_OPTIONAL,
+                               ParamInfo::HANDLING_LATEXIFY);
+               param_info_.add("key", ParamInfo::LATEX_REQUIRED,
+                               ParamInfo::HANDLING_ESCAPE);
        }
        return param_info_;
 }
@@ -112,23 +113,75 @@ ParamInfo const & InsetBibitem::findInfo(string const & /* cmdName */)
 
 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
+               int previous;
+               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()) {
+                       // 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.forceBufferUpdate();
+                       buffer().invalidateBibinfoCache();
                }
-               buffer_->invalidateBibinfoCache();
                break;
        }
 
@@ -175,46 +228,6 @@ int InsetBibitem::plaintext(odocstream & os, OutputParams const &) const
 }
 
 
-int InsetBibitem::latex(odocstream & os, OutputParams const & runparams) const
-{
-       docstring cmd = '\\' + from_ascii(defaultCommand());
-       docstring uncodable;
-       if (!getParam("label").empty()) {
-               cmd += '[';
-               docstring orig = getParam("label");
-               for (size_t n = 0; n < orig.size(); ++n) {
-                       try {
-                               cmd += runparams.encoding->latexChar(orig[n]);
-                       } catch (EncodingException & /* e */) {
-                               LYXERR0("Uncodable character in bibitem!");
-                               if (runparams.dryrun) {
-                                       cmd += "<" + _("LyX Warning: ")
-                                           + _("uncodable character") + " '";
-                                       cmd += docstring(1, orig[n]);
-                                       cmd += "'>";
-                               } else
-                                       uncodable += orig[n];
-                       }
-               }
-               cmd += ']';
-       }
-       cmd += '{' + escape(getParam("key")) + '}';
-
-       os << cmd;
-
-       if (!uncodable.empty()) {
-               // issue a warning about omitted characters
-               // FIXME: should be passed to the error dialog
-               frontend::Alert::warning(_("Uncodable characters in bibliography item"),
-                       bformat(_("The following characters in one of the bibliography items are\n"
-                                 "not representable in the current encoding and have been omitted:\n%1$s."),
-                       uncodable));
-       }
-       
-       return 0;
-}
-
-
 // ale070405
 docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
 {
@@ -278,46 +291,39 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
        }
 
        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);
+       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);
 }
 
 
 // Update the counters of this inset and of its contents
-void InsetBibitem::updateLabels(ParIterator const & it, UpdateType utype)
+void InsetBibitem::updateBuffer(ParIterator const & it, UpdateType utype)
 {
        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 (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 {
@@ -334,7 +340,8 @@ docstring InsetBibitem::xhtml(XHTMLStream & xs, OutputParams const &) const
        // 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();