cprotect allows to place environments in fragile contexts.

use that possibility.

Fixes parts of #5128.
This commit is contained in:
Juergen Spitzmueller 2018-04-30 09:06:15 +02:00
parent 15df033bce
commit 768c9a552e
9 changed files with 38 additions and 15 deletions

View File

@ -508,6 +508,7 @@ InsetLayout Box:Doublebox
End End
InsetLayout Float InsetLayout Float
LaTeXType environment
LabelFont LabelFont
Color collapsible Color collapsible
Size Small Size Small

View File

@ -1794,7 +1794,9 @@ void Paragraph::write(ostream & os, BufferParams const & bparams,
void Paragraph::validate(LaTeXFeatures & features) const void Paragraph::validate(LaTeXFeatures & features) const
{ {
d->validate(features); d->validate(features);
if (needsCProtection()) bool fragile = features.runparams().moving_arg;
fragile |= layout().needprotect;
if (needsCProtection(fragile))
features.require("cprotect"); 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 // first check the layout of the paragraph, but only in insets
InsetText const * textinset = inInset().asInsetText(); InsetText const * textinset = inInset().asInsetText();
@ -3506,7 +3508,7 @@ bool Paragraph::needsCProtection() const
// now check whether we have insets that need cprotection // now check whether we have insets that need cprotection
pos_type size = d->text_.size(); pos_type size = d->text_.size();
for (pos_type i = 0; i < size; ++i) 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 true;
return false; return false;

View File

@ -426,7 +426,7 @@ public:
bool isHardHyphenOrApostrophe(pos_type pos) const; bool isHardHyphenOrApostrophe(pos_type pos) const;
/// Return true if this paragraph has verbatim content that needs to be /// Return true if this paragraph has verbatim content that needs to be
/// protected by \cprotect /// 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 /// returns true if at least one line break or line separator has been deleted
/// at the beginning of the paragraph (either physically or logically) /// at the beginning of the paragraph (either physically or logically)

View File

@ -595,7 +595,7 @@ public:
virtual void rejectChanges() {} 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; virtual ColorCode backgroundColor(PainterInfo const &) const;

View File

@ -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 ColorCode InsetBox::backgroundColor(PainterInfo const &) const
{ {
// we only support background color for 3 types // 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 separation_string = params_.separation.asLatexString();
string shadowsize_string = params_.shadowsize.asLatexString(); string shadowsize_string = params_.shadowsize.asLatexString();
bool stdwidth = false; 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 // 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 // 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 // e.g. 0.1\columnwidth or 2cm he gets exactly this size

View File

@ -123,6 +123,9 @@ public:
/// ///
bool forcePlainLayout(idx_type = 0) const; bool forcePlainLayout(idx_type = 0) const;
/// ///
bool needsCProtection(bool const maintext = false,
bool const fragile = false) const;
///
bool neverIndent() const { return true; } bool neverIndent() const { return true; }
/// ///
bool inheritFont() const { return false; } bool inheritFont() const { return false; }

View File

@ -458,7 +458,7 @@ void InsetText::latex(otexstream & os, OutputParams const & runparams) const
// FIXME UNICODE // FIXME UNICODE
// FIXME \protect should only be used for fragile // FIXME \protect should only be used for fragile
// commands, but we do not provide this information yet. // commands, but we do not provide this information yet.
if (hasCProtectContent()) if (hasCProtectContent(runparams.moving_arg))
os << "\\cprotect"; os << "\\cprotect";
else if (runparams.moving_arg) else if (runparams.moving_arg)
os << "\\protect"; os << "\\protect";
@ -762,13 +762,13 @@ ParagraphList & InsetText::paragraphs()
} }
bool InsetText::hasCProtectContent() const bool InsetText::hasCProtectContent(bool const fragile) const
{ {
ParagraphList const & pars = paragraphs(); ParagraphList const & pars = paragraphs();
pit_type pend = paragraphs().size(); pit_type pend = paragraphs().size();
for (pit_type pit = 0; pit != pend; ++pit) { for (pit_type pit = 0; pit != pend; ++pit) {
Paragraph const & par = pars[pit]; Paragraph const & par = pars[pit];
if (par.needsCProtection()) if (par.needsCProtection(fragile))
return true; return true;
} }
return false; 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 // Nested cprotect content needs \cprotect
// on each level // 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; return true;
if (!getLayout().needsCProtect()) if (!getLayout().needsCProtect())
@ -1111,7 +1116,7 @@ bool InsetText::needsCProtection(bool const maintext) const
for (pit_type pit = 0; pit != pend; ++pit) { for (pit_type pit = 0; pit != pend; ++pit) {
Paragraph const & par = pars[pit]; Paragraph const & par = pars[pit];
if (par.needsCProtection()) if (par.needsCProtection(fragile))
return true; return true;
docstring const pars = par.asString(); docstring const pars = par.asString();
for (int k = 0; k < nchars_escape; k++) { for (int k = 0; k < nchars_escape; k++) {

View File

@ -224,9 +224,10 @@ public:
bool confirmDeletion() const { return !text().empty(); } 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: protected:
/// ///

View File

@ -654,7 +654,7 @@ void parStartCommand(Paragraph const & par, otexstream & os,
{ {
switch (style.latextype) { switch (style.latextype) {
case LATEX_COMMAND: case LATEX_COMMAND:
if (par.needsCProtection()) if (par.needsCProtection(runparams.moving_arg))
os << "\\cprotect"; os << "\\cprotect";
os << '\\' << from_ascii(style.latexname()); os << '\\' << from_ascii(style.latexname());