]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
tex2lyx/text.cpp: fix 2 typos
[lyx.git] / src / Buffer.cpp
index fdcbb04259525cf4922e50cf425506398a3ff3d2..8204fe1aeaca2c1697c09fc5eca9af87c0b9e217 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;
@@ -358,6 +356,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
        bibfile_cache_valid_ = cloned_buffer_->d->bibfile_cache_valid_;
        bibfile_status_ = cloned_buffer_->d->bibfile_status_;
        cite_labels_valid_ = cloned_buffer_->d->cite_labels_valid_;
+       unnamed = cloned_buffer_->d->unnamed;
 }
 
 
@@ -713,10 +712,10 @@ int Buffer::readHeader(Lexer & lex)
        params().indiceslist().clear();
        params().backgroundcolor = lyx::rgbFromHexName("#ffffff");
        params().isbackgroundcolor = false;
-       params().fontcolor = lyx::rgbFromHexName("#000000");
+       params().fontcolor = RGBColor(0, 0, 0);
        params().isfontcolor = false;
-       params().notefontcolor = lyx::rgbFromHexName("#cccccc");
-       params().boxbgcolor = lyx::rgbFromHexName("#ff0000");
+       params().notefontcolor = RGBColor(0xCC, 0xCC, 0xCC);
+       params().boxbgcolor = RGBColor(0xFF, 0, 0);
        params().html_latex_start.clear();
        params().html_latex_end.clear();
        params().html_math_img_scale = 1.0;
@@ -1300,6 +1299,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 +1311,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 +1340,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 +1384,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 +1411,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.
@@ -1642,6 +1713,21 @@ void Buffer::writeLyXHTMLSource(odocstream & os,
                                << styleinfo
                                << "</style>\n";
                }
+
+               bool const needfg = params().fontcolor != RGBColor(0, 0, 0);
+               bool const needbg = params().backgroundcolor != RGBColor(0xFF, 0xFF, 0xFF);
+               if (needfg || needbg) {
+                               os << "<style type='text/css'>\nbody {\n";
+                               if (needfg)
+                                  os << "  color: "
+                                           << from_ascii(X11hexname(params().fontcolor))
+                                           << ";\n";
+                               if (needbg)
+                                  os << "  background-color: "
+                                           << from_ascii(X11hexname(params().backgroundcolor))
+                                           << ";\n";
+                               os << "}\n</style>\n";
+               }
                os << "</head>\n<body>\n";
        }
 
@@ -1662,6 +1748,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..."));
@@ -1671,7 +1758,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());
@@ -1928,7 +2015,15 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 
                case LFUN_BUFFER_EXPORT: {
                        docstring const arg = cmd.argument();
-                       enable = arg == "custom" || params().isExportable(to_utf8(arg));
+                       if (arg == "custom") {
+                               enable = true;
+                               break;
+                       }
+                       string format = to_utf8(arg);
+                       size_t pos = format.find(' ');
+                       if (pos != string::npos)
+                               format = format.substr(0, pos);
+                       enable = params().isExportable(format);
                        if (!enable)
                                flag.message(bformat(
                                        _("Don't know how to export to format: %1$s"), arg));
@@ -3094,7 +3189,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;
@@ -3391,12 +3486,23 @@ bool Buffer::isExporting() const
 }
 
 
-bool Buffer::doExport(string const & format, bool put_in_tempdir,
+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 dest_filename;
+       size_t pos = target.find(' ');
+       if (pos != string::npos) {
+               dest_filename = target.substr(pos + 1, target.length() - pos - 1);
+               format = target.substr(0, pos);
+               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;
-       OutputParams runparams(&params().encoding());
        runparams.flavor = OutputParams::LATEX;
        runparams.linelen = lyxrc.plaintext_linelen;
        runparams.includeall = includeall;
@@ -3428,6 +3534,7 @@ bool Buffer::doExport(string const & format, 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;
@@ -3443,6 +3550,7 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir,
        filename = addName(temppath(), filename);
        filename = changeExtension(filename,
                                   formats.extension(backend_format));
+       LYXERR(Debug::FILES, "filename=" << filename);
 
        // Plain text backend
        if (backend_format == "text") {
@@ -3477,7 +3585,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"];
@@ -3491,7 +3599,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"];
@@ -3552,12 +3660,16 @@ bool Buffer::doExport(string const & format, 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 =
                runparams.exportdata->externalFiles(format);
-       string const dest = onlyPath(result_file);
+       string const dest = runparams.export_folder.empty() ?
+               onlyPath(result_file) : runparams.export_folder;
        bool use_force = use_gui ? lyxrc.export_overwrite == ALL_FILES
                                 : force_overwrite == ALL_FILES;
        CopyStatus status = use_force ? FORCE : SUCCESS;
@@ -3566,9 +3678,19 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir,
        vector<ExportedFile>::const_iterator const en = files.end();
        for (; it != en && status != CANCEL; ++it) {
                string const fmt = formats.getFormatFromFile(it->sourceName);
+               string fixedName = it->exportName;
+               if (!runparams.export_folder.empty()) {
+                       // Relative pathnames starting with ../ will be sanitized
+                       // if exporting to a different folder
+                       while (fixedName.substr(0, 3) == "../")
+                               fixedName = fixedName.substr(3, fixedName.length() - 3);
+               }
+               FileName fixedFileName = makeAbsPath(fixedName, dest);
+               fixedFileName.onlyPath().createPath();
                status = copyFile(fmt, it->sourceName,
-                       makeAbsPath(it->exportName, dest),
-                       it->exportName, status == FORCE);
+                       fixedFileName,
+                       it->exportName, status == FORCE,
+                       runparams.export_folder.empty());
        }
 
        if (status == CANCEL) {
@@ -3596,15 +3718,15 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir,
 }
 
 
-bool Buffer::doExport(string const & format, bool put_in_tempdir,
-                     bool includeall) const
+bool Buffer::doExport(string const & target, bool put_in_tempdir,
+       bool includeall) const
 {
        string result_file;
        // (1) export with all included children (omit \includeonly)
-       if (includeall && !doExport(format, put_in_tempdir, true, result_file))
+       if (includeall && !doExport(target, put_in_tempdir, true, result_file))
                return false;
        // (2) export with included children only
-       return doExport(format, put_in_tempdir, false, result_file);
+       return doExport(target, put_in_tempdir, false, result_file);
 }
 
 
@@ -4133,8 +4255,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()) {
@@ -4142,8 +4265,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();