]> git.lyx.org Git - lyx.git/blobdiff - src/Paragraph.cpp
Accelerators
[lyx.git] / src / Paragraph.cpp
index 3acdd93915382cc8916a889603d745cd5c6457c4..2465cc4101e88c425c616bd3152965fa69fa52e6 100644 (file)
@@ -1033,10 +1033,10 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
                close = true;
        }
 
-       if (open_font && (!inset->inheritFont() || inset->allowMultiPar())) {
+       if (open_font && fontswitch_inset) {
                bool lang_closed = false;
                // Close language if needed
-               if (closeLanguage) {
+               if (closeLanguage && !lang_switched_at_inset) {
                        // We need prev_font here as language changes directly at inset
                        // will only be started inside the inset.
                        Font const prev_font = (i > 0) ?
@@ -1060,6 +1060,8 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
                running_font = basefont;
                if (!closeLanguage)
                        running_font.setLanguage(copy_font.language());
+               OutputParams rp = runparams;
+               rp.encoding = basefont.language()->encoding();
                // For these, we use switches, so they should be taken as
                // base inside the inset.
                basefont.fontInfo().setSize(copy_font.fontInfo().size());
@@ -1073,9 +1075,10 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
                          && !textinset->text().isMainText()
                        : false;
                unsigned int count2 = basefont.latexWriteStartChanges(os, bparams,
-                                                     runparams, running_font,
+                                                     rp, running_font,
                                                      basefont, true,
                                                      cprotect);
+               open_font = true;
                column += count2;
                if (count2 == 0 && (lang_closed || lang_switched_at_inset))
                        // All fonts closed
@@ -1084,6 +1087,12 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
                        runparams.local_font = &basefont;
        }
 
+       if (fontswitch_inset && !closeLanguage && fontswitch_inset) {
+               // The directionality has been switched at inset.
+               // Force markup inside.
+               runparams.local_font = &basefont;
+       }
+
        size_t const previous_row_count = os.texrow().rows();
 
        try {
@@ -2570,7 +2579,7 @@ void Paragraph::latex(BufferParams const & bparams,
                ++column;
 
                // Fully instantiated font
-               Font const current_font = getFont(bparams, i, outerfont);
+               Font current_font = getFont(bparams, i, outerfont);
                // Previous font
                Font const prev_font = (i > 0) ?
                                        getFont(bparams, i - 1, outerfont)
@@ -2581,16 +2590,37 @@ void Paragraph::latex(BufferParams const & bparams,
                                             && runningChange == change
                                             && change.type == Change::DELETED
                                             && !os.afterParbreak());
-               bool const multipar_inset =
-                       (c == META_INSET && getInset(i) && getInset(i)->allowMultiPar());
+               // Insets where font switches are used (rather than font commands)
+               bool const fontswitch_inset =
+                               c == META_INSET
+                               && getInset(i)
+                               && getInset(i)->allowMultiPar()
+                               && getInset(i)->lyxCode() != ERT_CODE;
+
+               bool closeLanguage = false;
+               bool lang_switched_at_inset = false;
+               if (fontswitch_inset) {
+                       // 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),
+                       // so we don't close the language in those cases
+                       // (= differing isRightToLeft()).
+                       // ArabTeX, though, doesn't seem to handle this special behavior.
+                       closeLanguage = basefont.isRightToLeft() == current_font.isRightToLeft()
+                                       || basefont.language()->lang() == "arabic_arabtex"
+                                       || current_font.language()->lang() == "arabic_arabtex";
+                       // We need to check prev_font as language changes directly at inset
+                       // will only be started inside the inset.
+                       lang_switched_at_inset = prev_font.language() != current_font.language();
+               }
 
                // Do we need to close the previous font?
+               bool langClosed = false;
                if (open_font &&
                    ((current_font != running_font
                      || current_font.language() != running_font.language())
-                    || (multipar_inset
-                        && (current_font == prev_font
-                            || current_font.language() == prev_font.language()))))
+                    || (fontswitch_inset
+                        && (current_font == prev_font))))
                {
                        // ensure there is no open script-wrapper
                        if (!alien_script.empty()) {
@@ -2605,6 +2635,9 @@ void Paragraph::latex(BufferParams const & bparams,
                                os << '}';
                                column += 1;
                        }
+                       if (closeLanguage)
+                               // Force language closing
+                               current_font.setLanguage(basefont.language());
                        column += running_font.latexWriteEndChanges(
                                    os, bparams, runparams, basefont,
                                    (i == body_pos-1) ? basefont : current_font,
@@ -2618,6 +2651,7 @@ void Paragraph::latex(BufferParams const & bparams,
                        }
                        running_font = basefont;
                        open_font = false;
+                       langClosed = true;
                }
 
                // if necessary, close language environment before opening CJK
@@ -2634,7 +2668,8 @@ void Paragraph::latex(BufferParams const & bparams,
                }
 
                // Switch file encoding if necessary (and allowed)
-               if (!runparams.pass_thru && !style.pass_thru &&
+               if ((!fontswitch_inset || closeLanguage)
+                   && !runparams.pass_thru && !style.pass_thru &&
                    runparams.encoding->package() != Encoding::none &&
                    current_font.language()->encoding()->package() != Encoding::none) {
                        pair<bool, int> const enc_switch =
@@ -2664,19 +2699,19 @@ void Paragraph::latex(BufferParams const & bparams,
                     current_font.language() != running_font.language())
                    && i != body_pos - 1)
                {
-                       if (in_ct_deletion) {
-                               // We have to close and then reopen \lyxdeleted,
-                               // as strikeout needs to be on lowest level.
-                               bool needPar = false;
-                               OutputParams rp = runparams;
-                               column += running_font.latexWriteEndChanges(
-                                       os, bparams, rp, basefont,
-                                       basefont, needPar);
-                               os << '}';
-                               column += 1;
-                       }
-                       otexstringstream ots;
-                       if (!multipar_inset) {
+                       if (!fontswitch_inset) {
+                               if (in_ct_deletion) {
+                                       // We have to close and then reopen \lyxdeleted,
+                                       // as strikeout needs to be on lowest level.
+                                       bool needPar = false;
+                                       OutputParams rp = runparams;
+                                       column += running_font.latexWriteEndChanges(
+                                               os, bparams, rp, basefont,
+                                               basefont, needPar);
+                                       os << '}';
+                                       column += 1;
+                               }
+                               otexstringstream ots;
                                InsetText const * textinset = inInset().asInsetText();
                                bool const cprotect = textinset
                                        ? textinset->hasCProtectContent(runparams.moving_arg)
@@ -2685,35 +2720,38 @@ void Paragraph::latex(BufferParams const & bparams,
                                column += current_font.latexWriteStartChanges(ots, bparams,
                                                                              runparams, basefont, last_font, false,
                                                                              cprotect);
-                       }
-                       // Check again for display math in ulem commands as a
-                       // font change may also occur just before a math inset.
-                       if (runparams.inDisplayMath && !deleted_display_math
-                           && runparams.inulemcmd) {
-                               if (os.afterParbreak())
-                                       os << "\\noindent";
-                               else
-                                       os << "\\\\\n";
-                       }
-                       running_font = current_font;
-                       open_font = true;
-                       docstring fontchange = ots.str();
-                       os << fontchange;
-                       // check whether the fontchange ends with a \\textcolor
-                       // modifier and the text starts with a space. If so we
-                       // need to add } in order to prevent \\textcolor from gobbling
-                       // the space (bug 4473).
-                       docstring const last_modifier = rsplit(fontchange, '\\');
-                       if (prefixIs(last_modifier, from_ascii("textcolor")) && c == ' ')
-                               os << from_ascii("{}");
-                       else if (ots.terminateCommand())
-                               os << termcmd;
-                       if (in_ct_deletion) {
-                               // We have to close and then reopen \lyxdeleted,
-                               // as strikeout needs to be on lowest level.
-                               OutputParams rp = runparams;
-                               column += Changes::latexMarkChange(os, bparams,
-                                       Change(Change::UNCHANGED), change, rp);
+                               // Check again for display math in ulem commands as a
+                               // font change may also occur just before a math inset.
+                               if (runparams.inDisplayMath && !deleted_display_math
+                                   && runparams.inulemcmd) {
+                                       if (os.afterParbreak())
+                                               os << "\\noindent";
+                                       else
+                                               os << "\\\\\n";
+                               }
+                               running_font = current_font;
+                               open_font = true;
+                               docstring fontchange = ots.str();
+                               os << fontchange;
+                               // check whether the fontchange ends with a \\textcolor
+                               // modifier and the text starts with a space. If so we
+                               // need to add } in order to prevent \\textcolor from gobbling
+                               // the space (bug 4473).
+                               docstring const last_modifier = rsplit(fontchange, '\\');
+                               if (prefixIs(last_modifier, from_ascii("textcolor")) && c == ' ')
+                                       os << from_ascii("{}");
+                               else if (ots.terminateCommand())
+                                       os << termcmd;
+                               if (in_ct_deletion) {
+                                       // We have to close and then reopen \lyxdeleted,
+                                       // as strikeout needs to be on lowest level.
+                                       OutputParams rp = runparams;
+                                       column += Changes::latexMarkChange(os, bparams,
+                                               Change(Change::UNCHANGED), change, rp);
+                               }
+                       } else {
+                               running_font = current_font;
+                               open_font = !langClosed;
                        }
                }
 
@@ -2779,32 +2817,11 @@ void Paragraph::latex(BufferParams const & bparams,
                                // We need to restore parts of this after insets with
                                // allowMultiPar() true
                                Font const save_basefont = basefont;
-                               Font const save_runningfont = running_font;
-                               bool closeLanguage = false;
-                               bool lang_switched_at_inset = false;
-                               if (fontswitch_inset) {
-                                       // 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),
-                                       // so we don't close the language in those cases
-                                       // (= differing isRightToLeft()).
-                                       // ArabTeX, though, doesn't seem to handle this special behavior.
-                                       bool const inRLSwitch = 
-                                                       basefont.isRightToLeft() != running_font.isRightToLeft()
-                                                       && basefont.language()->lang() != "arabic_arabtex"
-                                                       && running_font.language()->lang() != "arabic_arabtex";
-                                       // Having said that, PassThru insets must be inside a font change command,
-                                       // as we do not re-open the font inside. So:
-                                       closeLanguage = !inset->isPassThru() && !inRLSwitch;;
-                                       // We need to check prev_font as language changes directly at inset
-                                       // will only be started inside the inset.
-                                       lang_switched_at_inset = prev_font.language() != running_font.language();
-                               }
                                d->latexInset(bparams, os, rp, running_font,
                                                basefont, real_outerfont, open_font,
-                               if (multipar_inset) {
-                                               runningChange, style, i, column,
-                                               fontswitch_inset, closeLanguage, lang_switched_at_inset);
+                                               runningChange, style, i, column, fontswitch_inset,
+                                               closeLanguage, lang_switched_at_inset);
+                               if (fontswitch_inset) {
                                        if (open_font) {
                                                bool needPar = false;
                                                column += running_font.latexWriteEndChanges(
@@ -4527,7 +4544,7 @@ Language * Paragraph::Private::locateSpellRange(
                // hop to end of word
                while (last < to && !owner_->isWordSeparator(last)) {
                        Inset const * inset = owner_->getInset(last);
-                       if (inset && inset->lyxCode() == SPECIALCHAR_CODE) {
+                       if (inset && dynamic_cast<const InsetSpecialChar *>(inset)) {
                                // check for "invisible" letters such as ligature breaks
                                odocstringstream os;
                                inset->toString(os);