#include "mathed/MathMacroTemplate.h"
#include "mathed/MathSupport.h"
+#include "graphics/GraphicsCache.h"
#include "graphics/PreviewLoader.h"
#include "frontends/alert.h"
/// A cache for the bibfiles (including bibfiles of loaded child
/// documents), needed for appropriate update of natbib labels.
- mutable support::FileNameList bibfiles_cache_;
+ mutable support::FileNamePairList bibfiles_cache_;
// FIXME The caching mechanism could be improved. At present, we have a
// cache for each Buffer, that caches all the bibliography info for that
ignore_parent(false), toc_backend(owner), macro_lock(false), timestamp_(0),
checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false),
- inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer), clone_list_(0),
- doing_export(false), parent_buffer(0),
+ inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer),
+ clone_list_(0), doing_export(false), parent_buffer(0),
word_count_(0), char_count_(0), blank_count_(0)
{
if (!cloned_buffer_) {
params().output_sync_macro.erase();
params().setLocalLayout(docstring(), false);
params().setLocalLayout(docstring(), true);
+ params().biblio_opts.erase();
+ params().biblatex_bibstyle.erase();
+ params().biblatex_citestyle.erase();
+ params().multibib.erase();
for (int i = 0; i < 4; ++i) {
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
runparams.use_babel = params().writeLaTeX(os, features,
d->filename.onlyPath());
+ // Biblatex bibliographies are loaded here
+ if (params().useBiblatex()) {
+ vector<docstring> const bibfiles =
+ prepareBibFilePaths(runparams, getBibfilesCache(), true);
+ for (docstring const & file: bibfiles)
+ os << "\\addbibresource{" << file << "}\n";
+ }
+
+ if (!runparams.dryrun && features.hasPolyglossiaExclusiveLanguages()
+ && !features.hasOnlyPolyglossiaLanguages()) {
+ docstring blangs;
+ docstring plangs;
+ vector<string> bll = features.getBabelExclusiveLanguages();
+ vector<string> pll = features.getPolyglossiaExclusiveLanguages();
+ if (!bll.empty()) {
+ docstring langs;
+ for (vector<string>::const_iterator it = bll.begin(); it != bll.end(); ++it) {
+ if (!langs.empty())
+ langs += ", ";
+ langs += _(*it);
+ }
+ blangs = bll.size() > 1 ?
+ support::bformat(_("The languages %1$s are only supported by Babel."), langs)
+ : support::bformat(_("The language %1$s is only supported by Babel."), langs);
+ }
+ if (!pll.empty()) {
+ docstring langs;
+ for (vector<string>::const_iterator it = pll.begin(); it != pll.end(); ++it) {
+ if (!langs.empty())
+ langs += ", ";
+ langs += _(*it);
+ }
+ plangs = pll.size() > 1 ?
+ support::bformat(_("The languages %1$s are only supported by Polyglossia."), langs)
+ : support::bformat(_("The language %1$s is only supported by Polyglossia."), langs);
+ if (!blangs.empty())
+ plangs += "\n";
+ }
+
+ frontend::Alert::warning(
+ _("Incompatible Languages!"),
+ support::bformat(
+ _("You cannot use the following languages "
+ "together in one LaTeX document because "
+ "they require conflicting language packages:\n"
+ "%1$s%2$s"),
+ plangs, blangs));
+ }
+
// Japanese might be required only in some children of a document,
// but once required, we must keep use_japanese true.
runparams.use_japanese |= features.isRequired("japanese");
if (! tclass.class_header().empty())
os << from_ascii(tclass.class_header());
else if (runparams.flavor == OutputParams::XML)
- os << "PUBLIC \"-//OASIS//DTD DocBook XML//EN\" "
+ os << "PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\" "
<< "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
else
os << " PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"";
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
if (it->lyxCode() == BIBTEX_CODE) {
InsetBibtex const & inset = static_cast<InsetBibtex const &>(*it);
- support::FileNameList const bibfiles = inset.getBibFiles();
+ support::FileNamePairList const bibfiles = inset.getBibFiles();
d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
bibfiles.begin(),
bibfiles.end());
Buffer const * const incbuf = inset.getChildBuffer();
if (!incbuf)
continue;
- support::FileNameList const & bibfiles =
+ support::FileNamePairList const & bibfiles =
incbuf->getBibfilesCache(UpdateChildOnly);
if (!bibfiles.empty()) {
d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
}
-support::FileNameList const & Buffer::getBibfilesCache(UpdateScope scope) const
+support::FileNamePairList const & Buffer::getBibfilesCache(UpdateScope scope) const
{
// FIXME This is probably unnecessary, given where we call this.
// If this is a child document, use the master's cache instead.
}
// compare the cached timestamps with the actual ones.
- FileNameList const & bibfiles_cache = getBibfilesCache();
- FileNameList::const_iterator ei = bibfiles_cache.begin();
- FileNameList::const_iterator en = bibfiles_cache.end();
+ FileNamePairList const & bibfiles_cache = getBibfilesCache();
+ FileNamePairList::const_iterator ei = bibfiles_cache.begin();
+ FileNamePairList::const_iterator en = bibfiles_cache.end();
for (; ei != en; ++ ei) {
- time_t lastw = ei->lastModified();
- time_t prevw = d->bibfile_status_[*ei];
+ FileName const fn = ei->second;
+ time_t lastw = fn.lastModified();
+ time_t prevw = d->bibfile_status_[fn];
if (lastw != prevw) {
d->bibinfo_cache_valid_ = false;
d->cite_labels_valid_ = false;
- d->bibfile_status_[*ei] = lastw;
+ d->bibfile_status_[fn] = lastw;
}
}
}
}
+string const Buffer::prepareFileNameForLaTeX(string const & name,
+ string const & ext, bool nice) const
+{
+ string const fname = makeAbsPath(name, filePath()).absFileName();
+ if (FileName::isAbsolute(name) || !FileName(fname + ext).isReadableFile())
+ return name;
+ if (!nice)
+ return fname;
+
+ // FIXME UNICODE
+ return to_utf8(makeRelPath(from_utf8(fname),
+ from_utf8(masterBuffer()->filePath())));
+}
+
+
+vector<docstring> const Buffer::prepareBibFilePaths(OutputParams const & runparams,
+ FileNamePairList const bibfilelist,
+ bool const add_extension) const
+{
+ // If we are processing the LaTeX file in a temp directory then
+ // copy the .bib databases to this temp directory, mangling their
+ // names in the process. Store this mangled name in the list of
+ // all databases.
+ // (We need to do all this because BibTeX *really*, *really*
+ // can't handle "files with spaces" and Windows users tend to
+ // use such filenames.)
+ // Otherwise, store the (maybe absolute) path to the original,
+ // unmangled database name.
+
+ vector<docstring> res;
+
+ // determine the export format
+ string const tex_format = flavor2format(runparams.flavor);
+
+ // check for spaces in paths
+ bool found_space = false;
+
+ FileNamePairList::const_iterator it = bibfilelist.begin();
+ FileNamePairList::const_iterator en = bibfilelist.end();
+ for (; it != en; ++it) {
+ string utf8input = to_utf8(it->first);
+ string database =
+ prepareFileNameForLaTeX(utf8input, ".bib", runparams.nice);
+ FileName const try_in_file =
+ makeAbsPath(database + ".bib", filePath());
+ bool const not_from_texmf = try_in_file.isReadableFile();
+
+ if (!runparams.inComment && !runparams.dryrun && !runparams.nice &&
+ not_from_texmf) {
+ // mangledFileName() needs the extension
+ DocFileName const in_file = DocFileName(try_in_file);
+ database = removeExtension(in_file.mangledFileName());
+ FileName const out_file = makeAbsPath(database + ".bib",
+ masterBuffer()->temppath());
+ bool const success = in_file.copyTo(out_file);
+ if (!success) {
+ LYXERR0("Failed to copy '" << in_file
+ << "' to '" << out_file << "'");
+ }
+ } else if (!runparams.inComment && runparams.nice && not_from_texmf) {
+ runparams.exportdata->addExternalFile(tex_format, try_in_file, database + ".bib");
+ if (!isValidLaTeXFileName(database)) {
+ frontend::Alert::warning(_("Invalid filename"),
+ _("The following filename will cause troubles "
+ "when running the exported file through LaTeX: ") +
+ from_utf8(database));
+ }
+ if (!isValidDVIFileName(database)) {
+ frontend::Alert::warning(_("Problematic filename for DVI"),
+ _("The following filename can cause troubles "
+ "when running the exported file through LaTeX "
+ "and opening the resulting DVI: ") +
+ from_utf8(database), true);
+ }
+ }
+
+ if (add_extension)
+ database += ".bib";
+
+ // FIXME UNICODE
+ docstring const path = from_utf8(latex_path(database));
+
+ if (contains(path, ' '))
+ found_space = true;
+
+ if (find(res.begin(), res.end(), path) == res.end())
+ res.push_back(path);
+ }
+
+ // Check if there are spaces in the path and warn BibTeX users, if so.
+ // (biber can cope with such paths)
+ if (!prefixIs(runparams.bibtex_command, "biber")) {
+ // Post this warning only once.
+ static bool warned_about_spaces = false;
+ if (!warned_about_spaces &&
+ runparams.nice && found_space) {
+ warned_about_spaces = true;
+ Alert::warning(_("Export Warning!"),
+ _("There are spaces in the paths to your BibTeX databases.\n"
+ "BibTeX will be unable to find them."));
+ }
+ }
+
+ return res;
+}
+
+
+
string Buffer::layoutPos() const
{
return d->layout_position;
MacroContext mc = MacroContext(this, it);
for (DocIterator::idx_type i = 0; i < n; ++i) {
MathData & data = minset->cell(i);
- data.updateMacros(0, mc, utype);
+ data.updateMacros(0, mc, utype, 0);
}
}
}
// in order to know if we should output polyglossia
// macros (instead of babel macros)
LaTeXFeatures features(*this, params(), runparams);
- params().validate(features);
+ validate(features);
runparams.use_polyglossia = features.usePolyglossia();
// latex or literate
otexstream ots(os);
ParIterator parit = cbuf.par_iterator_begin();
updateBuffer(parit, utype);
+ /// FIXME: Perf
+ /// Update the tocBackend for any buffer. The outliner uses the master's,
+ /// and the navigation menu uses the child's.
+ cbuf.tocBackend().update(true, utype);
+
if (master != this)
- // TocBackend update will be done later.
return;
d->bibinfo_cache_valid_ = true;
d->cite_labels_valid_ = true;
- /// FIXME: Perf
- cbuf.tocBackend().update(true, utype);
if (scope == UpdateMaster)
cbuf.structureChanged();
}