X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=3f0f44aeff5956fe659c638593017700bf5008a2;hb=5a8e91d1c5381d8c152b12269707b547d5241624;hp=c7ec167709746eef17d89bb687455435b5e7d818;hpb=9894e0be23dafe3ad195d483ed7a0dd44cabf847;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index c7ec167709..3f0f44aeff 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -304,6 +304,35 @@ SpaceTranslator const & spacetranslator() return translator; } + +bool inSystemDir(FileName const & document_dir, string & system_dir) +{ + // A document is assumed to be in a system LyX directory (not + // necessarily the system directory of the running instance) + // if both "configure.py" and "chkconfig.ltx" are found in + // either document_dir/../ or document_dir/../../. + // If true, the system directory path is returned in system_dir + // with a trailing path separator. + + string const msg = "Checking whether document is in a system dir..."; + + string dir = document_dir.absFileName(); + + for (int i = 0; i < 2; ++i) { + dir = addPath(dir, ".."); + if (!fileSearch(dir, "configure.py").empty() && + !fileSearch(dir, "chkconfig.ltx").empty()) { + LYXERR(Debug::FILES, msg << " yes"); + system_dir = addPath(FileName(dir).realPath(), ""); + return true; + } + } + + LYXERR(Debug::FILES, msg << " no"); + system_dir = string(); + return false; +} + } // anon namespace @@ -369,6 +398,7 @@ BufferParams::BufferParams() biblio_style = "plain"; use_bibtopic = false; use_indices = false; + save_transient_properties = true; track_changes = false; output_changes = false; use_default_options = true; @@ -429,6 +459,9 @@ BufferParams::BufferParams() output_sync = false; use_refstyle = true; + + // map current author + author_map_[pimpl_->authorlist.get(0).bufferId()] = 0; } @@ -504,6 +537,12 @@ AuthorList const & BufferParams::authors() const } +void BufferParams::addAuthor(Author a) +{ + author_map_[a.bufferId()] = pimpl_->authorlist.record(a); +} + + BranchList & BufferParams::branchlist() { return pimpl_->branchlist; @@ -664,13 +703,19 @@ string BufferParams::readToken(Lexer & lex, string const & token, frontend::Alert::warning(_("Document class not available"), msg, true); } + } else if (token == "\\save_transient_properties") { + lex >> save_transient_properties; } 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()); + string docsys; + if (inSystemDir(filepath, docsys)) + origin.replace(0, sysdirprefix.length() - 1, docsys); + else + origin.replace(0, sysdirprefix.length() - 1, + package().system_support().absFileName()); } } else if (token == "\\begin_preamble") { readPreamble(lex); @@ -876,7 +921,7 @@ string BufferParams::readToken(Lexer & lex, string const & token, istringstream ss(lex.getString()); Author a; ss >> a; - author_map[a.bufferId()] = pimpl_->authorlist.record(a); + addAuthor(a); } else if (token == "\\paperorientation") { string orient; lex >> orient; @@ -1006,12 +1051,21 @@ 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) + os << "\\save_transient_properties " + << convert(save_transient_properties) << '\n'; + + // the document directory (must end with a path separator) + // realPath() is used to resolve symlinks, while addPath(..., "") + // ensures a trailing path separator. + string docsys; + string filepath = addPath(buf->fileName().onlyPath().realPath(), ""); + string const sysdir = inSystemDir(FileName(filepath), docsys) ? docsys + : addPath(package().system_support().realPath(), ""); + string const relpath = + to_utf8(makeRelPath(from_utf8(filepath), from_utf8(sysdir))); + if (!prefixIs(relpath, "../") && !FileName::isAbsolute(relpath)) + filepath = addPath("/systemlyxdir", relpath); + else if (!save_transient_properties || !lyxrc.save_origin) filepath = "unavailable"; os << "\\origin " << quoteIfNeeded(filepath) << '\n'; @@ -1260,9 +1314,15 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const } } - os << "\\tracking_changes " << convert(track_changes) << '\n' - << "\\output_changes " << convert(output_changes) << '\n' - << "\\html_math_output " << html_math_output << '\n' + os << "\\tracking_changes " + << (save_transient_properties ? convert(track_changes) : "false") + << '\n'; + + os << "\\output_changes " + << (save_transient_properties ? convert(output_changes) : "false") + << '\n'; + + os << "\\html_math_output " << html_math_output << '\n' << "\\html_css_as_file " << html_css_as_file << '\n' << "\\html_be_strict " << convert(html_be_strict) << '\n'; @@ -1381,11 +1441,8 @@ void BufferParams::validate(LaTeXFeatures & features) const } // some languages are only available via polyglossia - if ((features.runparams().flavor == OutputParams::XETEX - || features.runparams().flavor == OutputParams::LUATEX) - && (features.hasPolyglossiaExclusiveLanguages() - || useNonTeXFonts)) - features.require("polyglossia"); + if (features.hasPolyglossiaExclusiveLanguages()) + features.require("polyglossia"); if (useNonTeXFonts && fontsMath() != "auto") features.require("unicode-math"); @@ -1560,7 +1617,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << from_ascii(ams); if (useNonTeXFonts) { - os << "\\usepackage{fontspec}\n"; + if (!features.isProvided("fontspec")) + os << "\\usepackage{fontspec}\n"; if (features.mustProvide("unicode-math") && features.isAvailable("unicode-math")) os << "\\usepackage{unicode-math}\n"; @@ -2025,7 +2083,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // koma's own caption commands are used instead of caption. We // use \PassOptionsToPackage here because the user could have // already loaded subfig in the preamble. - if (features.isRequired("subfig")) { + if (features.mustProvide("subfig")) { atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n" " \\PassOptionsToPackage{caption=false}{subfig}}\n" "\\usepackage{subfig}\n"; @@ -2086,7 +2144,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } if (features.isRequired("bicaption")) lyxpreamble += "\\usepackage{bicaption}\n"; - if (!listings_params.empty() || features.isRequired("listings")) + if (!listings_params.empty() || features.mustProvide("listings")) lyxpreamble += "\\usepackage{listings}\n"; if (!listings_params.empty()) { lyxpreamble += "\\lstset{"; @@ -2100,6 +2158,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // xunicode needs to be loaded at least after amsmath, amssymb, // esint and the other packages that provide special glyphs + // The package only supports XeTeX currently. if (features.runparams().flavor == OutputParams::XETEX && useNonTeXFonts) lyxpreamble += "\\usepackage{xunicode}\n"; @@ -2114,14 +2173,17 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]"; lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n"; // now setup the other languages - std::map const polylangs = + set const polylangs = features.getPolyglossiaLanguages(); - for (std::map::const_iterator mit = polylangs.begin(); + for (set::const_iterator mit = polylangs.begin(); mit != polylangs.end() ; ++mit) { + // We do not output the options here; they are output in + // the language switch commands. This is safer if multiple + // varieties are used. + if (*mit == language->polyglossia()) + continue; lyxpreamble += "\\setotherlanguage"; - if (!mit->second.empty()) - lyxpreamble += "[" + from_ascii(mit->second) + "]"; - lyxpreamble += "{" + from_ascii(mit->first) + "}\n"; + lyxpreamble += "{" + from_ascii(*mit) + "}\n"; } } @@ -2321,7 +2383,10 @@ string BufferParams::bufferFormat() const string format = documentClass().outputFormat(); if (format == "latex") { if (useNonTeXFonts) - return "xetex"; // actually "xetex or luatex" + // FIXME: In this context, this means "xetex or luatex" + // with fontspec. We cannot differentiate further here. + // But maybe use a more appropriate string. + return "xetex"; if (encoding().package() == Encoding::japanese) return "platex"; } @@ -2391,11 +2456,8 @@ vector BufferParams::backends() const v.push_back("xetex"); } else if (buffmt == "xetex") { v.push_back("xetex"); - // FIXME: need to test all languages (bug 8205) - if (!language || !language->isPolyglossiaExclusive()) { - v.push_back("luatex"); - v.push_back("dviluatex"); - } + v.push_back("luatex"); + v.push_back("dviluatex"); } else v.push_back(buffmt); @@ -2941,15 +3003,13 @@ docstring BufferParams::getGraphicsDriver(string const & package) const void BufferParams::writeEncodingPreamble(otexstream & os, LaTeXFeatures & features) const { - // "inputenc" package not required with non-TeX fonts. - if (useNonTeXFonts) - return; - // "inputenc" fails with XeTeX (even in 8-bit compatiblitly mode) and with TeX fonts, - // (this is a bug in the "inputenc" package see #9740). - if (features.runparams().flavor == OutputParams::XETEX) + // XeTeX/LuaTeX: (see also #9740) + // With Unicode fonts we use utf8-plain without encoding package. + // With TeX fonts, we cannot use utf8-plain, but "inputenc" fails. + // XeTeX must use ASCII encoding (see Buffer.cpp), + // for LuaTeX, we load "luainputenc" (see below). + if (useNonTeXFonts || features.runparams().flavor == OutputParams::XETEX) return; - // For LuaTeX with TeX fonts, we can load - // the "luainputenc" package with the specified encoding(s) (see below). if (inputenc == "auto") { string const doc_encoding = @@ -2957,10 +3017,12 @@ void BufferParams::writeEncodingPreamble(otexstream & os, Encoding::Package const package = language->encoding()->package(); - // Create a list with all the input encodings used - // in the document - set encodings = - features.getEncodingSet(doc_encoding); + // Create list of inputenc options: + set encodings; + // luainputenc fails with more than one encoding + if (!features.runparams().isFullUnicode()) // if we reach this point, this means LuaTeX with TeX fonts + // list all input encodings used in the document + encodings = features.getEncodingSet(doc_encoding); // If the "japanese" package (i.e. pLaTeX) is used, // inputenc must be omitted. @@ -3141,14 +3203,13 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const Encoding const & BufferParams::encoding() const { - // FIXME: For export with XeTeX and TeX fonts, - // this function returns the wrong value. - // The combination of XeTeX and TeX-fonts requires ASCII (see #9740). - // However, the flavor is no buffer parameter but only known once export started. - // Currently, we set runparams.encoding to ASCII in Buffer::makeLaTeXFile - // (for export) and Buffer::writeLaTeXSource (for preview) - // and prevent overwriting it with another encoding in Paragraph::latex - // and at four places in output_latex.cpp. + // Main encoding for LaTeX output. + // + // Exception: XeTeX with 8-bit TeX fonts requires ASCII (see #9740). + // As the "flavor" is only known once export started, this + // cannot be handled here. Instead, runparams.encoding is set + // to ASCII in Buffer::makeLaTeXFile (for export) + // and Buffer::writeLaTeXSource (for preview). if (useNonTeXFonts) return *(encodings.fromLyXName("utf8-plain")); if (inputenc == "auto" || inputenc == "default")