]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
tex2lyx/text.cpp: code simplification
[lyx.git] / src / Buffer.cpp
index 0bb1f3bd720cf640b69fac6a61693cd1c8087f4e..33b79b274a3aa1f9ff70e35991280d3fb89bf86a 100644 (file)
@@ -126,9 +126,7 @@ namespace os = support::os;
 
 namespace {
 
-// Do not remove the comment below, so we get merge conflict in
-// independent branches. Instead add your own.
-int const LYX_FORMAT = 416; //uwestoehr : support for horizontal spaces (bug 7728)
+int const LYX_FORMAT = LYX_FORMAT_LYX;
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -1300,6 +1298,7 @@ bool Buffer::write(ostream & ofs) const
 
 
 bool Buffer::makeLaTeXFile(FileName const & fname,
+                          string const & original_path,
                           OutputParams const & runparams_in,
                           bool output_preamble, bool output_body) const
 {
@@ -1311,7 +1310,7 @@ bool Buffer::makeLaTeXFile(FileName const & fname,
                runparams.encoding = encodings.fromLyXName("utf8-plain");
 
        string const encoding = runparams.encoding->iconvName();
-       LYXERR(Debug::LATEX, "makeLaTeXFile encoding: " << encoding << "...");
+       LYXERR(Debug::LATEX, "makeLaTeXFile encoding: " << encoding << ", fname=" << fname.realPath());
 
        ofdocstream ofs;
        try { ofs.reset(encoding); }
@@ -1340,7 +1339,8 @@ bool Buffer::makeLaTeXFile(FileName const & fname,
 
        try {
                os.texrow().reset();
-               writeLaTeXSource(os, runparams, output_preamble, output_body);
+               writeLaTeXSource(os, original_path,
+                     runparams, output_preamble, output_body);
        }
        catch (EncodingException & e) {
                odocstringstream ods;
@@ -1383,6 +1383,7 @@ bool Buffer::makeLaTeXFile(FileName const & fname,
 
 
 void Buffer::writeLaTeXSource(otexstream & os,
+                          string const & original_path,
                           OutputParams const & runparams_in,
                           bool const output_preamble, bool const output_body) const
 {
@@ -1409,12 +1410,81 @@ void Buffer::writeLaTeXSource(otexstream & os,
        }
        LYXERR(Debug::INFO, "lyx document header finished");
 
-       // With respect to nice LaTeX, usual files have \batchmode
+       // There are a few differences between nice LaTeX and usual files:
+       // usual files have \batchmode and special input@path to allow
+       // inclusion of figures specified by an explicitly relative path
+       // (i.e., a path starting with './' or '../') with either \input or
+       // \includegraphics, as the TEXINPUTS method doesn't work in this case.
+       // input@path is set when the actual parameter original_path is set.
+       // This is done for usual tex-file, but not for nice-latex-file.
+       // (Matthias 250696)
+       // Note that input@path is only needed for something the user does
+       // in the preamble, included .tex files or ERT, files included by
+       // LyX work without it.
        if (output_preamble) {
                if (!runparams.nice) {
                        // code for usual, NOT nice-latex-file
                        os << "\\batchmode\n"; // changed from \nonstopmode
                }
+               if (!original_path.empty()) {
+                       // FIXME UNICODE
+                       // We don't know the encoding of inputpath
+                       docstring const inputpath = from_utf8(original_path);
+                       docstring uncodable_glyphs;
+                       Encoding const * const enc = runparams.encoding;
+                       if (enc) {
+                               for (size_t n = 0; n < inputpath.size(); ++n) {
+                                       docstring const glyph =
+                                               docstring(1, inputpath[n]);
+                                       if (enc->latexChar(inputpath[n], true) != glyph) {
+                                               LYXERR0("Uncodable character '"
+                                                       << glyph
+                                                       << "' in input path!");
+                                               uncodable_glyphs += glyph;
+                                       }
+                               }
+                       }
+
+                       // warn user if we found uncodable glyphs.
+                       if (!uncodable_glyphs.empty()) {
+                               frontend::Alert::warning(
+                                       _("Uncodable character in file path"),
+                                       support::bformat(
+                                         _("The path of your document\n"
+                                           "(%1$s)\n"
+                                           "contains glyphs that are unknown "
+                                           "in the current document encoding "
+                                           "(namely %2$s). This may result in "
+                                           "incomplete output, unless "
+                                           "TEXINPUTS contains the document "
+                                           "directory and you don't use "
+                                           "explicitly relative paths (i.e., "
+                                           "paths starting with './' or "
+                                           "'../') in the preamble or in ERT."
+                                           "\n\nIn case of problems, choose "
+                                           "an appropriate document encoding\n"
+                                           "(such as utf8) or change the "
+                                           "file path name."),
+                                         inputpath, uncodable_glyphs));
+                       } else {
+                               string docdir =
+                                       support::latex_path(original_path);
+                               if (contains(docdir, '#')) {
+                                       docdir = subst(docdir, "#", "\\#");
+                                       os << "\\catcode`\\#=11"
+                                             "\\def\\#{#}\\catcode`\\#=6\n";
+                               }
+                               if (contains(docdir, '%')) {
+                                       docdir = subst(docdir, "%", "\\%");
+                                       os << "\\catcode`\\%=11"
+                                             "\\def\\%{%}\\catcode`\\%=14\n";
+                               }
+                               os << "\\makeatletter\n"
+                                  << "\\def\\input@path{{"
+                                  << docdir << "/}}\n"
+                                  << "\\makeatother\n";
+                       }
+               }
 
                // get parent macros (if this buffer has a parent) which will be
                // written at the document begin further down.
@@ -1677,6 +1747,7 @@ int Buffer::runChktex()
        // get LaTeX-Filename
        FileName const path(temppath());
        string const name = addName(path.absFileName(), latexName());
+       string const org_path = filePath();
 
        PathChanger p(path); // path to LaTeX file
        message(_("Running chktex..."));
@@ -1686,7 +1757,7 @@ int Buffer::runChktex()
        runparams.flavor = OutputParams::LATEX;
        runparams.nice = false;
        runparams.linelen = lyxrc.plaintext_linelen;
-       makeLaTeXFile(FileName(name), runparams);
+       makeLaTeXFile(FileName(name), org_path, runparams);
 
        TeXErrors terr;
        Chktex chktex(lyxrc.chktex_command, onlyFileName(name), filePath());
@@ -3117,7 +3188,7 @@ void Buffer::getSourceCode(odocstream & os, string const format,
                else {
                        // latex or literate
                        otexstream ots(os, d->texrow);
-                       writeLaTeXSource(ots, runparams, true, true);
+                       writeLaTeXSource(ots, string(), runparams, true, true);
                }
        } else {
                runparams.par_begin = par_begin;
@@ -3417,15 +3488,17 @@ bool Buffer::isExporting() const
 bool Buffer::doExport(string const & target, bool put_in_tempdir,
        bool includeall, string & result_file) const
 {
+       LYXERR(Debug::FILES, "target=" << target << ", result_file=" << result_file);
        OutputParams runparams(&params().encoding());
        string format = target;
-       string filename;
+       string dest_filename;
        size_t pos = target.find(' ');
        if (pos != string::npos) {
-               filename = target.substr(pos + 1, target.length() - pos - 1);
+               dest_filename = target.substr(pos + 1, target.length() - pos - 1);
                format = target.substr(0, pos);
-               runparams.export_folder = FileName(filename).onlyPath().realPath();
-               FileName(filename).onlyPath().createPath();
+               runparams.export_folder = FileName(dest_filename).onlyPath().realPath();
+               FileName(dest_filename).onlyPath().createPath();
+               LYXERR(Debug::FILES, "format=" << format << ", dest_filename=" << dest_filename << ", export_folder=" << runparams.export_folder);
        }
        MarkAsExporting exporting(this);
        string backend_format;
@@ -3460,6 +3533,7 @@ bool Buffer::doExport(string const & target, bool put_in_tempdir,
 
        } else {
                backend_format = format;
+               LYXERR(Debug::FILES, "backend_format=" << backend_format);
                // FIXME: Don't hardcode format names here, but use a flag
                if (backend_format == "pdflatex")
                        runparams.flavor = OutputParams::PDFLATEX;
@@ -3471,12 +3545,11 @@ bool Buffer::doExport(string const & target, bool put_in_tempdir,
                        runparams.flavor = OutputParams::XETEX;
        }
 
-       if (filename.empty()) {
-               filename = latexName(false);
-               filename = addName(temppath(), filename);
-               filename = changeExtension(filename,
-                                          formats.extension(backend_format));
-       }
+       string filename = latexName(false);
+       filename = addName(temppath(), filename);
+       filename = changeExtension(filename,
+                                  formats.extension(backend_format));
+       LYXERR(Debug::FILES, "filename=" << filename);
 
        // Plain text backend
        if (backend_format == "text") {
@@ -3511,7 +3584,7 @@ bool Buffer::doExport(string const & target, bool put_in_tempdir,
        // LaTeX backend
        else if (backend_format == format) {
                runparams.nice = true;
-               if (!makeLaTeXFile(FileName(filename), runparams)) {
+               if (!makeLaTeXFile(FileName(filename), string(), runparams)) {
                        if (d->cloned_buffer_) {
                                d->cloned_buffer_->d->errorLists["Export"] =
                                        d->errorLists["Export"];
@@ -3525,7 +3598,7 @@ bool Buffer::doExport(string const & target, bool put_in_tempdir,
                return false;
        } else {
                runparams.nice = false;
-               if (!makeLaTeXFile(FileName(filename), runparams)) {
+               if (!makeLaTeXFile(FileName(filename), filePath(), runparams)) {
                        if (d->cloned_buffer_) {
                                d->cloned_buffer_->d->errorLists["Export"] =
                                        d->errorLists["Export"];
@@ -3586,7 +3659,10 @@ bool Buffer::doExport(string const & target, bool put_in_tempdir,
                return true;
        }
 
-       result_file = changeExtension(d->exportFileName().absFileName(), ext);
+       if (dest_filename.empty())
+               result_file = changeExtension(d->exportFileName().absFileName(), ext);
+       else
+               result_file = dest_filename;
        // We need to copy referenced files (e. g. included graphics
        // if format == "dvi") to the result dir.
        vector<ExportedFile> const files =
@@ -4178,8 +4254,9 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
        WordLangTuple wl;
        suggestions.clear();
        word_lang = WordLangTuple();
+       bool const to_end = to.empty();
+       DocIterator const end = to_end ? doc_iterator_end(this) : to;
        // OK, we start from here.
-       DocIterator const end = doc_iterator_end(this);
        for (; from != end; from.forwardPos()) {
                // We are only interested in text so remove the math CursorSlice.
                while (from.inMathed()) {
@@ -4187,8 +4264,8 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
                        from.pos()++;
                }
                // If from is at the end of the document (which is possible
-               // when leaving the mathed) LyX will crash later.
-               if (from == end)
+               // when leaving the mathed) LyX will crash later otherwise.
+               if (from.atEnd() || (!to_end && from >= end))
                        break;
                to = from;
                from.paragraph().spellCheck();