]> git.lyx.org Git - features.git/commitdiff
Fix bug #7835 (Relative paths are not supported by the TEXINPUTS prefix)
authorEnrico Forestieri <forenr@lyx.org>
Sun, 23 Oct 2011 03:32:37 +0000 (03:32 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Sun, 23 Oct 2011 03:32:37 +0000 (03:32 +0000)
This restores \input@path handling, which turns out to be necessary, as
the TEXINPUTS mechanism is not used with relative paths. It turns out
that both methods must be used, because \input@path does not work in all
cases (most notably with tikz).

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_2_0_X@39931 a592a061-630c-0410-9148-cb99ea01b6c8

src/Buffer.cpp
src/Buffer.h
src/BufferList.cpp
src/graphics/PreviewLoader.cpp
src/insets/InsetInclude.cpp
src/support/docstream.cpp
src/support/docstream.h
status.20x

index 732ffd7abe6aa02126a320b2069841e26e637413..86a1d03650c889ba0e64fa53c87ff238c40fa620 100644 (file)
@@ -1260,6 +1260,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
 {
@@ -1292,7 +1293,8 @@ bool Buffer::makeLaTeXFile(FileName const & fname,
        otexstream os(ofs, d->texrow);
        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;
@@ -1335,6 +1337,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
 {
@@ -1370,12 +1373,81 @@ void Buffer::writeLaTeXSource(otexstream & os,
        // macros will be put in the prefix anyway.
        updateMacroInstances(OutputUpdate);
 
-       // 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.
@@ -1634,6 +1706,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..."));
@@ -1643,7 +1716,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());
@@ -3046,7 +3119,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;
@@ -3444,7 +3517,7 @@ bool Buffer::doExport(string const & format, 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"];
@@ -3458,7 +3531,7 @@ bool Buffer::doExport(string const & format, 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"];
index 01e300e41a622f50275f47beb082aa582ba462d3..01d842b446d5df410b1676290a0d3a28ecbbe4ac 100644 (file)
@@ -272,6 +272,7 @@ public:
 
        /// Just a wrapper for writeLaTeXSource, first creating the ofstream.
        bool makeLaTeXFile(support::FileName const & filename,
+                          std::string const & original_path,
                           OutputParams const &,
                           bool output_preamble = true,
                           bool output_body = true) const;
@@ -298,6 +299,7 @@ public:
            \endcode
         */
        void writeLaTeXSource(otexstream & os,
+                          std::string const & original_path,
                           OutputParams const &,
                           bool output_preamble = true,
                           bool output_body = true) const;
index 01b344f039d85920aee497935fd01a4ddd245326..e19c8aa63d3f86523e7da5f4609fef018c28cb82 100644 (file)
@@ -212,7 +212,8 @@ void BufferList::updateIncludedTeXfiles(string const & masterTmpDir,
        for (; it != end; ++it) {
                if (!(*it)->isDepClean(masterTmpDir)) {
                        string writefile = addName(masterTmpDir, (*it)->latexName());
-                       (*it)->makeLaTeXFile(FileName(writefile), runparams, false);
+                       (*it)->makeLaTeXFile(FileName(writefile), masterTmpDir,
+                                            runparams, false);
                        (*it)->markDepClean(masterTmpDir);
                }
        }
index c8ba70cdafa94f4d887636313bc0f88e9fbc2ccf..9836eeb49a58ca44f081c6293bf89b1203d38342 100644 (file)
@@ -710,7 +710,7 @@ void PreviewLoader::Impl::dumpPreamble(otexstream & os) const
        runparams.nice = true;
        runparams.moving_arg = true;
        runparams.free_spacing = true;
-       buffer_.writeLaTeXSource(os, runparams, true, false);
+       buffer_.writeLaTeXSource(os, buffer_.filePath(), runparams, true, false);
 
        // FIXME! This is a HACK! The proper fix is to control the 'true'
        // passed to WriteStream below:
index 324b4a07628f9ae9f6fff7c503fdebe9ce06daa2..c5a3b0d668f032dae0e6cb1973d9802b14eef890 100644 (file)
@@ -617,7 +617,8 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const
                runparams.master_language = buffer().params().language;
                runparams.par_begin = 0;
                runparams.par_end = tmp->paragraphs().size();
-               if (!tmp->makeLaTeXFile(tmpwritefile, runparams, false)) {
+               if (!tmp->makeLaTeXFile(tmpwritefile, masterFileName(buffer()).
+                               onlyPath().absFileName(), runparams, false)) {
                        docstring msg = bformat(_("Included file `%1$s' "
                                        "was not exported correctly.\nWarning: "
                                        "LaTeX export is probably incomplete."),
@@ -656,8 +657,8 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const
                // In this case, it's not a LyX file, so we copy the file
                // to the temp dir, so that .aux files etc. are not created
                // in the original dir. Files included by this file will be
-               // found via the environment variable TEXINPUTS, which may be
-               // set in preferences and by default includes the original dir.
+               // found via either the environment variable TEXINPUTS, or
+               // input@path, see ../Buffer.cpp.
                unsigned long const checksum_in  = included_file.checksum();
                unsigned long const checksum_out = writefile.checksum();
 
index 3fb0c032951db82adb812f49bc45aa0a2d62b705..a44c062272e6ec5058fd81b776830828ae61b23c 100644 (file)
@@ -482,6 +482,13 @@ otexstream & operator<<(otexstream & ots, docstring const & s)
 }
 
 
+otexstream & operator<<(otexstream & ots, string const & s)
+{
+       ots << s.c_str();
+       return ots;
+}
+
+
 otexstream & operator<<(otexstream & ots, char const * s)
 {
        size_t const len = strlen(s);
index f59030f9238ec7125023acc8a43ebd0e90aa5340..b7e30409b368f6304bf97d00e4e69673b75e2582 100644 (file)
@@ -154,6 +154,8 @@ otexstream & operator<<(otexstream &, odocstream_manip);
 ///
 otexstream & operator<<(otexstream &, docstring const &);
 ///
+otexstream & operator<<(otexstream &, std::string const &);
+///
 otexstream & operator<<(otexstream &, char const *);
 ///
 otexstream & operator<<(otexstream &, char);
index 41b8b67e2e4db53d5731eae55b2734f39dcbc656..1670f28ac01d583aa245a8e4f841182a752621c1 100644 (file)
@@ -101,6 +101,8 @@ What's new
 - Fix deletion of temporary file used for preferences conversion on
   Windows (bug 7796).
 
+- Fix handling of relative paths used in the preamble or ERT (bug 7835).
+
 
 * USER INTERFACE