]> git.lyx.org Git - lyx.git/blobdiff - src/output_latex.cpp
Amend 207eaeee9071cb
[lyx.git] / src / output_latex.cpp
index 61537c827f64f73835a4f39761271eae76c5850f..49dbd2d07a8722a9d8485615faf0d329d5df48d4 100644 (file)
@@ -404,7 +404,7 @@ static void finishEnvironment(otexstream & os, OutputParams const & runparams,
 
 
 void TeXEnvironment(Buffer const & buf, Text const & text,
-                   OutputParams const & runparams,
+                   OutputParams const & runparams_in,
                    pit_type & pit, otexstream & os)
 {
        ParagraphList const & paragraphs = text.paragraphs();
@@ -415,6 +415,10 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
        depth_type const current_depth = ipar->params().depth();
        Length const & current_left_indent = ipar->params().leftIndent();
 
+       OutputParams runparams = runparams_in;
+       runparams.no_cprotect = current_layout.nocprotect;
+       runparams.no_pass_thru_chars = current_layout.no_pass_thru_chars;
+
        // This is for debugging purpose at the end.
        pit_type const par_begin = pit;
        for (; pit < runparams.par_end; ++pit) {
@@ -462,10 +466,10 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
                // Do not output empty environments if the whole paragraph has
                // been deleted with ct and changes are not output.
                bool output_changes;
-               if (runparams.for_searchAdv == OutputParams::NoSearch)
+               if (!runparams.find_effective())
                        output_changes = buf.params().output_changes;
                else
-                       output_changes = ((runparams.for_searchAdv & OutputParams::SearchWithDeleted) != 0);
+                       output_changes = runparams.find_with_deleted();
                if (size_t(pit + 1) < paragraphs.size()) {
                        ParagraphList::const_iterator nextpar = paragraphs.iterator_at(pit + 1);
                        Paragraph const & cpar = paragraphs.at(pit);
@@ -491,11 +495,19 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
 
        if (pit != runparams.par_end)
                LYXERR(Debug::OUTFILE, "TeXEnvironment for paragraph " << par_begin << " done.");
+
+       // set upstream encoding
+       runparams_in.encoding = runparams.encoding;
 }
 
 
-void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeXArgMap const & latexargs,
-                 map<size_t, lyx::InsetArgument const *> ilist, vector<string> required, string const & prefix)
+// FIXME: pass the \c required vector by reference and add the stuff
+// from \c latexargs to a different vector. This avoids a copy and
+// (more importantly?) a coverity defect.
+void getArgInsets(otexstream & os, OutputParams const & runparams,
+                  Layout::LaTeXArgMap const & latexargs,
+                  map<size_t, lyx::InsetArgument const *> const & ilist,
+                  vector<string> required, string const & prefix)
 {
        size_t const argnr = latexargs.size();
        if (argnr == 0)
@@ -578,7 +590,7 @@ void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeX
                        }
                }
        }
-       if ((runparams.for_searchAdv != OutputParams::NoSearch) && argnr > 1) {
+       if (runparams.find_effective() && argnr > 1) {
                // Mark end of arguments for findadv() only
                os << "\\endarguments{}";
        }
@@ -731,7 +743,7 @@ void parStartCommand(Paragraph const & par, otexstream & os,
 {
        switch (style.latextype) {
        case LATEX_COMMAND:
-               if (par.needsCProtection(runparams.moving_arg)) {
+               if (!runparams.no_cprotect && par.needsCProtection(runparams.moving_arg)) {
                        if (contains(runparams.active_chars, '^'))
                                // cprotect relies on ^ being on catcode 7
                                os << "\\begingroup\\catcode`\\^=7";
@@ -746,7 +758,7 @@ void parStartCommand(Paragraph const & par, otexstream & os,
                break;
        case LATEX_ITEM_ENVIRONMENT:
        case LATEX_LIST_ENVIRONMENT:
-               if (runparams.for_searchAdv != OutputParams::NoSearch) {
+               if (runparams.find_effective()) {
                        os << "\\" + style.itemcommand() << "{" << style.latexname() << "}";
                }
                else {
@@ -758,7 +770,7 @@ void parStartCommand(Paragraph const & par, otexstream & os,
                }
                break;
        case LATEX_ENVIRONMENT:
-               if (runparams.for_searchAdv != OutputParams::NoSearch) {
+               if (runparams.find_effective()) {
                        os << "\\latexenvironment{" << style.latexname() << "}{";
                }
                break;
@@ -796,7 +808,7 @@ void TeXOnePar(Buffer const & buf,
 
        // Do not output empty commands if the whole paragraph has
        // been deleted with ct and changes are not output.
-       if (((runparams_in.for_searchAdv & OutputParams::SearchWithDeleted) == 0) && style.latextype != LATEX_ENVIRONMENT
+       if (!runparams_in.find_with_deleted() && style.latextype != LATEX_ENVIRONMENT
            && !par.empty() && par.isDeleted(0, par.size()) && !bparams.output_changes)
                return;
 
@@ -866,7 +878,7 @@ void TeXOnePar(Buffer const & buf,
                // the code is different (JMarc)
                if (style.isCommand()) {
                        os << "}";
-                       if (par.needsCProtection(runparams.moving_arg)
+                       if (!runparams.no_cprotect && par.needsCProtection(runparams.moving_arg)
                            && contains(runparams.active_chars, '^'))
                                os << "\\endgroup";
                        if (merged_par)
@@ -936,7 +948,7 @@ void TeXOnePar(Buffer const & buf,
        bool const have_prior_nptpar =
                        prior_nontitle_par && !prior_nontitle_par->isPassThru();
        Language const * const prev_language =
-               runparams_in.for_searchAdv != OutputParams::NoSearch
+               runparams_in.find_effective()
                        ? languages.getLanguage("ignore")
                        : (have_prior_nptpar)
                                ? (use_prev_env_language 
@@ -988,7 +1000,7 @@ void TeXOnePar(Buffer const & buf,
                && !(have_prior_nptpar
                     && (prev_language->rightToLeft() != par_language->rightToLeft()));
        bool const localswitch =
-                       (runparams_in.for_searchAdv != OutputParams::NoSearch
+                       (runparams_in.find_effective()
                        || text.inset().forceLocalFontSwitch()
                        || (using_begin_end && text.inset().forcePlainLayout())
                        || in_polyglossia_rtl_env)
@@ -1003,7 +1015,7 @@ void TeXOnePar(Buffer const & buf,
        bool const localswitch_needed = localswitch && par_lang != outer_lang;
 
        // localswitches need to be closed and reopened at each par
-       if ((runparams_in.for_searchAdv != OutputParams::NoSearch) || ((par_lang != prev_lang || localswitch_needed)
+       if (runparams_in.find_effective() || ((par_lang != prev_lang || localswitch_needed)
             // check if we already put language command in TeXEnvironment()
             && !(style.isEnvironment()
                  && (pit == 0 || (priorpar->layout() != par.layout()
@@ -1063,7 +1075,7 @@ void TeXOnePar(Buffer const & buf,
                                else if (outer_language->lang() == "arabic_arabi")
                                        os << "\\textLR{";
                                // remaining RTL languages currently is hebrew
-                               else if (par_language->rightToLeft())
+                               else if (par_language->rightToLeft() && !runparams.isFullUnicode())
                                        os << "\\R{";
                                else
                                        os << "\\L{";
@@ -1071,7 +1083,7 @@ void TeXOnePar(Buffer const & buf,
                        // With CJK, the CJK tag has to be closed first (see below)
                        if ((runparams.encoding->package() != Encoding::CJK
                                 || bparams.useNonTeXFonts
-                                || (runparams.for_searchAdv != OutputParams::NoSearch))
+                                || runparams.find_effective())
                            && (par_lang != openLanguageName(state) || localswitch || intitle_command)
                            && !par_lang.empty()) {
                                string bc = use_polyglossia ?
@@ -1174,7 +1186,7 @@ void TeXOnePar(Buffer const & buf,
                                && (pit == 0 || !priorpar->hasSameLayout(par)))
                        {
                                os << from_ascii(par.params().spacing().writeEnvirBegin(useSetSpace))
-                                   << '\n';
+                                  << '\n';
                        }
 
                        if (style.isCommand()) {
@@ -1207,9 +1219,19 @@ void TeXOnePar(Buffer const & buf,
 
        bool const is_command = style.isCommand();
 
+       bool const last_was_separator =
+               !par.empty() && par.isEnvSeparator(par.size() - 1);
+
        // InTitle commands need to be closed after the language has been closed.
        if (!intitle_command) {
                if (is_command) {
+                       // 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 << "}";
+                       }
                        os << '}';
                        if (!style.postcommandargs().empty())
                                latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
@@ -1219,7 +1241,7 @@ void TeXOnePar(Buffer const & buf,
                                os << runparams.post_macro;
                                runparams.post_macro.clear();
                        }
-                       if (par.needsCProtection(runparams.moving_arg)
+                       if (!runparams.no_cprotect && par.needsCProtection(runparams.moving_arg)
                            && contains(runparams.active_chars, '^'))
                                os << "\\endgroup";
                        if (runparams.encoding != prev_encoding) {
@@ -1298,13 +1320,18 @@ void TeXOnePar(Buffer const & buf,
        if (localswitch_needed
            || (intitle_command && using_begin_end)
            || closing_rtl_ltr_environment
-           || (((runparams.isLastPar && !runparams.inbranch) || close_lang_switch)
+           || (((runparams.isLastPar
+                 && (using_begin_end
+                     // Since \selectlanguage write the language to the aux file,
+                     // we need to reset the language at the end of footnote or
+                     // float.
+                     || runparams.inFloat != OutputParams::NONFLOAT || runparams.inFootnote
+                     // Same for maintext in children (see below)
+                     || maintext))
+                || close_lang_switch)
                && (par_lang != outer_lang || (using_begin_end
                                                && style.isEnvironment()
                                                && par_lang != nextpar_lang)))) {
-               // Since \selectlanguage write the language to the aux file,
-               // we need to reset the language at the end of footnote or
-               // float.
 
                if (!localswitch && (pending_newline || close_lang_switch))
                        os << '\n';
@@ -1312,7 +1339,7 @@ void TeXOnePar(Buffer const & buf,
                // when the paragraph uses CJK, the language has to be closed earlier
                if ((font.language()->encoding()->package() != Encoding::CJK)
                        || bparams.useNonTeXFonts
-                       || (runparams_in.for_searchAdv != OutputParams::NoSearch)) {
+                       || runparams_in.find_effective()) {
                        if (lang_end_command.empty()) {
                                // If this is a child, we should restore the
                                // master language after the last paragraph.
@@ -1385,7 +1412,7 @@ void TeXOnePar(Buffer const & buf,
                        os << runparams.post_macro;
                        runparams.post_macro.clear();
                }
-               if (par.needsCProtection(runparams.moving_arg)
+               if (!runparams.no_cprotect && par.needsCProtection(runparams.moving_arg)
                    && contains(runparams.active_chars, '^'))
                        os << "\\endgroup";
                if (runparams.encoding != prev_encoding) {
@@ -1394,11 +1421,8 @@ void TeXOnePar(Buffer const & buf,
                }
        }
 
-       bool const last_was_separator =
-               !par.empty() && par.isEnvSeparator(par.size() - 1);
-
        // Signify added/deleted par break in output if show changes in output
-       if (nextpar && !os.afterParbreak() && !last_was_separator
+       if ((intitle_command || !is_command) && nextpar && !os.afterParbreak() && !last_was_separator
            && bparams.output_changes && par.parEndChange().changed()) {
                Changes::latexMarkChange(os, bparams, Change(Change::UNCHANGED),
                                         par.parEndChange(), runparams);
@@ -1499,21 +1523,22 @@ void TeXOnePar(Buffer const & buf,
                Layout const & next_layout = nextpar->layout();
                if (!next_layout.isCommand()) {
                        // Here we now try to avoid spurious empty lines by
-                       // outputting a paragraph break only if: (case 1) the
-                       // paragraph style allows parbreaks and no \begin, \end
-                       // or \item tags are going to follow (i.e., if the next
-                       // isn't the first or the current isn't the last
-                       // paragraph of an environment or itemize) and the
-                       // depth and alignment of the following paragraph is
-                       // unchanged, or (case 2) the following is a
-                       // non-environment paragraph whose depth is increased
-                       // but whose alignment is unchanged, or (case 3) the
-                       // paragraph is not an environment and the next one is a
-                       // non-itemize-like env at lower depth, or (case 4) the
-                       // paragraph is a command not followed by an environment
-                       // and the alignment of the current and next paragraph
-                       // is unchanged, or (case 5) the current alignment is
-                       // changed and a standard paragraph follows.
+                       // outputting a paragraph break only if: 
+                       // (case 1) the paragraph style allows parbreaks and
+                       // no \begin, \end or \item tags are going to follow
+                       // (i.e., if the next isn't the first or the current
+                       // isn't the last paragraph of an environment or itemize)
+                       // and the depth and alignment of the following paragraph is
+                       // unchanged, or 
+                       // (case 2) the following is a non-environment paragraph
+                       // whose depth is increased but whose alignment is unchanged, or
+                       // (case 3) the paragraph is not an environment and the next one
+                       // is a non-itemize-like env at lower depth, or
+                       // (case 4) the paragraph is a command not followed by an
+                       // environment and the alignment of the current and next
+                       // paragraph is unchanged, or
+                       // (case 5) the current alignment is changed and a
+                       // standard paragraph follows.
                        DocumentClass const & tclass = bparams.documentClass();
                        if ((style == next_layout
                             && !style.parbreak_is_newline
@@ -1523,7 +1548,8 @@ void TeXOnePar(Buffer const & buf,
                             && style.latextype != LATEX_LIST_ENVIRONMENT
                             && style.align == par.getAlign(bparams)
                             && nextpar->getDepth() == par.getDepth()
-                            && nextpar->getAlign(bparams) == par.getAlign(bparams))
+                            && (nextpar->getAlign(bparams) == par.getAlign(bparams)
+                                || par.params().spacing() != nextpar->params().spacing()))
                            || (!next_layout.isEnvironment()
                                && nextpar->getDepth() > par.getDepth()
                                && nextpar->getAlign(bparams) == next_layout.align)
@@ -1708,10 +1734,10 @@ void latexParagraphs(Buffer const & buf,
                // Do not output empty environments if the whole paragraph has
                // been deleted with ct and changes are not output.
                bool output_changes;
-               if (runparams.for_searchAdv == OutputParams::NoSearch)
+               if (!runparams.find_effective())
                        output_changes = bparams.output_changes;
                else
-                       output_changes = ((runparams.for_searchAdv & OutputParams::SearchWithDeleted) != 0);
+                       output_changes = runparams.find_with_deleted();
                bool const lastpar = size_t(pit + 1) >= paragraphs.size();
                if (!lastpar) {
                        ParagraphList::const_iterator nextpar = paragraphs.iterator_at(pit + 1);
@@ -1854,7 +1880,7 @@ pair<bool, int> switchEncoding(odocstream & os, BufferParams const & bparams,
                || oldEnc.package() == Encoding::japanese
                || oldEnc.package() == Encoding::none
                || newEnc.package() == Encoding::none
-               || (runparams.for_searchAdv != OutputParams::NoSearch))
+               || runparams.find_effective())
                return make_pair(false, 0);
        // FIXME We ignore encoding switches from/to encodings that do
        // neither support the inputenc package nor the CJK package here.