]> git.lyx.org Git - lyx.git/blobdiff - src/output_latex.cpp
Add buffer param to opt-out fragile content movement
[lyx.git] / src / output_latex.cpp
index 4124d2dd1c92fde9f5cf08cb62ca29808ed1277f..8a6ed8f4e5230501c7b5a3a0e1f99ea75f27c6bc 100644 (file)
@@ -434,6 +434,22 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
                        continue;
                }
 
+               // Do not output empty environments if the whole paragraph has
+               // been deleted with ct and changes are not output.
+               if (size_t(pit + 1) < paragraphs.size()) {
+                       ParagraphList::const_iterator nextpar = paragraphs.constIterator(pit + 1);
+                       Paragraph const & cpar = paragraphs.at(pit);
+                       if ((par->layout() != nextpar->layout()
+                            || par->params().depth() == nextpar->params().depth()
+                            || par->params().leftIndent() == nextpar->params().leftIndent())
+                           && !runparams.for_search && cpar.size() > 0
+                           && cpar.isDeleted(0, cpar.size()) && !buf.params().output_changes) {
+                               if (!buf.params().output_changes && !cpar.parEndChange().deleted())
+                                       os << '\n' << '\n';
+                               continue;
+                       }
+               }
+
                // This is a new environment.
                TeXEnvironmentData const data =
                        prepareEnvironment(buf, text, par, os, runparams);
@@ -742,6 +758,12 @@ void TeXOnePar(Buffer const & buf,
        if (style.inpreamble && !force)
                return;
 
+       // Do not output empty commands if the whole paragraph has
+       // been deleted with ct and changes are not output.
+       if (!runparams_in.for_search && style.latextype != LATEX_ENVIRONMENT
+           && par.size() > 0 && par.isDeleted(0, par.size()) && !bparams.output_changes)
+               return;
+
        LYXERR(Debug::LATEX, "TeXOnePar for paragraph " << pit << " ptr " << &par << " '"
                << everypar << "'");
 
@@ -763,11 +785,14 @@ void TeXOnePar(Buffer const & buf,
                state->open_encoding_ = none;
        }
 
+       // This paragraph is merged and we do not show changes in the output
+       bool const merged_par = !bparams.output_changes && par.parEndChange().deleted();
+
        if (text.inset().isPassThru()) {
                Font const outerfont = text.outerFont(pit);
 
                // No newline before first paragraph in this lyxtext
-               if (pit > 0 && !text.inset().getLayout().parbreakIgnored()) {
+               if (pit > 0 && !text.inset().getLayout().parbreakIgnored() && !merged_par) {
                        os << '\n';
                        if (!text.inset().getLayout().parbreakIsNewline())
                                os << '\n';
@@ -781,6 +806,10 @@ void TeXOnePar(Buffer const & buf,
                ? nullptr : &paragraphs.at(pit + 1);
 
        bool const intitle_command = style.intitle && style.isCommand();
+       // Intitle commands switch languages locally, thus increase
+       // language nesting level
+       if (intitle_command)
+               state->nest_level_ += 1;
 
        if (style.pass_thru) {
                Font const outerfont = text.outerFont(pit);
@@ -789,7 +818,8 @@ void TeXOnePar(Buffer const & buf,
                        // Due to the moving argument, some fragile
                        // commands (labels, index entries)
                        // are output after this command (#2154)
-                       runparams.postpone_fragile_stuff = true;
+                       runparams.postpone_fragile_stuff =
+                               bparams.postpone_fragile_content;
                if (intitle_command)
                        os << '{';
 
@@ -803,17 +833,20 @@ void TeXOnePar(Buffer const & buf,
                        if (par.needsCProtection(runparams.moving_arg)
                            && contains(runparams.active_chars, '^'))
                                os << "\\endgroup";
-                       os << "\n";
+                       if (merged_par)
+                               os << "{}";
+                       else
+                               os << "\n";
                }
-               else
+               else if (!merged_par)
                        os << '\n';
-               if (!style.parbreak_is_newline) {
+               if (!style.parbreak_is_newline && !merged_par) {
                        os << '\n';
                } else if (nextpar && !style.isEnvironment()) {
                        Layout const nextstyle = text.inset().forcePlainLayout()
                                ? bparams.documentClass().plainLayout()
                                : nextpar->layout();
-                       if (nextstyle.name() != style.name())
+                       if (nextstyle.name() != style.name() && !merged_par)
                                os << '\n';
                }
 
@@ -900,7 +933,8 @@ void TeXOnePar(Buffer const & buf,
                        // Due to the moving argument, some fragile
                        // commands (labels, index entries)
                        // are output after this command (#2154)
-                       runparams.postpone_fragile_stuff = true;
+                       runparams.postpone_fragile_stuff =
+                               bparams.postpone_fragile_content;
                os << '{';
        }
 
@@ -913,10 +947,12 @@ void TeXOnePar(Buffer const & buf,
                && runparams.local_font != nullptr
                && outer_language->rightToLeft()
                && !par_language->rightToLeft();
-       bool const localswitch = runparams_in.for_search
+       bool const localswitch =
+                       (runparams_in.for_search
                        || text.inset().forceLocalFontSwitch()
                        || (using_begin_end && text.inset().forcePlainLayout())
-                       || in_polyglossia_rtl_env;
+                       || in_polyglossia_rtl_env)
+                       && !text.inset().forceParDirectionSwitch();
        if (localswitch) {
                lang_begin_command = use_polyglossia ?
                            "\\text$$lang$$opts{" : lyxrc.language_command_local;
@@ -1115,7 +1151,8 @@ void TeXOnePar(Buffer const & buf,
                        // Due to the moving argument, some fragile
                        // commands (labels, index entries)
                        // are output after this command (#2154)
-                       runparams.postpone_fragile_stuff = true;
+                       runparams.postpone_fragile_stuff =
+                               bparams.postpone_fragile_content;
        }
 
        Font const outerfont = text.outerFont(pit);
@@ -1164,7 +1201,7 @@ void TeXOnePar(Buffer const & buf,
                            && nextpar->getDepth() < par.getDepth()))
                        close_lang_switch = using_begin_end;
                if (nextpar && par.params().depth() < nextpar->params().depth())
-                       pending_newline = !text.inset().getLayout().parbreakIgnored();
+                       pending_newline = !text.inset().getLayout().parbreakIgnored() && !merged_par;
                break;
        case LATEX_ENVIRONMENT: {
                // if it's the last paragraph of the current environment
@@ -1183,7 +1220,7 @@ void TeXOnePar(Buffer const & buf,
        default:
                // we don't need it for the last paragraph and in InTitle commands!!!
                if (nextpar && !intitle_command)
-                       pending_newline = !text.inset().getLayout().parbreakIgnored();
+                       pending_newline = !text.inset().getLayout().parbreakIgnored() && !merged_par;
        }
 
        // InTitle commands use switches (not environments) for space settings
@@ -1320,6 +1357,14 @@ void TeXOnePar(Buffer const & buf,
        bool const last_was_separator =
                par.size() > 0 && par.isEnvSeparator(par.size() - 1);
 
+       // Signify added/deleted par break in output if show changes in output
+       if (nextpar && !os.afterParbreak() && !last_was_separator
+           && bparams.output_changes && par.parEndChange().changed()) {
+               Changes::latexMarkChange(os, bparams, Change(Change::UNCHANGED),
+                                        par.parEndChange(), runparams);
+               os << bparams.encoding().latexString(docstring(1, 0x00b6)).first << "}";
+       }
+
        if (pending_newline) {
                if (unskip_newline)
                        // prevent unwanted whitespace
@@ -1403,7 +1448,7 @@ void TeXOnePar(Buffer const & buf,
        // TeXEnvironment, because it is needed in this case
        if (nextpar && !os.afterParbreak() && !last_was_separator) {
                Layout const & next_layout = nextpar->layout();
-               if (!text.inset().getLayout().parbreakIgnored())
+               if (!text.inset().getLayout().parbreakIgnored() && !merged_par)
                        // Make sure to start a new line
                        os << breakln;
                // A newline '\n' is always output before a command,
@@ -1447,11 +1492,18 @@ void TeXOnePar(Buffer const & buf,
                                && next_layout.align == nextpar->getAlign(bparams))
                            || (style.align != par.getAlign(bparams)
                                && tclass.isDefaultLayout(next_layout))) {
-                               os << '\n';
+                               // and omit paragraph break if it has been deleted with ct
+                               // and changes are not shown in output
+                               if (!merged_par)
+                                       os << '\n';
                        }
                }
        }
 
+       // Reset language nesting level after intitle command
+       if (intitle_command)
+               state->nest_level_ -= 1;
+
        LYXERR(Debug::LATEX, "TeXOnePar for paragraph " << pit << " done; ptr "
                << &par << " next " << nextpar);
 
@@ -1604,6 +1656,22 @@ void latexParagraphs(Buffer const & buf,
                        continue;
                }
 
+               // Do not output empty environments if the whole paragraph has
+               // been deleted with ct and changes are not output.
+               if (size_t(pit + 1) < paragraphs.size()) {
+                       ParagraphList::const_iterator nextpar = paragraphs.constIterator(pit + 1);
+                       Paragraph const & cpar = paragraphs.at(pit);
+                       if ((par->layout() != nextpar->layout()
+                            || par->params().depth() == nextpar->params().depth()
+                            || par->params().leftIndent() == nextpar->params().leftIndent())
+                           && !runparams.for_search && cpar.size() > 0
+                           && cpar.isDeleted(0, cpar.size()) && !bparams.output_changes) {
+                               if (!bparams.output_changes && !cpar.parEndChange().deleted())
+                                       os << '\n' << '\n';
+                               continue;
+                       }
+               }
+
                TeXEnvironmentData const data =
                        prepareEnvironment(buf, text, par, os, runparams);
                // pit can be changed in TeXEnvironment.
@@ -1643,7 +1711,9 @@ void latexParagraphs(Buffer const & buf,
                                        "$$lang",
                                        mainlang))
                        << '\n';
-               if (using_begin_end)
+               // If we have language_auto_begin, the stack will
+               // already be empty, nothing to pop()
+               if (using_begin_end && !lyxrc.language_auto_begin)
                        popLanguageName();
        }