0

I want to automatically skip punctuation when coloring text. At present, my solution is to color the text manually, but it is not elegant for a long article with more punctuation.I don't need all the words to be red, but all kinds of colors are possible .

\documentclass{article}
\usepackage{xcolor}
\begin{document}
    
    {\color{red}{This is a text}}, {\color{red}{this is a text}}, {\color{red}{this is a text}}! {\color{red}{This is a text}}, {\color{red}{this is a text}}.
    
\end{document}


enter image description here

2 Answers 2

2

An expl3 regex regular expression can do punctuation.

Here, inside a dedicated coloured environment:

black punctuation

MWE

\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn



\NewDocumentEnvironment { punct }  { o +b } {
    \IfNoValueTF {#1}
         {      
                \color{red}
        }
     {      
                \color{#1}
        }
        \tl_set:Nn
                    \l_tmpa_tl
                    { #2 }
\regex_replace_all:nnN 
            { [[:punct:]] } % POSIX punctuation set
            { 
                    \cB\{ \c{color}\cB\{ black \cE\} \0 \cE\} 
                    } 
            \l_tmpa_tl
            
        \tl_use:N
                    \l_tmpa_tl
}{}

\ExplSyntaxOff


\begin{document}
Outside environment:

This is a text, this is a text, this is a text! This is a text, this is a text.

\begin{punct}
Inside environment:

This is a text, this is a text, this is a text! This is a text, this is a text.

\end{punct}

\begin{punct}[blue]
Inside environment:

This is a text, this is a text, this is a text! This is a text, this is a text.

\end{punct}

\end{document}


If you have commands mixed in with the text, the situation becomes more complex.

Example case: With free-form colour and formatting, and \, { and } not counting as punctuation:

text and commands

MWE

\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn



\NewDocumentEnvironment { punct }  { +b } {
        \tl_set:Nn
                    \l_tmpa_tl
                    { #1 }

\regex_replace_all:nnN 
            { [\.\,\;\:\!\?] } % 
            { 
                    \cB\{ \c{color}\cB\{ black \cE\} \0 \cE\} 
                    } 
            \l_tmpa_tl
            
        \tl_use:N
                    \l_tmpa_tl
}{}

\ExplSyntaxOff

\newcommand\test{\color{red}This is a text, this \color{green} is a text, this is a text! This \color{brown} \textit{is a text, this} is a text.}

\begin{document}
Outside environment:

\color{red}This is a text, this \color{green} is a text, this is a text! This \color{brown} \textit{is a text, this} is a text.

\begin{punct}
Inside environment:


\color{red}This is a text, this \color{green} is a text, this is a text! This \color{brown} \textit{is a text, this} is a text.

\end{punct}


\end{document}

3
  • Thank you very much for your help
    – eric
    Mar 22, 2022 at 12:28
  • Is there a logic in the code indentation? ;-)
    – egreg
    Mar 23, 2022 at 8:18
  • @egreg Consequence of cold 2am ;-). Practically, to minimize copy-paste keystroke operations. Semantically, wanted to show the parent-child relationship between functions and parameters, but too many stray tabs and spaces across editors.
    – Cicada
    Mar 24, 2022 at 9:34
2

You could make the punctuation active and define it to be black, but I wouldn't: something is bound to break.

The markup can be greatly simplified if instead of making each text run red, you make everything red then just locally set the punctuation in black.

\documentclass{article}
\usepackage{xcolor}
\newcommand\B{\textcolor{black}}
\begin{document}
    
{\color{red}
This is a text\B, this is a text\B, this is a text\B! This is a text\B, this is a text\B.

}
    
\end{document}
7
  • Thank you for your help, but it's still not very convenient. I don't need all the words to be red, but all kinds of colors are possible
    – eric
    Mar 22, 2022 at 9:07
  • I think that's really the simplest solution: Color your text any way you want, then do a final search & replace for your punctuation marks and color them black.
    – Ingmar
    Mar 22, 2022 at 9:10
  • @eric if you are needing to separately mark each text run anyway leaving the commas out as in your original seems fine. You can of course do both, use the form you have where it makes sense and use a nested switch if that is more convenient. You could do \catcode`\,=\active \def,{\texcolor{black}{\string,}} to make comma active and self-black, but as I say this is bound to be incompatible with something. Mar 22, 2022 at 9:10
  • @David Carlisle Could you provide the same sample? I know nothing about catcode
    – eric
    Mar 22, 2022 at 9:18
  • just put exactly that code after \color{red} then omit the \B before , but I won't add it to the answer as I am explicitly not recommending that (and people copy code from answers wihout reading the text that says not to do it) Mar 22, 2022 at 9:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .