8
\documentclass{article}
\usepackage{xparse}

\DeclareDocumentCommand\TestA{>{\SplitArgument{1}{:}}m}{%
  \Example #1
}

\ExplSyntaxOn
\DeclareDocumentCommand\TestB{>{\SplitArgument{1}{:}}m}{
  \Example #1
}
\ExplSyntaxOff


\DeclareDocumentCommand\Example{mm}{%
  \begin{enumerate}
  \item #1
  \item #2
  \end{enumerate}
}

\begin{document}
\TestA{one : two}
\TestB{one : two}
\end{document}

output

4
  • well it works but it is splitting on a letter colon which you don't have in the main part of the document, you want a non-letter (catcode 12) colon Commented Aug 21, 2014 at 20:28
  • Don't use \ExplSyntaxOn; that's all.
    – egreg
    Commented Aug 21, 2014 at 20:34
  • @egreg Unfortunately this example is very minimal; I've already got two levels of indirection with these arguments :) Commented Aug 21, 2014 at 20:41
  • @DavidCarlisle I thought as much. I even had a guess at the problem in the draft, but I opted to nix it because I'm still pretty sure I barely know what I'm talking about :) I suppose this isn't fixable without introducing another layer of pass-the-buck? Is there a way to specify the category code as \SplitArgument sees it? Commented Aug 21, 2014 at 20:42

1 Answer 1

7

A way for coping with this is to use the celebrated \lowercase trick (but note that it uses a \tex_...:D function, so it should be avoided; if possible, opt for the second version):

\ExplSyntaxOn

\group_begin:
\char_set_lccode:nn { `? } { `: }
\tex_lowercase:D {
  \group_end:
  \NewDocumentCommand\TestB{>{\SplitArgument{1}{?}}m}
}{
  \Example #1
 }

\ExplSyntaxOff

Another way is using the \begingroup\edef\x trick:

\ExplSyntaxOn

\group_begin:
\use:x{
  \group_end:
  \NewDocumentCommand\exp_not:N\TestB{>{\SplitArgument{1}{\tl_to_str:n { : } }}m}
}{
  \Example #1
 }

\ExplSyntaxOff

Full example

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\group_begin:
\char_set_lccode:nn { `? } { `: }
\tex_lowercase:D {
  \group_end:
  \NewDocumentCommand\TestA{>{\SplitArgument{1}{?}}m}
}{
  \Example #1
 }

\group_begin:
\use:x{
  \group_end:
  \NewDocumentCommand\exp_not:N\TestB{>{\SplitArgument{1}{\tl_to_str:n { : } }}m}
}{
  \Example #1
 }

\ExplSyntaxOff

\DeclareDocumentCommand\Example{mm}{%
  \begin{enumerate}
  \item #1
  \item #2
  \end{enumerate}
}

\begin{document}
\TestA{one : two}
\TestB{one : two}
\end{document}

enter image description here

Note that it makes no sense to use \DeclareExpandableDocumentCommand if an argument is processed with \SplitArgument.

The problem presents also for the underscore, but this is a bit harder, because _ usually has category code 8.

\ExplSyntaxOn

\group_begin:
\char_set_lccode:nn { `? } { `: }
\char_set_catcode_math_subscript:n { `? }
\tex_lowercase:D {
  \group_end:
  \NewDocumentCommand\TestB{>{\SplitArgument{1}{?}}m}
}{
  <code for the definition
 }

\ExplSyntaxOff
3
  • Accepting to clean up my questions, but I'd like to note that I think this case should be handled in xparse in a perfect world. Commented Sep 19, 2014 at 16:57
  • @SeanAllred Raise the question on the LaTeX3 mailing list. The problem holds also for _. Maybe the argument to \SplitArgument can be “normalized” with the help of \tl_replace_all:Nnn
    – egreg
    Commented Sep 19, 2014 at 17:08
  • That was also my thought---there are a lot of tools in expl3 now that could be used to effect this. I'll raise it tonight if I can; I just felt like I needed to note this here. Not sure why. (I'm going through old, unaccepted questions of mine.) Commented Sep 19, 2014 at 17:10

You must log in to answer this question.

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