10 #include "frontends/Dialogs.h"
14 #include "BufferView.h"
17 #include "support/filetools.h"
18 #include "support/path.h"
19 #include "support/os.h"
20 #include "support/lstrings.h"
33 int InsetBibKey::key_counter = 0;
34 const string key_prefix = "key-";
36 InsetBibKey::InsetBibKey(InsetCommandParams const & p)
37 : InsetCommand(p), counter(1)
39 if (getContents().empty())
40 setContents(key_prefix + tostr(++key_counter));
44 InsetBibKey::~InsetBibKey()
49 Inset * InsetBibKey::clone(Buffer const &, bool) const
51 InsetBibKey * b = new InsetBibKey(params());
52 b->setCounter(counter);
57 void InsetBibKey::setCounter(int c)
63 // I'm sorry but this is still necessary because \bibitem is used also
64 // as a LyX 2.x command, and lyxlex is not enough smart to understand
65 // real LaTeX commands. Yes, that could be fixed, but would be a waste
66 // of time cause LyX3 won't use lyxlex anyway. (ale)
67 void InsetBibKey::write(Buffer const *, ostream & os) const
70 if (! getOptions().empty()) {
72 << getOptions() << ']';
75 << getContents() << "}\n";
79 // This is necessary here because this is written without begin_inset
80 // This should be changed!!! (Jug)
81 void InsetBibKey::read(Buffer const *, LyXLex & lex)
86 token = lex.GetString();
89 lex.printError("InsetCommand: Parse error: `$$Token'");
91 if (prefixIs(getContents(), key_prefix)) {
92 int key = strToInt(getContents().substr(key_prefix.length()));
93 key_counter = max(key_counter, key);
97 string const InsetBibKey::getBibLabel() const
99 if (! getOptions().empty())
101 return tostr(counter);
104 string const InsetBibKey::getScreenLabel(Buffer const *) const
106 return getContents() + " [" + getBibLabel() + "]";
110 void InsetBibKey::edit(BufferView * bv, int, int, unsigned int)
112 bv->owner()->getDialogs()->showBibitem(this);
116 void InsetBibKey::edit(BufferView * bv, bool)
122 InsetBibtex::InsetBibtex(InsetCommandParams const & p, bool)
127 InsetBibtex::~InsetBibtex()
132 string const InsetBibtex::getScreenLabel(Buffer const *) const
134 return _("BibTeX Generated References");
138 int InsetBibtex::latex(Buffer const * buffer, ostream & os,
139 bool /*fragile*/, bool/*fs*/) const
141 // If we generate in a temp dir, we might need to give an
142 // absolute path there. This is a bit complicated since we can
143 // have a comma-separated list of bibliographies
145 string db_in = getContents();
146 db_in = split(db_in, adb, ',');
147 while(!adb.empty()) {
148 if (!buffer->niceFile &&
149 IsFileReadable(MakeAbsPath(adb, buffer->filepath)+".bib"))
150 adb = os::external_path(MakeAbsPath(adb, buffer->filepath));
154 db_in= split(db_in, adb,',');
156 db_out = strip(db_out, ',');
159 if (!buffer->niceFile
160 && IsFileReadable(MakeAbsPath(getOptions(), buffer->filepath)
162 style = MakeAbsPath(getOptions(), buffer->filepath);
164 style = getOptions();
166 os << "\\bibliographystyle{" << style << "}\n"
167 << "\\bibliography{" << db_out << "}\n";
172 // This method returns a comma separated list of Bibtex entries
173 vector<pair<string, string> > const InsetBibtex::getKeys(Buffer const * buffer) const
175 Path p(buffer->filepath);
177 vector<pair<string,string> > keys;
179 string bibfiles = getContents();
180 bibfiles = split(bibfiles, tmp, ',');
181 while(!tmp.empty()) {
182 string fil = findtexfile(ChangeExtension(tmp, "bib"),
184 lyxerr[Debug::LATEX] << "Bibfile: " << fil << endl;
185 // If we didn't find a matching file name just fail silently
187 // This is a _very_ simple parser for Bibtex database
188 // files. All it does is to look for lines starting
189 // in @ and not being @preamble and @string entries.
190 // It does NOT do any syntax checking!
191 ifstream ifs(fil.c_str());
193 while (getline(ifs, linebuf0)) {
194 string linebuf = frontStrip(strip(linebuf0));
195 if (linebuf.empty() ) continue;
196 if (prefixIs(linebuf, "@")) {
197 linebuf = subst(linebuf, '{', '(');
198 linebuf = split(linebuf, tmp, '(');
199 tmp = lowercase(tmp);
200 if (!prefixIs(tmp, "@string")
201 && !prefixIs(tmp, "@preamble")) {
202 linebuf = split(linebuf, tmp, ',');
203 tmp = frontStrip(tmp);
205 keys.push_back(pair<string,string>(tmp,string()));
208 } else if (!keys.empty()) {
209 keys.back().second += linebuf + "\n";
213 // Get next file name
214 bibfiles = split(bibfiles, tmp, ',');
220 void InsetBibtex::edit(BufferView * bv, int, int, unsigned int)
222 bv->owner()->getDialogs()->showBibtex(this);
226 void InsetBibtex::edit(BufferView * bv, bool)
232 bool InsetBibtex::addDatabase(string const & db)
234 string contents(getContents());
235 if (!contains(contents, db)) {
236 if (!contents.empty())
238 setContents(contents + db);
245 bool InsetBibtex::delDatabase(string const & db)
247 if (contains(getContents(), db)) {
249 int const n = tokenPos(getContents(), ',', bd);
251 // Weird code, would someone care to explain this?(Lgb)
254 setContents(subst(getContents(), tmp, ", "));
256 setContents(split(getContents(), bd, ','));
264 // ale070405 This function maybe shouldn't be here. We'll fix this at 0.13.
265 int bibitemMaxWidth(BufferView * bv, LyXFont const & font)
268 #warning Ha, now we are mainly at 1.2.0 and it is still here (Jug)
269 // Does look like a hack? It is! (but will change at 0.13)
270 Paragraph * par = bv->buffer()->paragraph;
274 int const wx = par->bibkey->width(bv, font);
284 string const bibitemWidest(Buffer const * buffer)
287 // Does look like a hack? It is! (but will change at 0.13)
288 Paragraph * par = buffer->paragraph;
289 InsetBibKey * bkey = 0;
295 lyxfont::width(par->bibkey->getBibLabel(),
305 if (bkey && !bkey->getBibLabel().empty())
306 return bkey->getBibLabel();