I stumbled over a bug in trunk and branch that slipped in with my CJK patch. If "auto begin" is disabled in Prefs->Language, a language switch command is inserted in an optArg inset, so you get something like
\section[\selectlanguage{english}short title]{long title} in an English document, which breaks LaTeX compilation. The reason is that I assumed (erroneously) that runparams.local_font (as used in other places) is a safe indicator whether we are in an inset or in the main text. However, local_font returns zero not only in the main text, but also in OptArg insets. The attached patch (against branch) fixes the issue by adding a new bool argument "maintext" to latexParagraphs. I have also transferred the begin and end tags from TeXOnePar to latexParagraphs, where they belong IMO. I have tested with all my CJK testcases. Uwe and Koji, could you please test the patch with your cases as well? Thanks, Jürgen
Index: src/output_latex.h =================================================================== --- src/output_latex.h (Revision 22586) +++ src/output_latex.h (Arbeitskopie) @@ -42,7 +42,8 @@ odocstream & ofs, TexRow & texrow, OutputParams const &, - std::string const & everypar = std::string()); + std::string const & everypar = std::string(), + bool const & maintext = false); /// Switch the encoding of \p os from runparams.encoding to \p newEnc if needed. /// \return (did the encoding change?, number of characters written to \p os) Index: src/output_latex.cpp =================================================================== --- src/output_latex.cpp (Revision 22586) +++ src/output_latex.cpp (Arbeitskopie) @@ -67,7 +67,8 @@ ParagraphList::const_iterator pit, odocstream & os, TexRow & texrow, OutputParams const & runparams, - string const & everypar = string()); + string const & everypar = string(), + bool const & maintext = false); ParagraphList::const_iterator @@ -275,7 +276,8 @@ ParagraphList::const_iterator pit, odocstream & os, TexRow & texrow, OutputParams const & runparams_in, - string const & everypar) + string const & everypar, + bool const & maintext) { LYXERR(Debug::LATEX) << "TeXOnePar... " << &*pit << " '" << everypar << "'" << endl; @@ -293,31 +295,12 @@ runparams.moving_arg |= style->needprotect; // we are at the beginning of an inset and CJK is already open. - if (pit == paragraphs.begin() && runparams.local_font != 0 && + if (pit == paragraphs.begin() && !maintext && open_encoding_ == CJK) { cjk_inherited_ = true; open_encoding_ = none; } - if (pit == paragraphs.begin() && runparams.local_font == 0) { - // Open a CJK environment at the beginning of the main buffer - // if the document's language is a CJK language - if (bparams.encoding().package() == Encoding::CJK) { - os << "\\begin{CJK}{" << from_ascii(bparams.encoding().latexName()) - << "}{}%\n"; - texrow.newline(); - open_encoding_ = CJK; - } - if (!lyxrc.language_auto_begin && !bparams.language->babel().empty()) { - // FIXME UNICODE - os << from_utf8(subst(lyxrc.language_command_begin, - "$$lang", - bparams.language->babel())) - << '\n'; - texrow.newline(); - } - } - // This paragraph's language Language const * const par_language = pit->getParLanguage(bparams); // The document's language @@ -672,7 +655,7 @@ switch (open_encoding_) { case CJK: { // end of main text - if (runparams.local_font == 0) { + if (maintext) { os << '\n'; texrow.newline(); os << "\\end{CJK}\n"; @@ -693,16 +676,6 @@ // do nothing break; } - // auto_end tag only if the last par is in a babel language - if (runparams.local_font == 0 && !lyxrc.language_auto_end && - !bparams.language->babel().empty() && - font.language()->encoding()->package() != Encoding::CJK) { - os << from_utf8(subst(lyxrc.language_command_end, - "$$lang", - bparams.language->babel())) - << '\n'; - texrow.newline(); - } } // If this is the last paragraph, and a local_font was set upon entering @@ -746,11 +719,13 @@ odocstream & os, TexRow & texrow, OutputParams const & runparams, - string const & everypar) + string const & everypar, + bool const & maintext) { bool was_title = false; bool already_title = false; - TextClass const & tclass = buf.params().getTextClass(); + BufferParams const & bparams = buf.params(); + TextClass const & tclass = bparams.getTextClass(); ParagraphList::const_iterator par = paragraphs.begin(); ParagraphList::const_iterator endpar = paragraphs.end(); @@ -765,9 +740,30 @@ const_cast<OutputParams&>(runparams).par_end = 0; } + // Open a CJK environment at the beginning of the main buffer + // if the document's language is a CJK language + if (maintext && bparams.encoding().package() == Encoding::CJK) { + os << "\\begin{CJK}{" << from_ascii(bparams.encoding().latexName()) + << "}{}%\n"; + texrow.newline(); + open_encoding_ = CJK; + } + // if "auto begin" is switched off, explicitely switch the + // language on at start + if (maintext && !lyxrc.language_auto_begin && + !bparams.language->babel().empty()) { + // FIXME UNICODE + os << from_utf8(subst(lyxrc.language_command_begin, + "$$lang", + bparams.language->babel())) + << '\n'; + texrow.newline(); + } + + ParagraphList::const_iterator lastpar; // if only_body while (par != endpar) { - ParagraphList::const_iterator lastpar = par; + lastpar = par; // 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 @@ -806,18 +802,18 @@ if (layout->is_environment) { par = TeXOnePar(buf, paragraphs, par, os, texrow, - runparams, everypar); + runparams, everypar, maintext); } else if (layout->isEnvironment() || !par->params().leftIndent().zero()) { par = TeXEnvironment(buf, paragraphs, par, os, texrow, runparams); } else { par = TeXOnePar(buf, paragraphs, par, os, texrow, - runparams, everypar); + runparams, everypar, maintext); } } else { par = TeXOnePar(buf, paragraphs, par, os, texrow, - runparams, everypar); + runparams, everypar, maintext); } if (std::distance(lastpar, par) >= std::distance(lastpar, endpar)) break; @@ -834,9 +830,19 @@ } texrow.newline(); } + // if "auto end" is switched off, explicitely close the language at the end + // but only if the last par is in a babel language + if (maintext && !lyxrc.language_auto_end && !bparams.language->babel().empty() && + lastpar->getParLanguage(bparams)->encoding()->package() != Encoding::CJK) { + os << from_utf8(subst(lyxrc.language_command_end, + "$$lang", + bparams.language->babel())) + << '\n'; + texrow.newline(); + } // If the last paragraph is an environment, we'll have to close // CJK at the very end to do proper nesting. - if (open_encoding_ == CJK) { + if (maintext && open_encoding_ == CJK) { os << "\\end{CJK}\n"; texrow.newline(); open_encoding_ = none; Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (Revision 22586) +++ src/Buffer.cpp (Arbeitskopie) @@ -1073,7 +1073,7 @@ } // the real stuff - latexParagraphs(*this, paragraphs(), os, texrow(), runparams); + latexParagraphs(*this, paragraphs(), os, texrow(), runparams, string(), true); // Restore the parenthood if needed if (output_preamble) @@ -1826,7 +1826,7 @@ // output paragraphs if (isLatex()) { texrow().reset(); - latexParagraphs(*this, paragraphs(), os, texrow(), runparams); + latexParagraphs(*this, paragraphs(), os, texrow(), runparams, string(), true); } else { // DocBook docbookParagraphs(paragraphs(), *this, os, runparams);