3

I'm trying my hand at expl3 for the first time right now, and while tinkering I ran into an error that I cannot wrap my head around: Every time I try to use the result of a tl_use or a clist_item as the second argument to \colorlet from xcolor something breaks completely.

Concretely, here's a small example:

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn
\tl_new:N \l__color_dummy_tl

\cs_new:Npn \passcolorthrough #1 {
    \tl_set:Nn \l__color_dummy_tl {#1}
    \tl_use:N \l__color_dummy_tl
}
\ExplSyntaxOff

\colorlet{mycolor}{\passcolorthrough{black}} % <- Error's here

\begin{document}
:(
\end{document}

Compiling this with a recent TexLive version yields the following error:

Runaway argument?
\XC@func >\@nnil \edef \@@tmp {{\@@mod }{\@@clr }}\aftergroupdef \@@clr \ETC.
! Paragraph ended before \XC@split@iv was complete.
<to be read again> 
                   \par 
l.14 
     
I suspect you've forgotten a `}', causing me to apply this
control sequence to too much text.

I haven't been able to make heads or tails of this. Replacing \l__color_dummy_tl with a clist and \tl_use with \clist_item yields the same error.

What's the issue here, and how do I avoid it?

6
  • 3
    the arguments to \colorlet have to expand to a color. \tl_set:Nn is \def and not expandable Commented Aug 4 at 23:53
  • 1
    you would see the same with \colorlet{mycolor}{\newcommand\tmp{black}\tmp} it isn't related to expl3 Commented Aug 4 at 23:55
  • Sorry, but the example is completely unrealistic. It would be better if you explain the real problem you want to solve.
    – egreg
    Commented Aug 5 at 10:18
  • @egreg Fine. The real problem I wan to solve is that I want to store and pass lists of color names ("color schemes" if you want) between class and package boundaries. So replace \l__color_dummy_tl above by a seq or clist and the appropriate accessors, and you basically have my use case. (I'm not going to edit the question now since there's an answer already.) Commented Aug 5 at 12:00
  • @DavidCarlisle Thank you, that answers at least half of my question! Commented Aug 5 at 12:05

2 Answers 2

2

The second argument of \colorlet has to expand to a color. Any command using assignments such as \tl_set:Nn (which is \def, more or less) is not expandable.

So the canonical expandable passthrough would be

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn
\tl_new:N \l__color_dummy_tl

\cs_new:Npn \passcolorthrough #1 {
 #1
}
\ExplSyntaxOff

\colorlet{mycolor}{\passcolorthrough{black}} % <- Error's here

\begin{document}
:)
\end{document}

You could use more complicated definitions as long as you stick to expandable commands (texdoc interface3 marks all expandable commands with a *)

2

Do you want to do some processing on the second parameter black instead of using \colorlet{mycolor}{black} directly? Is it possible to use the following method to achieve your purpose?

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn
\tl_new:N \l__color_dummy_tl

\cs_new:Npn \mycolorlet #1#2 {
  \tl_set:Nn \l__color_dummy_tl {#2}
  % some process for \l__color_dummy_tl
  \tl_set:Nx \l__color_dummy_tl {\l__color_dummy_tl !50! red}
  \exp_args:NnV \colorlet{#1}\l__color_dummy_tl
}
\ExplSyntaxOff

\mycolorlet{mycolor}{black} % <- Error's here

\begin{document}
:(
\textcolor{mycolor}{xxxx}
\end{document}

enter image description here

6
  • This is nice, but it doesn't answer my question. The answer to both of your questions is "no." That's not what I'm trying to do. Commented Aug 5 at 12:01
  • What is missing?
    – projetmbc
    Commented Aug 5 at 12:50
  • 1
    @projetmbc An answer to my question "What's the issue here, and how do I avoid it?" I asked about a specific issue; this answer is taking a guess at what I was "actually" trying to do and answers that instead, and in the process misses completely. Commented Aug 5 at 14:11
  • 1
    @BenSteffan but I answered the question (in a comment) and you said there that it only answers half the question. I have no idea what the other half of the question is, you need to edit the question or perhaps ask a new one. Specifically you posted some code that gives an error, It is clear why it errors but you leave us to guess what the code was intended to do. Commented Aug 7 at 14:28
  • 1
    @BenSteffan "how to avoid it" is simply "don't do that" In order to give a more constructive answer you'd need to give some information about what the code was intended to do, I can't guess, sorry, and apparently the answer here is a wrong guess as well. Commented Aug 7 at 14:55

You must log in to answer this question.

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