diff options
Diffstat (limited to 'macros/latex/contrib/cprotectinside/cprotectinside.sty')
-rw-r--r-- | macros/latex/contrib/cprotectinside/cprotectinside.sty | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/macros/latex/contrib/cprotectinside/cprotectinside.sty b/macros/latex/contrib/cprotectinside/cprotectinside.sty new file mode 100644 index 0000000000..53afd0beb1 --- /dev/null +++ b/macros/latex/contrib/cprotectinside/cprotectinside.sty @@ -0,0 +1,78 @@ +% File: cprotectinside.sty +% Copyright 2022 user202729 +% +% This work may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this license or +% (at your option) any later version. The latest version of this license is in +% the file: +% +% http://www.latex-project.org/lppl.txt +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is user202729. + +\ProvidesExplPackage{cprotectinside}{2022/06/25}{0.0.0}{Use cprotect arbitrarily deeply nested} + +% '__' ↔ '_cpi_' + +\msg_new:nnn {cprotectinside} {delimiter-not-match} {Delimiters~does~not~match!} + +\int_new:N \_cpi_used + +\edef \cprotectinsideAppend { \c_backslash_str empty } +% 12 is other catcode + +\cs_generate_variant:Nn \tl_replace_all:Nnn {Nnx} + +% #1: single character for the delimiter e.g. '+' +% #2: the body + + +\NewDocumentCommand\cprotectinside{v +v}{ + + %\seq_set_split_keep_spaces:Nnn \_cpi_entries {#1} {#2} + % cannot do this in old version + + \tl_set:Nn \_cpi_entries {#2} + \tl_replace_all:Nnx \_cpi_entries {~} { \char_generate:nn {`\ } {12} } % replace space <space> with other <space> + \seq_set_split:NnV \_cpi_entries {#1} \_cpi_entries % so that they're not lost here. Support older versions without \seq_set_split_keep_spaces + + \int_if_even:nT {\seq_count:N \_cpi_entries} { + \msg_error:nn {cprotectinside} {delimiter-not-match} + } + \tl_build_gbegin:N \_cpi_result + \seq_map_indexed_inline:Nn \_cpi_entries { + % ##1 is index, ##2 is item + \int_if_even:nTF {##1} { + % index 2, 4, 6...: content to be cprotect-ed + \int_incr:N \_cpi_used + \exp_args:NV \_cpi_aux:nn \cprotectinsideAppend {##2} + \tl_build_gput_right:Nx \_cpi_result { \c_backslash_str cpiContentA \romannumeral \_cpi_used / } + + } { + % index 1, 3, 5...: normal text + \tl_build_gput_right:Nn \_cpi_result {##2} + } + } + %\tl_build_gput_right:Nn \_cpi_result {##2} + \tl_build_gend:N \_cpi_result + \begingroup + \newlinechar=13~ % have to setup like this because +v collect newline as char 13 + \exp_args:NNNV \expandafter \endgroup \scantokens \_cpi_result +} + +\def \_cpi_aux:nn #1 #2 { + \protected \cs_set_protected:cpn {cpiContentA \romannumeral \_cpi_used} / {\cprotectinsideReexec{#2 #1}} +} + +\def \cprotectinsideReexec #1 { + \begingroup + \newlinechar=13~ + \expandafter % expand the \scantokens once when newlinechar=13 + \endgroup + \scantokens {#1} % then execute the code with original newlinechar value +} + +\cs_generate_variant:Nn \_cpi_aux:n {V} +\cs_generate_variant:Nn \tl_gset_rescan:Nnn {NnV} |