Dov Feldstern wrote:
Enrico Forestieri wrote:
On Fri, Jul 13, 2007 at 02:48:49AM +0300, Dov Feldstern wrote:

I realized that with the partial solution, which fixed some cases, other cases which used to work stopped working. So the only way to go is to provide a complete solution for all cases (well, maybe not *all*...). That's what the attached patch does.

Hi Dov,

I tested your new patch and think that it somehow improves things wrt
the previous one, but there are still problems. I am attaching three
sample files demonstrating them.

Yeah, I've been working only with LTR, so I see there are some adaptations I need to make for non-LTR languages. Perhaps the current state (before my patch) is working correctly for non-RTL languages? If not, where do you see problems?

Basically, I'll try as much as possible to isolate my changes only to RTL language switches, so let me know if there are any parts of it which *do* need to be applied to non-RTL, as well.

Dov


Hi!

I have to stop working now, I'm going to be offline until tomorrow night.

Attached find the latest additions to the patch. Enrico, I think these will solve the samples you sent me, and it seems to still work for the RTL stuff. But I haven't had time to clean up the patch yet, nor have I tested it enough.

I would still like this to go into 1.5.0 if possible, but it'll take at least a few more days... I'll understand (but be upset :( ) if you can't wait...

Dov
Index: src/Font.cpp
===================================================================
--- src/Font.cpp        (revision 19065)
+++ src/Font.cpp        (working copy)
@@ -875,7 +875,8 @@
 int Font::latexWriteEndChanges(odocstream & os, BufferParams const & bparams,
                                  OutputParams const & runparams,
                                  Font const & base,
-                                 Font const & next) const
+                                 Font const & next,
+                                 bool const & closeLanguage) const
 {
        int count = 0;
        bool env = false;
@@ -953,7 +954,8 @@
                open_encoding_ = false;
        }
 
-       if (language() != base.language() && language() != next.language()) {
+       if (closeLanguage &&
+                       language() != base.language() && language() != 
next.language()) {
                os << '}';
                ++count;
        }
Index: src/TextMetrics.cpp
===================================================================
--- src/TextMetrics.cpp (revision 19065)
+++ src/TextMetrics.cpp (working copy)
@@ -361,6 +361,7 @@
                            && !disp_inset
                                ) {
                                result.separator = w / ns;
+                               lyxerr << "sepwidth: " << result.separator << 
endl;
                        } else if (is_rtl) {
                                result.x += w;
                        }
Index: src/Font.h
===================================================================
--- src/Font.h  (revision 19065)
+++ src/Font.h  (working copy)
@@ -309,7 +309,8 @@
        int latexWriteEndChanges(odocstream &, BufferParams const & bparams,
                                 OutputParams const & runparams,
                                 Font const & base,
-                                Font const & next) const;
+                                Font const & next,
+                                bool const & closeLanguage = true) const;
 
 
        /// Build GUI description of font state
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp   (revision 19065)
+++ src/Paragraph.cpp   (working copy)
@@ -191,7 +191,7 @@
        ///
        void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
                                   odocstream &,
-                                  TexRow & texrow, OutputParams const &,
+                                  TexRow & texrow, OutputParams &,
                                   Font & running_font,
                                   Font & basefont,
                                   Font const & outerfont,
@@ -662,7 +662,7 @@
                                             BufferParams const & bparams,
                                             odocstream & os,
                                             TexRow & texrow,
-                                            OutputParams const & runparams,
+                                            OutputParams & runparams,
                                             Font & running_font,
                                             Font & basefont,
                                             Font const & outerfont,
@@ -752,14 +752,32 @@
 // right now, which means stupid latex code like \textsf{}. AFAIK,
 // this does not harm dvi output. A minor bug, thus (JMarc)
 #endif
-               // some insets cannot be inside a font change command
+               // some insets cannot be inside a font change command.
+               // however, even such insets *can* be placed in \L or \R
+               // or their equivalents (for RTL language switches)
                if (open_font && inset->noFontChange()) {
-                       column += running_font.latexWriteEndChanges(
+                       bool closeLanguage = 
+                               (basefont.isRightToLeft() == 
running_font.isRightToLeft());
+                       // setting the last parameter to false means the 
language
+                       // will *not* be closed, even when the rest of the font
+                       // properties are.
+                       unsigned int count = running_font.latexWriteEndChanges(
                                        os, bparams, runparams,
-                                               basefont, basefont);
-                       open_font = false;
-                       basefont = owner_->getLayoutFont(bparams, outerfont);
-                       running_font = basefont;
+                                               basefont, basefont, 
closeLanguage);
+                       column += count;
+                       // if any font properties were closed, update the 
running_font, 
+                       // making sure, however, to leave the language as it was
+                       if (count > 0) {
+                               Font const copy_font(running_font);
+                               basefont = owner_->getLayoutFont(bparams, 
outerfont);
+                               running_font = basefont;
+                               if (!closeLanguage)
+                                       
running_font.setLanguage(copy_font.language());
+                               // leave font open if language is still open
+                               open_font = (running_font.language() == 
basefont.language());
+                               if (closeLanguage)
+                                       runparams.local_font = &basefont;
+                       }
                }
 
                int tmp = inset->latex(buf, os, runparams);
Index: src/output_latex.cpp
===================================================================
--- src/output_latex.cpp        (revision 19065)
+++ src/output_latex.cpp        (working copy)
@@ -248,6 +248,7 @@
                << everypar << "'" << endl;
        BufferParams const & bparams = buf.params();
        Layout_ptr style;
+       bool close_rtl_lang_at_end = false;
 
        // In an inset with unlimited length (all in one row),
        // force layout to default
@@ -259,14 +260,19 @@
        OutputParams runparams = runparams_in;
        runparams.moving_arg |= style->needprotect;
 
+       // The previous language is the language of the previous paragraph, 
+       // if it exists; if this is the first paragraph, the previous 
+       // language is the local language upon entering the inset, if it
+       // is set; otherwise, it's the document's language.
        Language const * const par_language = pit->getParLanguage(bparams);
        Language const * const doc_language = bparams.language;
-       Language const * const prev_par_language =
-               (pit != paragraphs.begin())
-               ? boost::prior(pit)->getParLanguage(bparams)
-               : doc_language;
+       Language const * const prev_language =
+               (pit != paragraphs.begin()) ?
+                       boost::prior(pit)->getParLanguage(bparams) :
+                               (runparams.local_font != 0) ?
+                                       runparams.local_font->language() : 
doc_language;
 
-       if (par_language->babel() != prev_par_language->babel()
+       if (par_language->babel() != prev_language->babel()
            // check if we already put language command in TeXEnvironment()
            && !(style->isEnvironment()
                 && (pit == paragraphs.begin() ||
@@ -275,19 +281,35 @@
                     || boost::prior(pit)->getDepth() < pit->getDepth())))
        {
                if (!lyxrc.language_command_end.empty() &&
-                   prev_par_language->babel() != doc_language->babel() &&
-                   !prev_par_language->babel().empty())
+                   prev_language->babel() != prev_language->babel() &&
+                   !prev_language->babel().empty())
                {
+                       //XXX ???
+                       if (lyxrc.rtl_support && runparams.local_font != 0)
+                               os << "}";
                        os << from_ascii(subst(lyxrc.language_command_end,
                                "$$lang",
-                               prev_par_language->babel()))
+                               prev_language->babel()))
                           << '\n';
                        texrow.newline();
                }
 
                if ((lyxrc.language_command_end.empty() ||
-                    par_language->babel() != doc_language->babel()) &&
+                    par_language->babel() != prev_language->babel()) &&
                    !par_language->babel().empty()) {
+                       // If the new paragraph is in a different direction 
than the
+                       // local_font direction, we need an appropriate \L or \R
+                       if (lyxrc.rtl_support && runparams.local_font != 0 &&
+                                       runparams.local_font->isRightToLeft() 
!= 
+                                               par_language->rightToLeft()) {
+                               // FIXME: instead of \\R, \\L, use correct 
form, depending 
+                               // on the language (arabic, farsi, etc.)
+                               if (par_language->rightToLeft())
+                                       os << "\\R{";
+                               else
+                                       os << "\\L{";
+                               close_rtl_lang_at_end = true;
+                       }
                        os << from_ascii(subst(
                                lyxrc.language_command_begin,
                                "$$lang",
@@ -457,8 +479,8 @@
                }
        }
 
-       if (boost::next(pit) == paragraphs.end()
-           && par_language->babel() != doc_language->babel()) {
+       if (close_rtl_lang_at_end || (boost::next(pit) == paragraphs.end()
+           && par_language->babel() != prev_language->babel())) {
                // Since \selectlanguage write the language to the aux file,
                // we need to reset the language at the end of footnote or
                // float.
@@ -468,11 +490,11 @@
                        texrow.newline();
                }
                if (lyxrc.language_command_end.empty()) {
-                       if (!doc_language->babel().empty()) {
+                       if (!prev_language->babel().empty()) {
                                os << from_ascii(subst(
                                        lyxrc.language_command_begin,
                                        "$$lang",
-                                       doc_language->babel()));
+                                       prev_language->babel()));
                                pending_newline = true;
                        }
                } else if (!par_language->babel().empty()) {
@@ -483,13 +505,28 @@
                        pending_newline = true;
                }
        }
+       if (close_rtl_lang_at_end)
+               os << "}";
 
        if (pending_newline) {
                os << '\n';
                texrow.newline();
        }
-       runparams_in.encoding = runparams.encoding;
 
+       // 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
+       // switch command is needed, since latex will automatically revert to it
+       // when this inset closes.
+       if (boost::next(pit) == paragraphs.end() && runparams_in.local_font != 
0) {
+               runparams_in.encoding = 
runparams_in.local_font->language()->encoding();
+               os << setEncoding(runparams_in.encoding->iconvName());
+       }
+       // Otherwise, the current encoding should be set for the next paragraph.
+       else
+               runparams_in.encoding = runparams.encoding;
+
+
        // we don't need it for the last paragraph!!!
        // Note from JMarc: we will re-add a \n explicitely in
        // TeXEnvironment, because it is needed in this case
Index: lyx-devel/src/output_latex.cpp
===================================================================
--- lyx-devel.orig/src/output_latex.cpp 2007-07-13 18:15:02.000000000 +0300
+++ lyx-devel/src/output_latex.cpp      2007-07-13 18:57:26.000000000 +0300
@@ -284,6 +284,7 @@
                    prev_language->babel() != prev_language->babel() &&
                    !prev_language->babel().empty())
                {
+                       //XXX ???
                        if (lyxrc.rtl_support && runparams.local_font != 0)
                                os << "}";
                        os << from_ascii(subst(lyxrc.language_command_end,
@@ -296,10 +297,11 @@
                if ((lyxrc.language_command_end.empty() ||
                     par_language->babel() != prev_language->babel()) &&
                    !par_language->babel().empty()) {
-                       // FIXME: this is probably only necessary in cases 
where we 
-                       // are actually switching the direction (i.e., 
local_font is
-                       // RTL and new paragraph is LTR, not sure... 
-                       if (lyxrc.rtl_support && runparams.local_font != 0) {
+                       // If the new paragraph is in a different direction 
than the
+                       // local_font direction, we need an appropriate \L or \R
+                       if (lyxrc.rtl_support && runparams.local_font != 0 &&
+                                       runparams.local_font->isRightToLeft() 
!= 
+                                               par_language->rightToLeft()) {
                                // FIXME: instead of \\R, \\L, use correct 
form, depending 
                                // on the language (arabic, farsi, etc.)
                                if (par_language->rightToLeft())
Index: lyx-devel/src/Paragraph.cpp
===================================================================
--- lyx-devel.orig/src/Paragraph.cpp    2007-07-13 18:15:02.000000000 +0300
+++ lyx-devel/src/Paragraph.cpp 2007-07-13 19:01:52.000000000 +0300
@@ -191,7 +191,7 @@
        ///
        void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
                                   odocstream &,
-                                  TexRow & texrow, OutputParams const &,
+                                  TexRow & texrow, OutputParams &,
                                   Font & running_font,
                                   Font & basefont,
                                   Font const & outerfont,
@@ -662,7 +662,7 @@
                                             BufferParams const & bparams,
                                             odocstream & os,
                                             TexRow & texrow,
-                                            OutputParams const & runparams,
+                                            OutputParams & runparams,
                                             Font & running_font,
                                             Font & basefont,
                                             Font const & outerfont,
@@ -753,14 +753,17 @@
 // this does not harm dvi output. A minor bug, thus (JMarc)
 #endif
                // some insets cannot be inside a font change command.
-               // however, even such insets *can* be placed in a language 
change.
+               // however, even such insets *can* be placed in \L or \R
+               // or their equivalents (for RTL language switches)
                if (open_font && inset->noFontChange()) {
+                       bool closeLanguage = 
+                               (basefont.isRightToLeft() == 
running_font.isRightToLeft());
                        // setting the last parameter to false means the 
language
                        // will *not* be closed, even when the rest of the font
                        // properties are.
                        unsigned int count = running_font.latexWriteEndChanges(
                                        os, bparams, runparams,
-                                               basefont, basefont, false);
+                                               basefont, basefont, 
closeLanguage);
                        column += count;
                        // if any font properties were closed, update the 
running_font, 
                        // making sure, however, to leave the language as it was
@@ -768,9 +771,12 @@
                                Font const copy_font(running_font);
                                basefont = owner_->getLayoutFont(bparams, 
outerfont);
                                running_font = basefont;
-                               running_font.setLanguage(copy_font.language());
+                               if (!closeLanguage)
+                                       
running_font.setLanguage(copy_font.language());
                                // leave font open if language is still open
                                open_font = (running_font.language() == 
basefont.language());
+                               if (closeLanguage)
+                                       runparams.local_font = &basefont;
                        }
                }
 

Reply via email to