X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Foutput_latex.C;h=e78773eea6862420ab9a675bdd53bfd8e168901b;hb=0657a91fd08e9c31d7f9e6be26055cc5050e5f8b;hp=f7acbf5dedf96e55c0af5ad8c729d95b3a12d893;hpb=03f56201d8d9f4b926e1a5719dea1d16093fd46e;p=lyx.git diff --git a/src/output_latex.C b/src/output_latex.C index f7acbf5ded..e78773eea6 100644 --- a/src/output_latex.C +++ b/src/output_latex.C @@ -29,7 +29,6 @@ #include "insets/insetoptarg.h" #include "support/lstrings.h" -#include "support/unicode.h" namespace lyx { @@ -237,14 +236,13 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf, ParagraphList const & paragraphs, ParagraphList::const_iterator pit, - odocstream & ucs4, TexRow & texrow, + odocstream & os, TexRow & texrow, OutputParams const & runparams_in, string const & everypar) { lyxerr[Debug::LATEX] << "TeXOnePar... " << &*pit << " '" << everypar << "'" << endl; BufferParams const & bparams = buf.params(); - bool further_blank_line = false; LyXLayout_ptr style; // In an inset with unlimited length (all in one row), @@ -275,49 +273,42 @@ TeXOnePar(Buffer const & buf, if (!lyxrc.language_command_end.empty() && previous_language->babel() != doc_language->babel()) { - ucs4 << from_ascii(subst(lyxrc.language_command_end, + os << from_ascii(subst(lyxrc.language_command_end, "$$lang", previous_language->babel())) - << '\n'; + << '\n'; texrow.newline(); } if (lyxrc.language_command_end.empty() || language->babel() != doc_language->babel()) { - ucs4 << from_ascii(subst( + os << from_ascii(subst( lyxrc.language_command_begin, "$$lang", language->babel())) - << '\n'; + << '\n'; texrow.newline(); } } - // FIXME thailatex does not support the inputenc package, so we - // ignore switches from/to tis620-0 encoding here. This does of - // course only work as long as the non-thai text contains ASCII - // only, but it is the best we can do. - bool const use_thailatex = (language->encoding()->name() == "tis620-0" || - previous_language->encoding()->name() == "tis620-0"); - if (bparams.inputenc == "auto" && - language->encoding() != previous_language->encoding() && - !use_thailatex) { - ucs4 << "\\inputencoding{" - << from_ascii(language->encoding()->latexName()) - << "}\n"; + LyXFont const outerfont = + outerFont(std::distance(paragraphs.begin(), pit), + paragraphs); + // This must be identical to basefont in Paragraph::simpleTeXOnePar + LyXFont basefont = (pit->beginOfBody() > 0) ? + pit->getLabelFont(bparams, outerfont) : + pit->getLayoutFont(bparams, outerfont); + Encoding const & outer_encoding(*(outerfont.language()->encoding())); + // FIXME we switch from the outer encoding to the encoding of + // this paragraph, since I could not figure out the correct + // logic to take the encoding of the previous paragraph into + // account. This may result in some unneeded encoding changes. + if (switchEncoding(os, bparams, outer_encoding, + *(basefont.language()->encoding()))) { + os << '\n'; texrow.newline(); } - // We need to output the paragraph to a temporary stream if we - // need to change the encoding. Don't do this if the result does - // not go to a file but to the builtin source viewer. - odocstringstream par_stream; - bool const change_encoding = !runparams_in.dryrun && - bparams.inputenc == "auto" && - language->encoding() != doc_language->encoding() && - !use_thailatex; - // don't trigger the copy ctor because it's private on msvc - odocstream & os = *(change_encoding ? &par_stream : &ucs4); // In an inset with unlimited length (all in one row), // don't allow any special options in the paragraph @@ -340,11 +331,6 @@ TeXOnePar(Buffer const & buf, os << '\n'; texrow.newline(); } - - if (further_blank_line) { - os << '\n'; - texrow.newline(); - } } switch (style->latextype) { @@ -376,9 +362,6 @@ TeXOnePar(Buffer const & buf, // FIXME UNICODE os << from_utf8(everypar); - LyXFont const outerfont = - outerFont(std::distance(paragraphs.begin(), pit), - paragraphs); bool need_par = pit->simpleTeXOnePar(buf, bparams, outerfont, os, texrow, runparams); @@ -410,14 +393,13 @@ TeXOnePar(Buffer const & buf, } else if (is_command) os << '}'; + bool pending_newline = false; switch (style->latextype) { case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: if (boost::next(pit) != paragraphs.end() - && (pit->params().depth() < boost::next(pit)->params().depth())) { - os << '\n'; - texrow.newline(); - } + && (pit->params().depth() < boost::next(pit)->params().depth())) + pending_newline = true; break; case LATEX_ENVIRONMENT: { // if its the last paragraph of the current environment @@ -433,27 +415,21 @@ TeXOnePar(Buffer const & buf, // fall through possible default: // we don't need it for the last paragraph!!! - if (boost::next(pit) != paragraphs.end()) { - os << '\n'; - texrow.newline(); - } + if (boost::next(pit) != paragraphs.end()) + pending_newline = true; } if (!pit->forceDefaultParagraphs()) { - further_blank_line = false; - - if (further_blank_line) { - os << '\n'; - texrow.newline(); - } - if (!pit->params().spacing().isDefault() && (boost::next(pit) == paragraphs.end() || !boost::next(pit)->hasSameLayout(*pit))) { - os << from_ascii(pit->params().spacing().writeEnvirEnd()) - << '\n'; - texrow.newline(); + if (pending_newline) { + os << '\n'; + texrow.newline(); + } + os << from_ascii(pit->params().spacing().writeEnvirEnd()); + pending_newline = true; } } @@ -463,18 +439,32 @@ TeXOnePar(Buffer const & buf, // we need to reset the language at the end of footnote or // float. + if (pending_newline) { + os << '\n'; + texrow.newline(); + } if (lyxrc.language_command_end.empty()) os << from_ascii(subst( lyxrc.language_command_begin, "$$lang", - doc_language->babel())) - << '\n'; + doc_language->babel())); else os << from_ascii(subst( lyxrc.language_command_end, "$$lang", - language->babel())) - << '\n'; + language->babel())); + pending_newline = true; + } + + // FIXME we switch from the encoding of this paragraph to the + // outer encoding, since I could not figure out the correct logic + // to take the encoding of the next paragraph into account. + // This may result in some unneeded encoding changes. + basefont = pit->getLayoutFont(bparams, outerfont); + switchEncoding(os, bparams, *(basefont.language()->encoding()), + outer_encoding); + if (pending_newline) { + os << '\n'; texrow.newline(); } @@ -490,59 +480,6 @@ TeXOnePar(Buffer const & buf, lyxerr.debugging(Debug::LATEX)) lyxerr << "TeXOnePar...done " << &*boost::next(pit) << endl; - if (change_encoding) { - lyxerr[Debug::LATEX] << "Converting paragraph to encoding " - << language->encoding()->iconvName() << endl; - docstring const par = par_stream.str(); - // Convert the paragraph to the 8bit encoding that we need to - // output. - std::vector const encoded = lyx::ucs4_to_eightbit(par.c_str(), - par.size(), language->encoding()->iconvName()); - // Interpret this as if it was in the 8 bit encoding of the - // document language and convert it back to UCS4. That means - // that faked does not contain pure UCS4 anymore, but what - // will be written to the output file will be correct, because - // the real output stream will do a UCS4 -> document language - // encoding conversion. - // This is of course a hack, but not a bigger one than mixing - // two encodings in one file. - // FIXME: Catch iconv conversion errors and display an error - // dialog. - - // Here follows an explanation how I (gb) came to the current - // solution: - - // codecvt facets are only used by file streams -> OK, maybe - // we could use file streams and not generic streams in the - // latex() methods? No, that does not work, we use them at - // several places to write to string streams. - // Next try: Maybe we could do something else than codecvt - // in our streams, and add a setEncoding() method? That - // does not work unless we rebuild the functionality of file - // and string streams, since both odocfstream and - // odocstringstream inherit from std::basic_ostream - // and we can neither add a method to that class nor change - // the inheritance of the file and string streams. - - // What might be possible is to encapsulate the real file and - // string streams in our own version, and use a homemade - // streambuf that would do the encoding conversion and then - // forward to the real stream. That would probably work, but - // would require far more code and a good understanding of - // stream buffers to get it right. - - // Another idea by JMarc is to use a modifier like - // os << setencoding("iso-8859-1"); - // That currently looks like the best idea. - - std::vector const faked = lyx::eightbit_to_ucs4(&(encoded[0]), - encoded.size(), doc_language->encoding()->iconvName()); - std::vector::const_iterator const end = faked.end(); - std::vector::const_iterator it = faked.begin(); - for (; it != end; ++it) - ucs4.put(*it); - } - return ++pit; } @@ -580,7 +517,8 @@ void latexParagraphs(Buffer const & buf, // well we have to check if we are in an inset with unlimited // length (all in one row) if that is true then we don't allow // any special options in the paragraph and also we don't allow - // any environment other then "Standard" to be valid! + // any environment other than the default layout of the + // text class to be valid! if (!par->forceDefaultParagraphs()) { LyXLayout_ptr const & layout = par->layout(); @@ -616,8 +554,7 @@ void latexParagraphs(Buffer const & buf, par = TeXOnePar(buf, paragraphs, par, os, texrow, runparams, everypar); } else if (layout->isEnvironment() || - !par->params().leftIndent().zero()) - { + !par->params().leftIndent().zero()) { par = TeXEnvironment(buf, paragraphs, par, os, texrow, runparams); } else { @@ -646,4 +583,27 @@ void latexParagraphs(Buffer const & buf, } +int switchEncoding(odocstream & os, BufferParams const & bparams, + Encoding const & oldEnc, Encoding const & newEnc) +{ + // FIXME thailatex does not support the inputenc package, so we + // ignore switches from/to tis620-0 encoding here. This does of + // course only work as long as the non-thai text contains ASCII + // only, but it is the best we can do. + if ((bparams.inputenc == "auto" || bparams.inputenc == "default") && + oldEnc.name() != newEnc.name() && + oldEnc.name() != "tis620-0" && newEnc.name() != "tis620-0") { + lyxerr[Debug::LATEX] << "Changing LaTeX encoding from " + << oldEnc.name() << " to " + << newEnc.name() << endl; + os << setEncoding(newEnc.iconvName()); + if (bparams.inputenc != "default") { + docstring const inputenc(from_ascii(newEnc.latexName())); + os << "\\inputencoding{" << inputenc << '}'; + return 16 + inputenc.length(); + } + } + return 0; +} + } // namespace lyx