3

I want to extract a set of n characters stored in a macro like this:

\def\foo{bar}
\extract{\foo}{1}

prints: b using expl3.

I have the following code:

\DeclareExpandableDocumentCommand{\extract}{mm}{%
  \tl_item:nn { #1 } { #2 }%
}

which works on a literal string: \extract{foo}{2} prints fo, but it does not work when using a macro. More specifically, a string stored in pgfkeys.

The final result should be fully expanded and not something that will most likely give the desired character (see: xstring package).

Full MWE:

\documentclass{article}

\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\extract}{mm}{%
  Extracted: \tl_item:nn { #1 } { #2 }%
}
\ExplSyntaxOff

\begin{document}

\extract{foo}{2}     % output: fo as expected

\def\foo{bar}

\extract{\foo}{2}    % output: nothing

\pgfkeys{/foo/.is family,
     /foo/.unknown/.style = %
     {\pgfkeyscurrentpath/\pgfkeyscurrentname/%
     .initial = #1}}
\pgfkeys{/foo/bar = some text here}

\pgfkeysvalueof{/foo/bar}

\extract{\pgfkeysvalueof{/foo/bar}}{2} % output: /foo/bar

\end{document}
0
2
\ExplSyntaxOn

\cs_generate_variant:Nn \tl_item:nn { f }

\DeclareExpandableDocumentCommand \extract { m m }
 {
  Extracted: ~ \tl_item:fn { #1 } { #2 }
 }

\ExplSyntaxOff
2
  • By the way, in an ideal world \tl_item:xn would be expandable (and it's already possible in LuaTeX), but for now :fn should be enough. In any case I would like to see what will be the future of expansion with LaTeX3.
    – Manuel
    Nov 24 '17 at 1:30
  • xinttools's \xintNthEltNoExpand is expandable.\xintNthEltNoExpand{2}{\pgfkeysvalueof{/foo/bar}}. (expands in two steps to the second item /foo/bar)
    – user4686
    Nov 25 '17 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.