5

I'm trying to use collcell.sty with xparse. If I have macro with an optional argument, using it with collcell.sty does not seem to pick up the optional argument. For example:

\documentclass{article}

\usepackage{xparse}
\usepackage{xcolor}
\usepackage{collcell}

\DeclareDocumentCommand\coloritt{omm}{%
    \IfNoValueTF{#3}{#2}{#2\textcolor{#1}{#3}}%
}

\DeclareDocumentCommand{\foo}%
    {O{blue}>{\SplitArgument{1}{-}}m}
    {\coloritt[#1]#2}

\newcolumntype{L}{>{\collectcell\foo}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{lL}
    Something&Some-thing\\
    Ask&[red]Ask-ing\\ %% <<-- Does not work
    NULL&NULL
\end{tabular}

\foo[red]{abcd-efgh} %% <<-- Does work.

\end{document}

Collcell and xparse example

What am I doing wrong?

sgmoye
  • 8,586

2 Answers2

3

The collcell package wrapps up the collected cell in braces, so you end up with for example

\foo{[red]Ask-ing}

rather than

\foo[red]{Ask-ing}

Indeed, for the latter case you have to find a way of adding the braces yourself. Just using xparse you might end up with

\documentclass{article}

\usepackage{xparse}
\usepackage{xcolor}
\usepackage{collcell}

\DeclareDocumentCommand\coloritt{omm}{%
    \IfNoValueTF{#3}{#2}{#2\textcolor{#1}{#3}}%
}

\DeclareDocumentCommand{\foo}{m}{\fooa#1\stop}
\DeclareDocumentCommand{\fooa}
    {O{blue}>{\SplitArgument{1}{-}}u{\stop}}
    {\coloritt[#1]#2}

\newcolumntype{L}{>{\collectcell\foo}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{lL}
    Something&Some-thing\\
    Ask&[red]Ask-ing\\ %% <<-- Does not work
    NULL&NULL
\end{tabular}

\end{document}

but ideally you'd separate out the document mark up from the processing. (This is clearly an edge case: are we doing programming or not here!)

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • Beat me by a few seconds. ;-) – egreg May 06 '15 at 12:50
  • Thank you very much -- that enables me to fill in a missing piece in my answer to this question: http://tex.stackexchange.com/questions/242279/automatically-colour-previously-defined-strings-of-text/242292#242292. – sgmoye May 06 '15 at 13:37
1

Two different approaches; the first uses standard expl3 constructs, the second one uses regular expressions.

First

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

\NewDocumentCommand{\coloritt}{O{blue}mo}{%
  \IfNoValueTF{#3}{#2}{#2\textcolor{#1}{#3}}%
}

\ExplSyntaxOn
\NewDocumentCommand{\processcell}{m}
 {
  \sgmoye_processcell:n { #1 }
 }

\tl_new:N \l_sgmoye_processcell_oargi_tl
\tl_new:N \l_sgmoye_processcell_oargii_tl
\tl_new:N \l_sgmoye_processcell_marg_tl
\seq_new:N \l_sgmoye_processcell_text_seq

\cs_new_protected:Npn \sgmoye_processcell:n #1
 {
  \tl_clear:N \l_sgmoye_processcell_oargi_tl
  \tl_clear:N \l_sgmoye_processcell_oargii_tl
  \tl_clear:N \l_sgmoye_processcell_marg_tl
  \seq_set_split:Nnn \l_sgmoye_processcell_text_seq { ] } { #1 }
  \int_compare:nTF { \seq_count:N \l_sgmoye_processcell_text_seq == 1 }
   { % no initial optional argument
    \__sgmoye_other_args:n { #1 }
   }
   {
    \tl_set:Nx \l_sgmoye_processcell_oargi_tl
     {
      \seq_item:Nn \l_sgmoye_processcell_text_seq { 1 } ] % reinstate the ]
     }
    \tl_set:Nx \l_sgmoye_processcell_marg_tl
     {
      \seq_item:Nn \l_sgmoye_processcell_text_seq { 2 }
     }
    \__sgmoye_other_args:V \l_sgmoye_processcell_marg_tl
   }
  \use:x
   {
    \coloritt
    \exp_not:V \l_sgmoye_processcell_oargi_tl
    \exp_not:V \l_sgmoye_processcell_marg_tl
    \exp_not:V \l_sgmoye_processcell_oargii_tl
   }
 }

\cs_new_protected:Npn \__sgmoye_other_args:n #1
 {
  \seq_set_split:Nnn \l_sgmoye_processcell_text_seq { - } { #1 }
  \int_compare:nTF { \seq_count:N \l_sgmoye_processcell_text_seq == 1 }
   { % no -
    \tl_set:Nn \l_sgmoye_processcell_marg_tl { { #1 } }
   }
   {
    \tl_set:Nx \l_sgmoye_processcell_marg_tl
     {
      { \seq_item:Nn \l_sgmoye_processcell_text_seq { 1 } }
     }
    \tl_set:Nx \l_sgmoye_processcell_oargii_tl
     {
      [ \seq_item:Nn \l_sgmoye_processcell_text_seq { 2 } ]
     }
   }
 }
\cs_generate_variant:Nn \__sgmoye_other_args:n { V }
\ExplSyntaxOff

\newcolumntype{L}{>{\collectcell\processcell}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{lL}
    Something&Some-thing\\
    Ask&[red]Ask-ing\\ %% <<-- Does not work
    NULL&NULL
\end{tabular}

\end{document}

Second

\documentclass{article}
\usepackage{collcell,xparse,l3regex,xcolor}

\NewDocumentCommand{\coloritt}{O{blue}mo}{%
  \IfNoValueTF{#3}{#2}{#2\textcolor{#1}{#3}}%
}

\ExplSyntaxOn
\NewDocumentCommand{\processcell}{m}
 {
  \sgmoye_processcell:n { #1 }
 }

\tl_new:N \l_sgmoye_processcell_oarg_tl
\tl_new:N \l_sgmoye_processcell_marg_tl
\seq_new:N \l_sgmoye_processcell_text_seq

\cs_new_protected:Npn \sgmoye_processcell:n #1
 {
  \tl_clear:N \l_sgmoye_processcell_oarg_tl
  \regex_match:nnTF { \A \[ } { #1 }
   {% there is an optional argument: split the two parts
    \regex_extract_once:nnN { \A (\[.*\]) (.*) \Z } { #1 } \l_sgmoye_processcell_text_seq
    \tl_set:Nx \l_sgmoye_processcell_oarg_tl
     {
      \seq_item:Nn \l_sgmoye_processcell_text_seq { 2 }
     }
    \tl_set:Nx \l_sgmoye_processcell_marg_tl
     {
      \seq_item:Nn \l_sgmoye_processcell_text_seq { 3 }
     }
   }
   {
    \tl_set:Nn \l_sgmoye_processcell_marg_tl { #1 }
   }
  \regex_match:nVTF { \- } \l_sgmoye_processcell_marg_tl
   {
    \regex_replace_once:nnN { \A (.*) \- (.*) \Z } { \cB\{\1\cE\}[\2] } \l_sgmoye_processcell_marg_tl
   }
   {
    \tl_set:Nx \l_sgmoye_processcell_marg_tl
     {
      { \exp_not:V \l_sgmoye_processcell_marg_tl }
     }
   }
  \use:x
   {
    \coloritt
    \exp_not:V \l_sgmoye_processcell_oarg_tl
    \exp_not:V \l_sgmoye_processcell_marg_tl
   }
 }
\cs_generate_variant:Nn \regex_match:nnTF { nV }
\ExplSyntaxOff

\newcolumntype{L}{>{\collectcell\processcell}l<{\endcollectcell}}

\begin{document}

\begin{tabular}{lL}
    Something&Some-thing\\
    Ask&[red]Ask-ing\\
    NULL&NULL
\end{tabular}

\end{document}

Output for both

enter image description here

egreg
  • 1,121,712