Jürgen Spitzmüller wrote:

Opinions?

Jürgen


Jurgen --- I wanted to take a look at this, but something really weird is going on: I'm trying to apply your patch to r21683 (which is what it's supposedly against), but it's not applying cleanly. And the line numbers in the patch are off:

in Paragraph.cpp, for example, second hunk, off by 200 lines:

@@ -2163,11 +2164,21 @@
            open_font = false;
        }

matches this:
http://www.lyx.org/trac/browser/lyx-devel/trunk/src/Paragraph.cpp?rev=21683#L1964

What's going on here?

Dov


------------------------------------------------------------------------

Index: src/output_latex.h
===================================================================
--- src/output_latex.h  (Revision 21683)
+++ src/output_latex.h  (Arbeitskopie)
@@ -48,7 +48,7 @@
 /// \return (did the encoding change?, number of characters written to \p os)
std::pair<bool, int> switchEncoding(odocstream & os, BufferParams const & bparams,
-                    bool moving_arg, Encoding const & oldEnc,
+                    OutputParams const &, Encoding const & oldEnc,
                     Encoding const & newEnc);
} // namespace lyx
Index: src/Font.cpp
===================================================================
--- src/Font.cpp        (Revision 21683)
+++ src/Font.cpp        (Arbeitskopie)
@@ -787,7 +787,7 @@
if (language()->encoding()->package() == Encoding::CJK) {
                pair<bool, int> const c = switchEncoding(os, bparams,
-                               runparams.moving_arg, *(runparams.encoding),
+                               runparams, *(runparams.encoding),
                                *(language()->encoding()));
                if (c.first) {
                        open_encoding_ = true;
@@ -948,7 +948,7 @@
                // to do correct environment nesting
                Encoding const * const ascii = 
encodings.getFromLyXName("ascii");
                pair<bool, int> const c = switchEncoding(os, bparams,
-                               runparams.moving_arg, *(runparams.encoding),
+                               runparams, *(runparams.encoding),
                                *ascii);
                BOOST_ASSERT(c.first);
                count += c.second;
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp   (Revision 21683)
+++ src/Paragraph.cpp   (Arbeitskopie)
@@ -68,6 +68,7 @@
using support::contains;
 using support::prefixIs;
+using support::subst;
 using support::suffixIs;
 using support::rsplit;
@@ -2163,11 +2164,21 @@
                        open_font = false;
                }
+ // close babel's font environment before opening CJK.
+               if (!running_font.language()->babel().empty() &&
+                   font.language()->encoding()->package() == Encoding::CJK) {
+                               string end_tag = 
subst(lyxrc.language_command_end,
+                                                       "$$lang",
+                                                       
running_font.language()->babel());
+                               os << from_ascii(end_tag);
+                               column += end_tag.length();
+               }
+
                // Switch file encoding if necessary
-               if (runparams.encoding->package() == Encoding::inputenc &&
-                   font.language()->encoding()->package() == 
Encoding::inputenc) {
+               if (runparams.encoding->package() != Encoding::none &&
+                   font.language()->encoding()->package() != Encoding::none) {
                        std::pair<bool, int> const enc_switch = 
switchEncoding(os, bparams,
-                                       runparams.moving_arg, 
*(runparams.encoding),
+                                       runparams, *(runparams.encoding),
                                        *(font.language()->encoding()));
                        if (enc_switch.first) {
                                column += enc_switch.second;
Index: src/output_latex.cpp
===================================================================
--- src/output_latex.cpp        (Revision 21683)
+++ src/output_latex.cpp        (Arbeitskopie)
@@ -43,6 +43,16 @@
namespace { +
+enum OpenEncoding {
+               none,
+               inputenc,
+               CJK
+       };
+
+static int open_encoding_ = none;
+
+
 ParagraphList::const_iterator
 TeXEnvironment(Buffer const & buf,
               ParagraphList const & paragraphs,
@@ -113,7 +123,8 @@
                                lyxrc.language_command_end,
                                "$$lang",
                                prev_par_language->babel()))
-                          << '\n';
+                          // the '%' is necessary to prevent unwanted 
whitespace
+                          << '%' << '\n';
                        texrow.newline();
                }
@@ -124,7 +135,8 @@
                                lyxrc.language_command_begin,
                                "$$lang",
                                par_language->babel()))
-                          << '\n';
+                          // the '%' is necessary to prevent unwanted 
whitespace
+                          << '%' << '\n';
                        texrow.newline();
                }
        }
@@ -259,11 +271,38 @@
        OutputParams runparams = runparams_in;
        runparams.moving_arg |= style->needprotect;
+ bool open_cjk_in_parent = false;
+       // we are at the beginning of an inset and CJK is already open.
+ if (pit == paragraphs.begin() && runparams.local_font != 0 && + open_encoding_ == CJK) {
+               open_encoding_ = none;
+               open_cjk_in_parent = true;
+       }
+
+       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
        Language const * const doc_language = bparams.language;
- // The language that was in effect when the environemnt this paragraph is + // The language that was in effect when the environment this paragraph is // inside of was opened Language const * const outer_language = (runparams.local_font != 0) ?
@@ -290,7 +329,8 @@
                        os << from_ascii(subst(lyxrc.language_command_end,
                                "$$lang",
                                prev_language->babel()))
-                          << '\n';
+                          // the '%' is necessary to prevent unwanted 
whitespace
+                          << '%' << '\n';
                        texrow.newline();
                }
@@ -339,12 +379,16 @@
                                else
                                        os << "\\L{";
                        }
-                       os << from_ascii(subst(
-                               lyxrc.language_command_begin,
-                               "$$lang",
-                               par_language->babel()))
-                          << '\n';
-                       texrow.newline();
+                       // With CJK, the CJK tag has to be closed first (see 
below)
+                       if (runparams.encoding->package() != Encoding::CJK) {
+                               os << from_ascii(subst(
+                                       lyxrc.language_command_begin,
+                                       "$$lang",
+                                       par_language->babel()))
+                                  // the '%' is necessary to prevent unwanted 
whitespace
+                                  << '%' << '\n';
+                               texrow.newline();
+                       }
                }
        }
@@ -352,14 +396,14 @@
        // encoding, since this only affects the position of the outputted
        // \inputencoding command; the encoding switch will occur when necessary
        if (bparams.inputenc == "auto" &&
-           runparams.encoding->package() == Encoding::inputenc) {
+           runparams.encoding->package() != Encoding::none) {
                // Look ahead for future encoding changes.
                // We try to output them at the beginning of the paragraph,
                // since the \inputencoding command is not allowed e.g. in
                // sections.
                for (pos_type i = 0; i < pit->size(); ++i) {
                        char_type const c = pit->getChar(i);
-                       if (c < 0x80)
+                       if (runparams.encoding->package() == Encoding::inputenc && 
c < 0x80)
                                continue;
                        if (pit->isInset(i))
                                break;
@@ -368,16 +412,32 @@
                        // encoding to that required by the language of c.
                        Encoding const * const encoding =
                                pit->getFontSettings(bparams, 
i).language()->encoding();
-                       pair<bool, int> enc_switch = switchEncoding(os, 
bparams, false,
+
+                       // with CJK, only add switch if we have CJK content at 
the beginning
+                       // of the paragraph
+                       if (encoding->package() != Encoding::CJK || i == 0) {
+                               pair<bool, int> enc_switch = switchEncoding(os, 
bparams, runparams,
                                        *(runparams.encoding), *encoding);
-                       if (encoding->package() == Encoding::inputenc && 
enc_switch.first) {
-                               runparams.encoding = encoding;
-                               if (enc_switch.second > 0) {
-                                       os << '\n';
-                                       texrow.newline();
+                               if (encoding->package() != Encoding::none && 
enc_switch.first) {
+                                       if (enc_switch.second > 0) {
+                                               // the '%' is necessary to 
prevent unwanted whitespace
+                                               os << '%' << '\n';
+                                               texrow.newline();
+                                       }
+                                       // With CJK, the CJK tag had to be 
closed first (see above)
+                                       if (runparams.encoding->package() == 
Encoding::CJK) {
+                                               os << from_ascii(subst(
+                                                       
lyxrc.language_command_begin,
+                                                       "$$lang",
+                                                       par_language->babel()))
+                                               // the '%' is necessary tp 
prevent unwanted whitespace
+                                               << '%' << '\n';
+                                               texrow.newline();
+                                       }
+                                       runparams.encoding = encoding;
                                }
+                               break;
                        }
-                       break;
                }
        }
@@ -535,20 +595,23 @@
                        os << '\n';
                        texrow.newline();
                }
-               if (lyxrc.language_command_end.empty()) {
-                       if (!prev_language->babel().empty()) {
+               // when the paragraph uses CJK, the language has to be closed 
earlier
+               if (font.language()->encoding()->package() != Encoding::CJK) {
+                       if (lyxrc.language_command_end.empty()) {
+                               if (!prev_language->babel().empty()) {
+                                       os << from_ascii(subst(
+                                               lyxrc.language_command_begin,
+                                               "$$lang",
+                                               prev_language->babel()));
+                                       pending_newline = true;
+                               }
+                       } else if (!par_language->babel().empty()) {
                                os << from_ascii(subst(
-                                       lyxrc.language_command_begin,
+                                       lyxrc.language_command_end,
                                        "$$lang",
-                                       prev_language->babel()));
+                                       par_language->babel()));
                                pending_newline = true;
                        }
-               } else if (!par_language->babel().empty()) {
-                       os << from_ascii(subst(
-                               lyxrc.language_command_end,
-                               "$$lang",
-                               par_language->babel()));
-                       pending_newline = true;
                }
        }
        if (closing_rtl_ltr_environment)
@@ -559,6 +622,47 @@
                texrow.newline();
        }
+ // if this is a CJK-paragraph and the next isn't, close CJK
+       if (boost::next(pit) != paragraphs.end() && open_encoding_ == CJK &&
+           boost::next(pit)->getParLanguage(bparams)->encoding()->package() != 
Encoding::CJK) {
+               os << "\\end{CJK}\n";
+               open_encoding_ = none;
+       }
+
+       // If this is the last paragraph, close the CJK environment
+       // if necessary
+       if (boost::next(pit) == paragraphs.end()) {
+               if (open_encoding_ == CJK) {
+                       // end of main text
+                       if (runparams.local_font == 0) {
+                               os << '\n';
+                               texrow.newline();
+                               os << "\\end{CJK}\n";
+                               texrow.newline();
+                       // end of an inset
+                       } else
+                               os << "\\end{CJK}";
+                       open_encoding_ = none;
+               }
+               if (open_encoding_ == inputenc) {
+                       os << "\\egroup";
+                       open_encoding_ = none;
+               }
+               // end of inset, reset cjk_open to parent
+               if (open_cjk_in_parent)
+                       open_encoding_ = CJK;
+               // 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
// the inset, the encoding should be set back to that local_font's // encoding. We don't use switchEncoding(), because no explicit encoding
@@ -692,9 +796,10 @@
pair<bool, int> switchEncoding(odocstream & os, BufferParams const & bparams,
-                  bool moving_arg, Encoding const & oldEnc,
+                  OutputParams const & runparams, Encoding const & oldEnc,
                   Encoding const & newEnc)
 {
+       bool moving_arg = runparams.moving_arg;
        if ((bparams.inputenc != "auto" && bparams.inputenc != "default")
                || moving_arg)
                return make_pair(false, 0);
@@ -719,27 +824,51 @@
        if (bparams.inputenc == "default")
                return make_pair(true, 0);
- docstring const inputenc(from_ascii(newEnc.latexName()));
+       docstring const inputenc_arg(from_ascii(newEnc.latexName()));
        switch (newEnc.package()) {
                case Encoding::none:
                        // shouldn't ever reach here, see above
                        return make_pair(true, 0);
                case Encoding::inputenc: {
-                       int count = inputenc.length();
-                       if (oldEnc.package() == Encoding::CJK) {
+                       int count = inputenc_arg.length();
+                       if (oldEnc.package() == Encoding::CJK &&
+                           open_encoding_ == CJK) {
                                os << "\\end{CJK}";
+                               open_encoding_ = none;
                                count += 9;
                        }
-                       os << "\\inputencoding{" << inputenc << '}';
+                       else if (oldEnc.package() == Encoding::inputenc &&
+                                open_encoding_ == inputenc) {
+                               os << "\\egroup";
+                               open_encoding_ = none;
+                               count += 7;
+                       }
+                       if (runparams.local_font != 0 && oldEnc.package() == 
Encoding::CJK) {
+ // within insets, \inputenc switches need to be + // embraced within \bgroup ... \egroup; else CJK fails.
+                               os << "\\bgroup";
+                               count += 7;
+                               open_encoding_ = inputenc;
+                       }
+                       os << "\\inputencoding{" << inputenc_arg << '}';
                        return make_pair(true, count + 16);
                 }
                case Encoding::CJK: {
-                       int count = inputenc.length();
-                       if (oldEnc.package() == Encoding::CJK) {
+                       int count = inputenc_arg.length();
+ if (oldEnc.package() == Encoding::CJK && + open_encoding_ == CJK) {
                                os << "\\end{CJK}";
+                               open_encoding_ = none;
                                count += 9;
                        }
-                       os << "\\begin{CJK}{" << inputenc << "}{}";
+ if (oldEnc.package() == Encoding::inputenc && + open_encoding_ == inputenc) {
+                               os << "\\egroup";
+                               open_encoding_ = inputenc;
+                               count += 7;
+                       }
+                       os << "\\begin{CJK}{" << inputenc_arg << "}{}";
+                       open_encoding_ = CJK;
                        return make_pair(true, count + 15);
                }
        }
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp      (Revision 21683)
+++ src/Buffer.cpp      (Arbeitskopie)
@@ -1044,26 +1044,6 @@
        } // output_preamble
        LYXERR(Debug::INFO) << "preamble finished, now the body." << endl;
- if (!lyxrc.language_auto_begin &&
-           !params().language->babel().empty()) {
-               // FIXME UNICODE
-               os << from_utf8(subst(lyxrc.language_command_begin,
-                                          "$$lang",
-                                          params().language->babel()))
-                  << '\n';
-               texrow().newline();
-       }
-
-       Encoding const & encoding = params().encoding();
-       if (encoding.package() == Encoding::CJK) {
-               // Open a CJK environment, since in contrast to the encodings
-               // handled by inputenc the document encoding is not set in
-               // the preamble if it is handled by CJK.sty.
-               os << "\\begin{CJK}{" << from_ascii(encoding.latexName())
-                  << "}{}\n";
-               texrow().newline();
-       }
-
        // if we are doing a real file with body, even if this is the
        // child of some other buffer, let's cut the link here.
        // This happens for example if only a child document is printed.
@@ -1084,23 +1064,6 @@
        os << endl;
        texrow().newline();
- if (encoding.package() == Encoding::CJK) {
-               // Close the open CJK environment.
-               // latexParagraphs will have opened one even if the last text
-               // was not CJK.
-               os << "\\end{CJK}\n";
-               texrow().newline();
-       }
-
-       if (!lyxrc.language_auto_end &&
-           !params().language->babel().empty()) {
-               os << from_utf8(subst(lyxrc.language_command_end,
-                                          "$$lang",
-                                          params().language->babel()))
-                  << '\n';
-               texrow().newline();
-       }
-
        if (output_preamble) {
                os << "\\end{document}\n";
                texrow().newline();

Reply via email to