From 768c9a552e895b44b59f984a0533233b9845d11f Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Mon, 30 Apr 2018 09:06:15 +0200 Subject: [PATCH] cprotect allows to place environments in fragile contexts. use that possibility. Fixes parts of #5128. --- lib/layouts/stdinsets.inc | 1 + src/Paragraph.cpp | 8 +++++--- src/Paragraph.h | 2 +- src/insets/Inset.h | 2 +- src/insets/InsetBox.cpp | 13 ++++++++++++- src/insets/InsetBox.h | 3 +++ src/insets/InsetText.cpp | 17 +++++++++++------ src/insets/InsetText.h | 5 +++-- src/output_latex.cpp | 2 +- 9 files changed, 38 insertions(+), 15 deletions(-) diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc index f03b915e7c..c08272284c 100644 --- a/lib/layouts/stdinsets.inc +++ b/lib/layouts/stdinsets.inc @@ -508,6 +508,7 @@ InsetLayout Box:Doublebox End InsetLayout Float + LaTeXType environment LabelFont Color collapsible Size Small diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 5fdfb157d0..307f8f4549 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1794,7 +1794,9 @@ void Paragraph::write(ostream & os, BufferParams const & bparams, void Paragraph::validate(LaTeXFeatures & features) const { d->validate(features); - if (needsCProtection()) + bool fragile = features.runparams().moving_arg; + fragile |= layout().needprotect; + if (needsCProtection(fragile)) features.require("cprotect"); } @@ -3478,7 +3480,7 @@ bool Paragraph::isHardHyphenOrApostrophe(pos_type pos) const } -bool Paragraph::needsCProtection() const +bool Paragraph::needsCProtection(bool const fragile) const { // first check the layout of the paragraph, but only in insets InsetText const * textinset = inInset().asInsetText(); @@ -3506,7 +3508,7 @@ bool Paragraph::needsCProtection() const // now check whether we have insets that need cprotection pos_type size = d->text_.size(); for (pos_type i = 0; i < size; ++i) - if (isInset(i) && getInset(i)->needsCProtection(maintext)) + if (isInset(i) && getInset(i)->needsCProtection(maintext, fragile)) return true; return false; diff --git a/src/Paragraph.h b/src/Paragraph.h index 2a308d6efa..450dfe3265 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -426,7 +426,7 @@ public: bool isHardHyphenOrApostrophe(pos_type pos) const; /// Return true if this paragraph has verbatim content that needs to be /// protected by \cprotect - bool needsCProtection() const; + bool needsCProtection(bool const fragile = false) const; /// returns true if at least one line break or line separator has been deleted /// at the beginning of the paragraph (either physically or logically) diff --git a/src/insets/Inset.h b/src/insets/Inset.h index b6b8db64a5..0f76671ea8 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -595,7 +595,7 @@ public: virtual void rejectChanges() {} /// - virtual bool needsCProtection(bool const) const { return false; } + virtual bool needsCProtection(bool const, bool const) const { return false; } /// virtual ColorCode backgroundColor(PainterInfo const &) const; diff --git a/src/insets/InsetBox.cpp b/src/insets/InsetBox.cpp index e543b44fb3..2219c23e37 100644 --- a/src/insets/InsetBox.cpp +++ b/src/insets/InsetBox.cpp @@ -201,6 +201,17 @@ bool InsetBox::forcePlainLayout(idx_type) const } +bool InsetBox::needsCProtection(bool const maintext, bool const fragile) const +{ + // We need to cprotect boxes that use minipages as inner box + // in fragile context + if (fragile && params_.inner_box && !params_.use_parbox && !params_.use_makebox) + return true; + + return InsetText::needsCProtection(maintext, fragile); +} + + ColorCode InsetBox::backgroundColor(PainterInfo const &) const { // we only support background color for 3 types @@ -336,7 +347,7 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const string separation_string = params_.separation.asLatexString(); string shadowsize_string = params_.shadowsize.asLatexString(); bool stdwidth = false; - string const cprotect = hasCProtectContent() ? "\\cprotect" : string(); + string const cprotect = hasCProtectContent(runparams.moving_arg) ? "\\cprotect" : string(); // in general the overall width of some decorated boxes is wider thean the inner box // we could therefore calculate the real width for all sizes so that if the user wants // e.g. 0.1\columnwidth or 2cm he gets exactly this size diff --git a/src/insets/InsetBox.h b/src/insets/InsetBox.h index d5610b746a..e181bd738a 100644 --- a/src/insets/InsetBox.h +++ b/src/insets/InsetBox.h @@ -123,6 +123,9 @@ public: /// bool forcePlainLayout(idx_type = 0) const; /// + bool needsCProtection(bool const maintext = false, + bool const fragile = false) const; + /// bool neverIndent() const { return true; } /// bool inheritFont() const { return false; } diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index 61c4a19b34..dad7e2e248 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -458,7 +458,7 @@ void InsetText::latex(otexstream & os, OutputParams const & runparams) const // FIXME UNICODE // FIXME \protect should only be used for fragile // commands, but we do not provide this information yet. - if (hasCProtectContent()) + if (hasCProtectContent(runparams.moving_arg)) os << "\\cprotect"; else if (runparams.moving_arg) os << "\\protect"; @@ -762,13 +762,13 @@ ParagraphList & InsetText::paragraphs() } -bool InsetText::hasCProtectContent() const +bool InsetText::hasCProtectContent(bool const fragile) const { ParagraphList const & pars = paragraphs(); pit_type pend = paragraphs().size(); for (pit_type pit = 0; pit != pend; ++pit) { Paragraph const & par = pars[pit]; - if (par.needsCProtection()) + if (par.needsCProtection(fragile)) return true; } return false; @@ -1086,11 +1086,16 @@ InsetText::XHTMLOptions operator|(InsetText::XHTMLOptions a1, InsetText::XHTMLOp } -bool InsetText::needsCProtection(bool const maintext) const +bool InsetText::needsCProtection(bool const maintext, bool const fragile) const { // Nested cprotect content needs \cprotect // on each level - if (hasCProtectContent()) + if (hasCProtectContent(fragile)) + return true; + + // Environments and "no latex" types (e.g., knitr chunks) + // need cprotection regardless the content + if (fragile && getLayout().latextype() == InsetLayout::ENVIRONMENT) return true; if (!getLayout().needsCProtect()) @@ -1111,7 +1116,7 @@ bool InsetText::needsCProtection(bool const maintext) const for (pit_type pit = 0; pit != pend; ++pit) { Paragraph const & par = pars[pit]; - if (par.needsCProtection()) + if (par.needsCProtection(fragile)) return true; docstring const pars = par.asString(); for (int k = 0; k < nchars_escape; k++) { diff --git a/src/insets/InsetText.h b/src/insets/InsetText.h index e4e4bfc798..41bfa18367 100644 --- a/src/insets/InsetText.h +++ b/src/insets/InsetText.h @@ -224,9 +224,10 @@ public: bool confirmDeletion() const { return !text().empty(); } /// - bool needsCProtection(bool const maintext = false) const; + bool needsCProtection(bool const maintext = false, + bool const fragile = false) const; /// - bool hasCProtectContent() const; + bool hasCProtectContent(bool const fragile = false) const; protected: /// diff --git a/src/output_latex.cpp b/src/output_latex.cpp index 25ec597387..148be99490 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -654,7 +654,7 @@ void parStartCommand(Paragraph const & par, otexstream & os, { switch (style.latextype) { case LATEX_COMMAND: - if (par.needsCProtection()) + if (par.needsCProtection(runparams.moving_arg)) os << "\\cprotect"; os << '\\' << from_ascii(style.latexname()); -- 2.39.5