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);

Reply via email to