commit 2e04158e29c63dc07c1aa97192b621f3688cd4d7
Author: Udi Fogiel <[email protected]>
Date:   Tue Jul 14 21:49:16 2026 +0300

    Fix RTL numeral-run wrapper nesting around font/language switches
    
    The {\beginL ... \endL} wrapper was opened/closed in the wrong spot
    relative to font/language switching, so its closing brace could land
    inside a still-open group instead of closing its own. Move the close
    to fire right after the old font/language closes and before the new
    one opens.
---
 src/Paragraph.cpp | 61 +++++++++++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 26 deletions(-)

diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index 0a39810eb3..63f6cbeecd 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -3012,6 +3012,25 @@ void Paragraph::latex(BufferParams const & bparams,
                        open_font &= !langClosed;
                }
 
+               // Do we need to close the RTL numeral-run wrapper? This must
+               // happen after the previous font is closed above (so e.g. a
+               // still-open \textbf{ closes first) but before the next font/
+               // language is opened below (so \endL} closes this run before
+               // a language switch's own \L{/\R{} opens).
+               // Insets (c == META_INSET) are never part of a numeral run.
+               bool const numeral_here = c != META_INSET
+                       && i >= start_pos && (end_pos == -1 || i < end_pos)
+                       && !runparams.pass_thru
+                       && !bparams.useBidiPackage(runparams)
+                       && isRTLNumberRun(i)
+                       && (current_font.language()->lang() == "hebrew"
+                           || current_font.language()->lang() == "farsi"
+                           || current_font.language()->lang() == 
"arabic_arabi");
+               if (in_numeral_run && !numeral_here) {
+                       closeNumeralRun();
+                       in_numeral_run = false;
+               }
+
                // if necessary, close language environment before opening CJK
                string const running_lang = running_font.language()->babel();
                string const lang_end_command = lyxrc.language_command_end;
@@ -3121,26 +3140,12 @@ void Paragraph::latex(BufferParams const & bparams,
                        }
                }
 
-               // Do we need to open or close the RTL numeral-run wrapper? This
-               // must happen after the general font/language open-close above
-               // but before anything writes the character itself,
-               // including simpleTeXBlanks() below for spaces, so that the
-               // wrap correctly brackets just the run's own text.
-               // Insets (c == META_INSET) are never part of a numeral run.
-               bool const numeral_here = c != META_INSET
-                       && i >= start_pos && (end_pos == -1 || i < end_pos)
-                       && !runparams.pass_thru
-                       && !bparams.useBidiPackage(runparams)
-                       && isRTLNumberRun(i)
-                       && (current_font.language()->lang() == "hebrew"
-                           || current_font.language()->lang() == "farsi"
-                           || current_font.language()->lang() == 
"arabic_arabi");
-               if (numeral_here != in_numeral_run) {
-                       if (numeral_here)
-                               openNumeralRun();
-                       else
-                               closeNumeralRun();
-                       in_numeral_run = numeral_here;
+               // Open the RTL numeral-run wrapper now, after any font/language
+               // switch above has already written its own output, but still
+               // before the character itself is written below.
+               if (numeral_here && !in_numeral_run) {
+                       openNumeralRun();
+                       in_numeral_run = true;
                }
 
                // FIXME: think about end_pos implementation...
@@ -3297,12 +3302,6 @@ void Paragraph::latex(BufferParams const & bparams,
                runparams.post_macro = rp.post_macro;
        }
 
-       // Close a numeral-run wrapper left open at the end of the paragraph
-       if (in_numeral_run) {
-               closeNumeralRun();
-               in_numeral_run = false;
-       }
-
        // Close wrapper for alien script
        if (!alien_script.empty()) {
                os << "}";
@@ -3363,6 +3362,15 @@ void Paragraph::latex(BufferParams const & bparams,
                                basefont, basefont, needPar);
 #endif
        }
+
+       // Close a numeral-run wrapper left open at the end of the
+       // paragraph, after the font above (so a still-open \textbf{
+       // closes first).
+       if (in_numeral_run) {
+               closeNumeralRun();
+               in_numeral_run = false;
+       }
+
        if (needPar) {
                // The \par could not be inserted at the same nesting
                // level of the font size change, so do it now.
@@ -4489,6 +4497,7 @@ bool isNumberRunOperator(char_type c)
 } // namespace
 
 
+// FIXME: this doesn't stop a run at a font/language switch.
 bool Paragraph::isRTLNumberRun(pos_type pos) const
 {
        pos_type const psize = size();
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to