LaTeX3 how to use content/value of predefined command in token list/string

expansionexpl3latex3stringstoken-lists

First of all, I guess that will be a very easy answer for people who are experienced in expl3. But for me its new and I'm very willing to learn that stuff to understand Latex3 better. So I hope for some pro help here.

What i want to achieve is the following:

First an userdefined command which has a simple sentence as content. Let's say \NewDocumentCommand{\testcommand}{}{A Test Sentence for expl3}

Now I want to store the content of the command in a token list or string. So that it can be printed/used or counted. The latter is needed, because I want to use the number of characters in an if-condition which activates different commands depending on the total count.

My MWE looks like this:

\documentclass[%
]{article}
\usepackage[T1]{fontenc}

\NewDocumentCommand{\testcommand}{}{A Test Sentence for expl3}

\ExplSyntaxOn
\tl_new:N \test_tl

\tl_set:Nn \test_tl {\testcommand}

\NewDocumentCommand{\showteststring}{}{
    \tl_use:N \test_tl \par
    \tl_count:N \test_tl
}

\NewDocumentCommand{\countteststring}{}{
    \tl_to_str:N \test_tl \par
    \str_count:N \test_tl
}
\ExplSyntaxOff

\begin{document}

    \showteststring
    
    \countteststring
    
\end{document}

\showteststring prints the content of \testcommand correctly using \tl_use:N, but \tl_count:N only counts one token; of course this token is \testcommand.

The same for the for \countteststring. It converts only the command-sequence \testcommand into a string and counts the 13 characters of the command-sequence itself.

So I need to expand \testcommand first. But my tries so far didn't offer any success. For instance, I tried:

\tl_set:Nx \test_tl {\testcommand} (with x) instead of \tl_set:Nn \test_tl {\testcommand}. It compiles fine, but the output remains the same.

I also tried some variants with \exp_args:N, but didn't get it to work, because I don't fully understand where to place it and which argument specifier to use in expl3 syntax.

I also thought about the v/V argument specifier, but couldn't get it to work.

I looked into the interface3 doc. But its overwhelming in case of informations and I couldn't figure out the right commands so far. Further, I searched Tex.SE and read the blog by Ziyue Xiang; also very informative, but not the specific solution I'm looking for (or, of course, I may have overlooked something).

Thus, I am already thankful in advance for any help or hint! For an explanation I would also be very grateful, so I understand it better next time!

Best Answer

You have declared \testcommand as a document command: these are protected from expansion. That means that \tl_set:Nx \l_test_tl { \testcommand } doesn't change the result. I would declare \testcommand as an expandable command and use V-type expansion:

\newcommand*\testcommand{A Test Sentence for expl3}
\tl_set:NV \l_test_tl \testcommand

etc.

Related Question