+
+bool InsetText::needsCProtection(bool const maintext, bool const fragile) const
+{
+ // Nested cprotect content needs \cprotect
+ // on each level
+ if (producesOutput() && hasCProtectContent(fragile))
+ return true;
+
+ // Environments generally need cprotection in fragile context
+ if (fragile && getLayout().latextype() == InsetLayout::ENVIRONMENT)
+ return true;
+
+ if (!getLayout().needsCProtect())
+ return false;
+
+ // Environments and "no latex" types (e.g., knitr chunks)
+ // need cprotection regardless the content
+ if (!maintext && getLayout().latextype() != InsetLayout::COMMAND)
+ return true;
+
+ // If the inset does not produce output (e.g. Note or Branch),
+ // we can ignore the contained paragraphs
+ if (!producesOutput())
+ return false;
+
+ // Commands need cprotection if they contain specific chars
+ int const nchars_escape = 9;
+ static char_type const chars_escape[nchars_escape] = {
+ '&', '_', '$', '%', '#', '^', '{', '}', '\\'};
+
+ ParagraphList const & pars = paragraphs();
+ pit_type pend = pit_type(paragraphs().size());
+
+ for (pit_type pit = 0; pit != pend; ++pit) {
+ Paragraph const & par = pars[size_type(pit)];
+ if (par.needsCProtection(fragile))
+ return true;
+ docstring const par_str = par.asString();
+ for (int k = 0; k < nchars_escape; k++) {
+ if (contains(par_str, chars_escape[k]))
+ return true;
+ }
+ }
+ return false;
+}
+