]> git.lyx.org Git - features.git/commitdiff
Add basic support for cprotect
authorJuergen Spitzmueller <spitz@lyx.org>
Fri, 13 Apr 2018 15:46:37 +0000 (17:46 +0200)
committerJuergen Spitzmueller <spitz@lyx.org>
Fri, 13 Apr 2018 15:46:37 +0000 (17:46 +0200)
This allows (some) verbatim contents in macros, such as \url's with
specific chars (#, % etc.) in section headings or footnotes (#449)
or comments in captions (#9313).

The mentioned two bugs are fixed by this commit.

Note that the implementation is still rather basic and might need
extension for other cases.

13 files changed:
lib/chkconfig.ltx
lib/doc/Customization.lyx
lib/doc/LaTeXConfig.lyx
lib/layouts/stdinsets.inc
src/LaTeXFeatures.cpp
src/Paragraph.cpp
src/Paragraph.h
src/insets/Inset.h
src/insets/InsetLayout.cpp
src/insets/InsetLayout.h
src/insets/InsetText.cpp
src/insets/InsetText.h
src/output_latex.cpp

index e4ba2edce82db07773fa1c876a8e83d78137a517..a3e3518859ec5dea14fb94224625dc4ca3e07289 100644 (file)
 \TestPackage{chicago}
 \TestPackage{color} % this one should be there if graphics.sty is there.
 \TestPackage{covington}
+\TestPackage{cprotect}
 \TestPackage{csquotes}
 \TestPackage[koi8-r.def]{cyrillic}
 \TestPackage{dvipost}
index 7b81ff850e36b15e06499e2627c353252fb9bbb6..ab1092e8cb120d14edf5af46d4deb2afccba20ec 100644 (file)
@@ -19663,6 +19663,79 @@ protect
 not
 \emph default
  whether the command should itself be protected.) Default is false.
+\change_inserted -712698321 1523633958
+
+\end_layout
+
+\begin_layout Description
+
+\change_inserted -712698321 1523634088
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1523633961
+NeedCProtect
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1523633958
+
+\emph on
+0
+\end_layout
+
+\end_inset
+
+,
+\begin_inset space \thinspace{}
+\end_inset
+
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1523633958
+1
+\end_layout
+
+\end_inset
+
+] This causes macros that contain this inset to be protected with 
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1523634038
+
+\backslash
+cprotect
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ (cf.
+ package 
+\family sans
+cprotect
+\family default
+) if necessary and thus allows (some) verbatim stuff in macros.
+ Default is false.
+\change_unchanged
+
 \end_layout
 
 \begin_layout Description
index 2fbba56ab9699c1d9e138c26d8d95253a1c78191..fc71a6c3bcdefd12a0431206d3dc7f38d271b8fc 100644 (file)
@@ -7069,6 +7069,34 @@ cancelto
 .
 \end_layout
 
+\begin_layout Subsection
+cprotect
+\end_layout
+
+\begin_layout Description
+Found: 
+\begin_inset Info
+type  "package"
+arg   "cprotect"
+\end_inset
+
+
+\end_layout
+
+\begin_layout Description
+CTAN: 
+\family typewriter
+macros/latex/contrib/cprotect/
+\end_layout
+
+\begin_layout Description
+Notes: The package 
+\family sans
+cprotect
+\family default
+ is used to allow (some) verbatim stuff in macros.
+\end_layout
+
 \begin_layout Subsection
 CJKutf8
 \end_layout
index b66b1caee2716e22c108372151fdfd2d19de8352..31f53c585adac3f56733adcf2b893dfdabf92282 100644 (file)
@@ -150,6 +150,7 @@ InsetLayout Note:Comment
        EndHTMLStyle
        AddToToc              note
        IsTocCaption          true
+       NeedCProtect          true
 End
 
 
@@ -552,6 +553,7 @@ InsetLayout "Flex:URL"
        PassThru              true
        FreeSpacing           true
        ForceLTR              true
+       NeedCProtect          true
        Font
          Family              Typewriter
          Color               urltext
index 85f3009eedf8af281c07e1215909bbd5e4115ff8..146fddb2178643500a54c67948e853ba62d03360 100644 (file)
@@ -908,6 +908,7 @@ char const * simplefeatures[] = {
 // note that the package order here will be the same in the LaTeX-output
        "array",
        "verbatim",
+       "cprotect",
        "longtable",
        "rotating",
        "latexsym",
index 56741ad20fb787e55da45ce75d55f8505021cada..b7ce543cafc3f2e41211350a5a23c960a12de1e1 100644 (file)
@@ -1694,6 +1694,8 @@ void Paragraph::write(ostream & os, BufferParams const & bparams,
 void Paragraph::validate(LaTeXFeatures & features) const
 {
        d->validate(features);
+       if (needsCProtection())
+               features.require("cprotect");
 }
 
 
@@ -3376,6 +3378,17 @@ bool Paragraph::isHardHyphenOrApostrophe(pos_type pos) const
 }
 
 
+bool Paragraph::needsCProtection() const
+{
+       pos_type size = d->text_.size();
+       for (pos_type i = 0; i < size; ++i)
+               if (isInset(i))
+                       return getInset(i)->needsCProtection();
+
+       return false;
+}
+
+
 FontSpan const & Paragraph::getSpellRange(pos_type pos) const
 {
        return d->speller_state_.getRange(pos);
index 84fcf759e225b8e70a18b0fce9e5626a5b26ee82..2a308d6efaa1557ace5af9648fd8804c50da11a4 100644 (file)
@@ -424,6 +424,9 @@ public:
        /// True if the element at this point is a hard hyphen or a apostrophe
        /// If it is enclosed by spaces return false
        bool isHardHyphenOrApostrophe(pos_type pos) const;
+       /// Return true if this paragraph has verbatim content that needs to be
+       /// protected by \cprotect
+       bool needsCProtection() 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)
index ecd171dc45de302844373c860c378171d198f662..f6df439b3b46a861d279f71079cdeb1c22188921 100644 (file)
@@ -594,6 +594,9 @@ public:
        /// reject the changes within the inset
        virtual void rejectChanges() {}
 
+       ///
+       virtual bool needsCProtection() const { return false; }
+
        ///
        virtual ColorCode backgroundColor(PainterInfo const &) const;
        ///
index 621e784174c5f605953201a2ea100039fa9b8fce..ef8e7d3f66fea3e7c97e2257ef6001cbd738fa00 100644 (file)
@@ -42,8 +42,8 @@ InsetLayout::InsetLayout() :
        htmlisblock_(true), multipar_(true), custompars_(true),
        forceplain_(false), passthru_(false), parbreakisnewline_(false),
        freespacing_(false), keepempty_(false), forceltr_(false),
-       forceownlines_(false), needprotect_(false), intoc_(false),
-       spellcheck_(true), resetsfont_(false), display_(true),
+       forceownlines_(false), needprotect_(false), needcprotect_(false),
+       intoc_(false), spellcheck_(true), resetsfont_(false), display_(true),
        forcelocalfontswitch_(false), add_to_toc_(false), is_toc_caption_(false)
 {
        labelfont_.setColor(Color_error);
@@ -119,6 +119,7 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass)
                IL_OBSOLETEDBY,
                IL_KEEPEMPTY,
                IL_MULTIPAR,
+               IL_NEEDCPROTECT,
                IL_NEEDPROTECT,
                IL_PASSTHRU,
                IL_PASSTHRU_CHARS,
@@ -174,6 +175,7 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass)
                { "leftdelim", IL_LEFTDELIM },
                { "lyxtype", IL_LYXTYPE },
                { "multipar", IL_MULTIPAR },
+               { "needcprotect", IL_NEEDCPROTECT },
                { "needprotect", IL_NEEDPROTECT },
                { "obsoletedby", IL_OBSOLETEDBY },
                { "parbreakisnewline", IL_PARBREAKISNEWLINE },
@@ -322,6 +324,9 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass)
                case IL_NEEDPROTECT:
                        lex >> needprotect_;
                        break;
+               case IL_NEEDCPROTECT:
+                       lex >> needcprotect_;
+                       break;
                case IL_CONTENTASLABEL:
                        lex >> contentaslabel_;
                        break;
index c4a12a4018a9e17eaee309c0b4676ba08ed7afe1..b48ea7c2902238768d8fee0aa64c0fff0a3c834d 100644 (file)
@@ -162,6 +162,8 @@ public:
        ///
        bool isNeedProtect() const { return needprotect_; }
        ///
+       bool needsCProtect() const { return needcprotect_; }
+       ///
        bool isFreeSpacing() const { return freespacing_; }
        ///
        bool isKeepEmpty() const { return keepempty_; }
@@ -283,6 +285,8 @@ private:
        bool forceownlines_;
        ///
        bool needprotect_;
+       ///
+       bool needcprotect_;
        /// should the contents be written to TOC strings?
        bool intoc_;
        /// check spelling of this inset?
index b19b3841ae6689ea0776c2dffd66ab172aec976e..4c560f492c7314d9297075e6005ea541fcedd3bf 100644 (file)
@@ -458,7 +458,9 @@ 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 (runparams.moving_arg)
+                       if (hasCProtectContent())
+                               os << "\\cprotect";
+                       else if (runparams.moving_arg)
                                os << "\\protect";
                        os << '\\' << from_utf8(il.latexname());
                        if (!il.latexargs().empty())
@@ -760,6 +762,19 @@ ParagraphList & InsetText::paragraphs()
 }
 
 
+bool InsetText::hasCProtectContent() 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())
+                       return true;
+       }
+       return false;
+}
+
+
 bool InsetText::insetAllowed(InsetCode code) const
 {
        switch (code) {
@@ -1070,4 +1085,35 @@ InsetText::XHTMLOptions operator|(InsetText::XHTMLOptions a1, InsetText::XHTMLOp
        return static_cast<InsetText::XHTMLOptions>((int)a1 | (int)a2);
 }
 
+
+bool InsetText::needsCProtection() const
+{
+       if (!getLayout().needsCProtect())
+               return false;
+
+       // Environments need cprotection regardless the content
+       if (getLayout().latextype() == InsetLayout::ENVIRONMENT)
+               return true;
+
+       // 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 = paragraphs().size();
+
+       for (pit_type pit = 0; pit != pend; ++pit) {
+               Paragraph const & par = pars[pit];
+               if (par.needsCProtection())
+                       return true;
+               docstring const pars = par.asString();
+               for (int k = 0; k < nchars_escape; k++) {
+                       if (contains(pars, chars_escape[k]))
+                               return true;
+               }
+       }
+       return false;
+}
+
 } // namespace lyx
index eea88cdd690786ac9fddfaaa127872159b4c9180..537c8bbfb5e831a171fd305ac4c5c82cc05aebde 100644 (file)
@@ -223,6 +223,9 @@ public:
        ///
        bool confirmDeletion() const { return !text().empty(); }
 
+       ///
+       bool needsCProtection() const;
+
 protected:
        ///
        void iterateForToc(DocIterator const & cdit, bool output_active,
@@ -238,6 +241,8 @@ private:
        void closeAddToTocForParagraph(pit_type start, pit_type end,
                                       TocBackend & backend) const;
        ///
+       bool hasCProtectContent() const;
+       ///
        bool drawFrame_;
        ///
        ColorCode frame_color_;
index c91c06981aa5af9a8a2e2a4bb81502a114d37de7..f8da22ca5c598b5901bc875892420220e6b68389 100644 (file)
@@ -654,6 +654,8 @@ void parStartCommand(Paragraph const & par, otexstream & os,
 {
        switch (style.latextype) {
        case LATEX_COMMAND:
+               if (par.needsCProtection())
+                       os << "\\cprotect";
                os << '\\' << from_ascii(style.latexname());
 
                // Command arguments