]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
tex2lyx/text.cpp: code simplification
[lyx.git] / src / Buffer.cpp
index 3632af200c769a9bc53f8b3f1914ca27d26acb15..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 = 413; // rgh: html_css_as_file
+int const LYX_FORMAT = LYX_FORMAT_LYX;
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -713,10 +711,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;
@@ -1312,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); }
@@ -1413,12 +1411,13 @@ void Buffer::writeLaTeXSource(otexstream & os,
        LYXERR(Debug::INFO, "lyx document header finished");
 
        // There are a few differences between nice LaTeX and usual files:
-       // usual is \batchmode and has a
-       // special input@path to allow the including of figures
-       // with either \input or \includegraphics (what figinsets do).
-       // 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)
+       // 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.
@@ -1430,7 +1429,7 @@ void Buffer::writeLaTeXSource(otexstream & os,
                if (!original_path.empty()) {
                        // FIXME UNICODE
                        // We don't know the encoding of inputpath
-                       docstring const inputpath = from_utf8(support::latex_path(original_path));
+                       docstring const inputpath = from_utf8(original_path);
                        docstring uncodable_glyphs;
                        Encoding const * const enc = runparams.encoding;
                        if (enc) {
@@ -1448,18 +1447,41 @@ void Buffer::writeLaTeXSource(otexstream & os,
 
                        // 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\n"
-                                                 "current document encoding (namely %2$s).\n"
-                                                 "This will likely result in incomplete output.\n\n"
-                                                 "Choose an appropriate document encoding (such as utf8)\n"
-                                                 "or change the file path name."), inputpath, uncodable_glyphs));
+                               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{{"
-                                  << inputpath << "/}}\n"
+                                  << docdir << "/}}\n"
                                   << "\\makeatother\n";
                        }
                }
@@ -1690,6 +1712,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";
        }
 
@@ -1977,7 +2014,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));
@@ -2333,18 +2378,6 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
                break;
        }
 
-       case LFUN_BUFFER_LANGUAGE: {
-               Language const * oldL = params().language;
-               Language const * newL = languages.getLanguage(argument);
-               if (!newL || oldL == newL)
-                       break;
-               if (oldL->rightToLeft() == newL->rightToLeft() && !isMultiLingual()) {
-                       changeLanguage(oldL, newL);
-                       dr.forceBufferUpdate();
-               }
-               break;
-       }
-
        default:
                dispatched = false;
                break;
@@ -2647,6 +2680,12 @@ ListOfBuffers Buffer::getChildren() const
 {
        ListOfBuffers v;
        collectChildren(v, false);
+       // Make sure we have not included ourselves.
+       ListOfBuffers::iterator bit = find(v.begin(), v.end(), this);
+       if (bit != v.end()) {
+               LYXERR0("Recursive include detected in `" << fileName() << "'.");
+               v.erase(bit);
+       }
        return v;
 }
 
@@ -2655,6 +2694,12 @@ ListOfBuffers Buffer::getDescendents() const
 {
        ListOfBuffers v;
        collectChildren(v, true);
+       // Make sure we have not included ourselves.
+       ListOfBuffers::iterator bit = find(v.begin(), v.end(), this);
+       if (bit != v.end()) {
+               LYXERR0("Recursive include detected in `" << fileName() << "'.");
+               v.erase(bit);
+       }
        return v;
 }
 
@@ -3440,12 +3485,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;
@@ -3477,11 +3533,14 @@ 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;
                else if (backend_format == "luatex")
                        runparams.flavor = OutputParams::LUATEX;
+               else if (backend_format == "dviluatex")
+                       runparams.flavor = OutputParams::DVILUATEX;
                else if (backend_format == "xetex")
                        runparams.flavor = OutputParams::XETEX;
        }
@@ -3490,6 +3549,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") {
@@ -3599,12 +3659,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;
@@ -3613,9 +3677,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) {
@@ -3643,15 +3717,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);
 }
 
 
@@ -4180,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()) {
@@ -4189,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();