http://bugzilla.lyx.org/show_bug.cgi?id=3522
reviewed and approved by Georg. The patch does the following: - it moves all the encoding checks in BufferParams::writeLaTeX to an own function "writeEncodingPreamble" and (so in BufferParams.cpp most is just code-shuffling) - accesses that from PreviewLoader So the preview snippets are always compiled with the same encoding as the main document, which should work in any case I can imagine (also if utf8-inputenc is not available). I tested it with several encodings. Seems to work fine (more testing is appreciated, though). I think this bug should be fixed for 1.5.0. Jürgen
Index: src/graphics/PreviewLoader.cpp =================================================================== --- src/graphics/PreviewLoader.cpp (Revision 18516) +++ src/graphics/PreviewLoader.cpp (Arbeitskopie) @@ -15,14 +15,19 @@ #include "GraphicsCache.h" #include "Buffer.h" +#include "BufferParams.h" #include "Converter.h" #include "debug.h" +#include "Encoding.h" #include "Format.h" #include "InsetIterator.h" #include "Color.h" +#include "LaTeXFeatures.h" #include "LyXRC.h" +#include "output.h" #include "OutputParams.h" #include "Paragraph.h" +#include "TexRow.h" #include "frontends/Application.h" // hexName @@ -570,10 +575,16 @@ // Output the LaTeX file. FileName const latexfile(filename_base + ".tex"); - // FIXME UNICODE - // This creates an utf8 encoded file, but the proper inputenc - // command is missing. - odocfstream of(latexfile.toFilesystemEncoding().c_str()); + // we use the encoding of the buffer + Encoding const & enc = buffer_.params().encoding(); + odocfstream of(enc.iconvName()); + TexRow texrow; + OutputParams runparams(&enc); + LaTeXFeatures features(buffer_, buffer_.params(), runparams); + + if (!openFileWrite(of, latexfile)) + return; + if (!of) { LYXERR(Debug::GRAPHICS) << "PreviewLoader::startLoading()\n" << "Unable to create LaTeX file\n" @@ -582,10 +593,18 @@ } of << "\\batchmode\n"; dumpPreamble(of); + // handle inputenc etc. + of << buffer_.params().writeEncodingPreamble(features, texrow); of << "\n\\begin{document}\n"; dumpData(of, inprogress.snippets); of << "\n\\end{document}\n"; of.close(); + if (of.fail()) { + LYXERR(Debug::GRAPHICS) << "PreviewLoader::startLoading()\n" + << "File was not closed properly." + << endl; + return; + } // The conversion command. ostringstream cs; Index: src/BufferParams.h =================================================================== --- src/BufferParams.h (Revision 18516) +++ src/BufferParams.h (Arbeitskopie) @@ -253,6 +253,9 @@ std::string const paperSizeName() const; /// set up if and how babel is called std::string const babelCall(std::string const & lang_opts) const; + /// handle inputenc etc. + docstring const writeEncodingPreamble(LaTeXFeatures & features, + TexRow & texrow) const; /// set up the document fonts std::string const loadFonts(std::string const & rm, std::string const & sf, std::string const & tt, Index: src/BufferParams.cpp =================================================================== --- src/BufferParams.cpp (Revision 18516) +++ src/BufferParams.cpp (Arbeitskopie) @@ -906,62 +906,9 @@ texrow.newline(); } - if (inputenc == "auto") { - string const doc_encoding = - language->encoding()->latexName(); - Encoding::Package const package = - language->encoding()->package(); + // handle inputenc etc. + os << writeEncodingPreamble(features, texrow); - // Create a list with all the input encodings used - // in the document - std::set<string> encodings = - features.getEncodingSet(doc_encoding); - - if (!encodings.empty() || package == Encoding::inputenc) { - os << "\\usepackage["; - std::set<string>::const_iterator it = encodings.begin(); - std::set<string>::const_iterator const end = encodings.end(); - if (it != end) { - os << from_ascii(*it); - ++it; - } - for (; it != end; ++it) - os << ',' << from_ascii(*it); - if (package == Encoding::inputenc) { - if (!encodings.empty()) - os << ','; - os << from_ascii(doc_encoding); - } - os << "]{inputenc}\n"; - texrow.newline(); - } - if (package == Encoding::CJK) { - os << "\\usepackage{CJK}\n"; - texrow.newline(); - } - } else if (inputenc != "default") { - switch (language->encoding()->package()) { - case Encoding::none: - break; - case Encoding::inputenc: - os << "\\usepackage[" << from_ascii(inputenc) - << "]{inputenc}\n"; - texrow.newline(); - break; - case Encoding::CJK: - os << "\\usepackage{CJK}\n"; - texrow.newline(); - break; - } - } - - // The encoding "armscii8" is only available when the package "armtex" is loaded. - // armscii8 is used for Armenian. - if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") { - os << "\\usepackage{armtex}\n"; - texrow.newline(); - } - if (!listings_params.empty()) { os << "\\usepackage{listings}\n"; texrow.newline(); @@ -1422,6 +1369,71 @@ } +docstring const BufferParams::writeEncodingPreamble(LaTeXFeatures & features, + TexRow & texrow) const +{ + odocstringstream os; + + if (inputenc == "auto") { + string const doc_encoding = + language->encoding()->latexName(); + Encoding::Package const package = + language->encoding()->package(); + + // Create a list with all the input encodings used + // in the document + std::set<string> encodings = + features.getEncodingSet(doc_encoding); + + if (!encodings.empty() || package == Encoding::inputenc) { + os << "\\usepackage["; + std::set<string>::const_iterator it = encodings.begin(); + std::set<string>::const_iterator const end = encodings.end(); + if (it != end) { + os << from_ascii(*it); + ++it; + } + for (; it != end; ++it) + os << ',' << from_ascii(*it); + if (package == Encoding::inputenc) { + if (!encodings.empty()) + os << ','; + os << from_ascii(doc_encoding); + } + os << "]{inputenc}\n"; + texrow.newline(); + } + if (package == Encoding::CJK) { + os << "\\usepackage{CJK}\n"; + texrow.newline(); + } + } else if (inputenc != "default") { + switch (language->encoding()->package()) { + case Encoding::none: + break; + case Encoding::inputenc: + os << "\\usepackage[" << from_ascii(inputenc) + << "]{inputenc}\n"; + texrow.newline(); + break; + case Encoding::CJK: + os << "\\usepackage{CJK}\n"; + texrow.newline(); + break; + } + } + + // The encoding "armscii8" is only available when the package "armtex" is loaded. + // armscii8 is used for Armenian. + if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") { + os << "\\usepackage{armtex}\n"; + texrow.newline(); + } + + return os.str(); +} + + string const BufferParams::loadFonts(string const & rm, string const & sf, string const & tt, bool const & sc, bool const & osf,