]> git.lyx.org Git - lyx.git/blobdiff - src/output_latex.cpp
Revert "XHTML: remove DOCTYPE, as the document is then understood as HTML4/XHTML1...
[lyx.git] / src / output_latex.cpp
index 8a33d51dc403497728ec856376104dda614f215b..12f58aaecdaff0c9d5c103321425d3d35854fde0 100644 (file)
@@ -383,7 +383,7 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
                    pit_type & pit, otexstream & os)
 {
        ParagraphList const & paragraphs = text.paragraphs();
-       ParagraphList::const_iterator ipar = paragraphs.constIterator(pit);
+       ParagraphList::const_iterator ipar = paragraphs.iterator_at(pit);
        LYXERR(Debug::LATEX, "TeXEnvironment for paragraph " << pit);
 
        Layout const & current_layout = ipar->layout();
@@ -393,7 +393,7 @@ void TeXEnvironment(Buffer const & buf, Text const & text,
        // This is for debugging purpose at the end.
        pit_type const par_begin = pit;
        for (; pit < runparams.par_end; ++pit) {
-               ParagraphList::const_iterator par = paragraphs.constIterator(pit);
+               ParagraphList::const_iterator par = paragraphs.iterator_at(pit);
 
                // check first if this is an higher depth paragraph.
                bool go_out = (par->params().depth() < current_depth);
@@ -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.iterator_at(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);
@@ -458,8 +474,8 @@ void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeX
        // other arguments, consider this.
        for (auto const & larg : latexargs) {
                Layout::latexarg const & arg = larg.second;
-               if ((!arg.presetarg.empty() || !arg.defaultarg.empty()) && !arg.requires.empty()) {
-                               vector<string> req = getVectorFromString(arg.requires);
+               if ((!arg.presetarg.empty() || !arg.defaultarg.empty()) && !arg.required.empty()) {
+                               vector<string> req = getVectorFromString(arg.required);
                                required.insert(required.end(), req.begin(), req.end());
                        }
        }
@@ -593,7 +609,7 @@ void addArgInsets(Paragraph const & par, string const & prefix,
                        latexargs.find(arg->name());
                if (lit != latexargs.end()) {
                        Layout::latexarg const & larg = lit->second;
-                       vector<string> req = getVectorFromString(larg.requires);
+                       vector<string> req = getVectorFromString(larg.required);
                        move(req.begin(), req.end(), back_inserter(required));
                }
        }
@@ -627,11 +643,11 @@ void latexArgInsets(ParagraphList const & pars,
        Layout const current_layout = pit->layout();
 
        // get the first paragraph in sequence with this layout and depth
-       pit_type offset = 0;
+       ptrdiff_t offset = 0;
        while (true) {
-               if (lyx::prev(pit, offset) == pars.begin())
+               if (prev(pit, offset) == pars.begin())
                        break;
-               ParagraphList::const_iterator priorpit = lyx::prev(pit, offset + 1);
+               ParagraphList::const_iterator priorpit = prev(pit, offset + 1);
                if (priorpit->layout() == current_layout
                    && priorpit->params().depth() == current_depth)
                        ++offset;
@@ -639,7 +655,7 @@ void latexArgInsets(ParagraphList const & pars,
                        break;
        }
 
-       ParagraphList::const_iterator spit = lyx::prev(pit, offset);
+       ParagraphList::const_iterator spit = prev(pit, offset);
 
        for (; spit != pars.end(); ++spit) {
                if (spit->layout() != current_layout ||
@@ -745,7 +761,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_search && style.latextype != LATEX_ENVIRONMENT
-           && par.isDeleted(0, par.size()) && !bparams.output_changes)
+           && par.size() > 0 && par.isDeleted(0, par.size()) && !bparams.output_changes)
                return;
 
        LYXERR(Debug::LATEX, "TeXOnePar for paragraph " << pit << " ptr " << &par << " '"
@@ -769,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';
@@ -799,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 << '{';
 
@@ -813,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';
                }
 
@@ -910,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 << '{';
        }
 
@@ -1127,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);
@@ -1176,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
@@ -1195,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
@@ -1332,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
@@ -1345,7 +1378,8 @@ void TeXOnePar(Buffer const & buf,
        if (nextpar && state->open_encoding_ == CJK
                && bparams.encoding().iconvName() != "UTF-8"
                && bparams.encoding().package() != Encoding::CJK
-               && (nextpar_language->encoding()->package() != Encoding::CJK
+               && ((nextpar_language &&
+                       nextpar_language->encoding()->package() != Encoding::CJK)
                        || (nextpar->layout().isEnvironment() && nextpar->isMultiLingual(bparams)))
                // inbetween environments, CJK has to be closed later (nesting!)
                && (!style.isEnvironment() || !nextpar->layout().isEnvironment())) {
@@ -1408,6 +1442,9 @@ void TeXOnePar(Buffer const & buf,
 
        // Also pass the post_macros upstream
        runparams_in.post_macro = runparams.post_macro;
+       // These need to be passed upstream as well
+       runparams_in.need_maketitle = runparams.need_maketitle;
+       runparams_in.have_maketitle = runparams.have_maketitle;
 
 
        // we don't need a newline for the last paragraph!!!
@@ -1415,7 +1452,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,
@@ -1459,7 +1496,10 @@ 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';
                        }
                }
        }
@@ -1555,16 +1595,13 @@ void latexParagraphs(Buffer const & buf,
        pit_type pit = runparams.par_begin;
        // lastpit is for the language check after the loop.
        pit_type lastpit = pit;
-       // variables used in the loop:
-       bool was_title = false;
-       bool already_title = false;
        DocumentClass const & tclass = bparams.documentClass();
 
        // Did we already warn about inTitle layout mixing? (we only warn once)
        bool gave_layout_warning = false;
        for (; pit < runparams.par_end; ++pit) {
                lastpit = pit;
-               ParagraphList::const_iterator par = paragraphs.constIterator(pit);
+               ParagraphList::const_iterator par = paragraphs.iterator_at(pit);
 
                // FIXME This check should not be needed. We should
                // perhaps issue an error if it is.
@@ -1572,7 +1609,7 @@ void latexParagraphs(Buffer const & buf,
                                tclass.plainLayout() : par->layout();
 
                if (layout.intitle) {
-                       if (already_title) {
+                       if (runparams.have_maketitle) {
                                if (!gave_layout_warning && !runparams.dryrun) {
                                        gave_layout_warning = true;
                                        frontend::Alert::warning(_("Error in latexParagraphs"),
@@ -1582,15 +1619,16 @@ void latexParagraphs(Buffer const & buf,
                                                          "could lead to missing or incorrect output."
                                                          ), layout.name()));
                                }
-                       } else if (!was_title) {
-                               was_title = true;
+                       } else if (!runparams.need_maketitle) {
+                               runparams.need_maketitle = true;
                                if (tclass.titletype() == TITLE_ENVIRONMENT) {
                                        os << "\\begin{"
                                                        << from_ascii(tclass.titlename())
                                                        << "}\n";
                                }
                        }
-               } else if (was_title && !already_title && !layout.inpreamble) {
+               } else if (runparams.need_maketitle && !runparams.have_maketitle
+                          && !layout.inpreamble && !text.inset().isInTitle()) {
                        if (tclass.titletype() == TITLE_ENVIRONMENT) {
                                os << "\\end{" << from_ascii(tclass.titlename())
                                                << "}\n";
@@ -1599,8 +1637,8 @@ void latexParagraphs(Buffer const & buf,
                                os << "\\" << from_ascii(tclass.titlename())
                                                << "\n";
                        }
-                       already_title = true;
-                       was_title = false;
+                       runparams.have_maketitle = true;
+                       runparams.need_maketitle = false;
                }
 
                if (layout.isCommand() && !layout.latexname().empty()
@@ -1620,6 +1658,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.iterator_at(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.
@@ -1635,8 +1689,11 @@ void latexParagraphs(Buffer const & buf,
                        //os << '\n';
        }
 
-       // It might be that we only have a title in this document
-       if (was_title && !already_title) {
+       // It might be that we only have a title in this document.
+       // But if we're in an inset, this is not the end of
+       // the document. (There may be some other checks of this
+       // kind that are needed.)
+       if (runparams.need_maketitle && !runparams.have_maketitle && maintext) {
                if (tclass.titletype() == TITLE_ENVIRONMENT) {
                        os << "\\end{" << from_ascii(tclass.titlename())
                           << "}\n";