#include "Author.h"
#include "LayoutFile.h"
#include "BranchList.h"
+#include "Buffer.h"
#include "buffer_funcs.h"
#include "Bullet.h"
#include "Color.h"
#include "support/gettext.h"
#include "support/Messages.h"
#include "support/mutex.h"
+#include "support/Package.h"
#include "support/Translator.h"
#include "support/lstrings.h"
string BufferParams::readToken(Lexer & lex, string const & token,
FileName const & filepath)
{
+ string result;
+
if (token == "\\textclass") {
lex.next();
string const classname = lex.getString();
// be available.
string tcp;
LayoutFileList & bcl = LayoutFileList::get();
- if (!filepath.empty())
- tcp = bcl.addLocalLayout(classname, filepath.absFileName());
+ if (!filepath.empty()) {
+ // If classname is an absolute path, the document is
+ // using a local layout file which could not be accessed
+ // by a relative path. In this case the path is correct
+ // even if the document was moved to a different
+ // location. However, we will have a problem if the
+ // document was generated on a different platform.
+ bool isabsolute = FileName::isAbsolute(classname);
+ string const classpath = onlyPath(classname);
+ string const path = isabsolute ? classpath
+ : FileName(addPath(filepath.absFileName(),
+ classpath)).realPath();
+ string const oldpath = isabsolute ? string()
+ : FileName(addPath(origin, classpath)).realPath();
+ tcp = bcl.addLocalLayout(onlyFileName(classname), path, oldpath);
+ }
// that returns non-empty if a "local" layout file is found.
- if (!tcp.empty())
- setBaseClass(tcp);
- else
- setBaseClass(classname);
+ if (!tcp.empty()) {
+ result = to_utf8(makeRelPath(from_utf8(onlyPath(tcp)),
+ from_utf8(filepath.absFileName())));
+ if (result.empty())
+ result = ".";
+ setBaseClass(onlyFileName(tcp));
+ } else
+ setBaseClass(onlyFileName(classname));
// We assume that a tex class exists for local or unknown
// layouts so this warning, will only be given for system layouts.
if (!baseClass()->isTeXClassAvailable()) {
frontend::Alert::warning(_("Document class not available"),
msg, true);
}
+ } else if (token == "\\origin") {
+ lex.eatLine();
+ origin = lex.getString();
+ string const sysdirprefix = "/systemlyxdir/";
+ if (prefixIs(origin, sysdirprefix)) {
+ origin.replace(0, sysdirprefix.length() - 1,
+ package().system_support().absFileName());
+ }
} else if (token == "\\begin_preamble") {
readPreamble(lex);
} else if (token == "\\begin_local_layout") {
} else if (token == "\\master") {
lex.eatLine();
master = lex.getString();
+ if (!filepath.empty() && FileName::isAbsolute(origin)) {
+ bool const isabs = FileName::isAbsolute(master);
+ FileName const abspath(isabs ? master : origin + master);
+ bool const moved = filepath != FileName(origin);
+ if (moved && abspath.exists()) {
+ docstring const path = isabs
+ ? from_utf8(master)
+ : from_utf8(abspath.realPath());
+ docstring const refpath =
+ from_utf8(filepath.absFileName());
+ master = to_utf8(makeRelPath(path, refpath));
+ }
+ }
} else if (token == "\\suppress_date") {
lex >> suppress_date;
} else if (token == "\\justification") {
return token;
}
- return string();
+ return result;
}
-void BufferParams::writeFile(ostream & os) const
+void BufferParams::writeFile(ostream & os, Buffer const * buf) const
{
// The top of the file is written by the buffer.
// Prints out the buffer info into the .lyx file given by file
+ // the document directory
+ string filepath = buf->filePath();
+ string const sysdir = package().system_support().absFileName();
+ if (prefixIs(filepath, sysdir))
+ filepath.replace(0, sysdir.length(), "/systemlyxdir/");
+ else if (!lyxrc.save_origin)
+ filepath = "unavailable";
+ os << "\\origin " << filepath << '\n';
+
// the textclass
- os << "\\textclass " << baseClass()->name() << '\n';
+ os << "\\textclass " << buf->includedFilePath(addName(buf->layoutPos(),
+ baseClass()->name()), "layout")
+ << '\n';
// then the preamble
if (!preamble.empty()) {
}
// some languages are only available via polyglossia
- if (features.runparams().flavor == OutputParams::XETEX
+ if ((features.runparams().flavor == OutputParams::XETEX
+ || features.runparams().flavor == OutputParams::LUATEX)
&& (features.hasPolyglossiaExclusiveLanguages()
|| useNonTeXFonts))
features.require("polyglossia");
// are doing!
if (features.mustProvide("fix-cm"))
os << "\\RequirePackage{fix-cm}\n";
+ // Likewise for fixltx2e. If other packages conflict with this policy,
+ // treat it as a package bug (and report it!)
+ // See http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/4407
+ if (features.mustProvide("fixltx2e"))
+ os << "\\RequirePackage{fixltx2e}\n";
os << "\\documentclass";
// XeTeX and LuaTeX (with OS fonts) do not need fontenc
if (!useNonTeXFonts && !features.isProvided("fontenc")
&& font_encoding() != "default") {
- vector<string> fontencs;
- // primary language font encoding and default encoding
- if (ascii_lowercase(language->fontenc()) != "none") {
- vector<string> fencs = getVectorFromString(font_encoding());
- fontencs.insert(fontencs.end(), fencs.begin(), fencs.end());
- fencs = getVectorFromString(language->fontenc());
- vector<string>::const_iterator fit = fencs.begin();
- for (; fit != fencs.end(); ++fit) {
- if (find(fontencs.begin(), fontencs.end(), *fit) == fontencs.end())
- fontencs.push_back(*fit);
- }
- }
+ // get main font encodings
+ vector<string> fontencs = font_encodings();
// get font encodings of secondary languages
features.getFontEncodings(fontencs);
if (!fontencs.empty()) {
else if (dformat == "lyx")
result = OutputParams::LYX;
else if (dformat == "pdflatex")
- result = OutputParams::PDFLATEX;
+ result = OutputParams::PDFLATEX;
else if (dformat == "xetex")
result = OutputParams::XETEX;
else if (dformat == "luatex")
string const BufferParams::font_encoding() const
{
- return (fontenc == "global") ? lyxrc.fontenc : fontenc;
+ return font_encodings().empty() ? "default" : font_encodings().back();
+}
+
+
+vector<string> const BufferParams::font_encodings() const
+{
+ string doc_fontenc = (fontenc == "global") ? lyxrc.fontenc : fontenc;
+
+ vector<string> fontencs;
+
+ // "default" means "no explicit font encoding"
+ if (doc_fontenc != "default") {
+ fontencs = getVectorFromString(doc_fontenc);
+ if (!language->fontenc().empty()
+ && ascii_lowercase(language->fontenc()) != "none") {
+ vector<string> fencs = getVectorFromString(language->fontenc());
+ vector<string>::const_iterator fit = fencs.begin();
+ for (; fit != fencs.end(); ++fit) {
+ if (find(fontencs.begin(), fontencs.end(), *fit) == fontencs.end())
+ fontencs.push_back(*fit);
+ }
+ }
+ }
+
+ return fontencs;
}