I quite often come into a situation, where I need to obtain some text produced by a package macro as a string, like in say:
One thing I bump into here, is trying to \typeout
the macros in question, and typically observing a space between the \command
and its arguments (hence the title); and I'd usually take this wrongly as a string parsing problem (as in, how do I remove the space between the command and its arguments), and spend quite a bit of time in a pointless battle :)
EDIT: to clarify this:
- In the 1st link:
\lipsum[1]
command typesets "Lorem Ipsum..." in the PDF document; one would want to somehow obtain the characters for "Lorem Ipsum..." in a\temp
command, such that\typeout{\temp}
would print "Lorem Ipsum ..." to the terminal and log output. - In the 2nd link:
\today
fromisodate
typesets "24 May, 2012" in the PDF document; likewise, one would want to somehow obtain the characters for "24 May, 2012" in a\temp
command, such that\typeout{\temp}
would print "24 May, 2012" to the terminal and log output.
(whether \edef
is used for the purpose is not that much of an issue, I guess; but as far as I can see, it is the only command possibly appropriate)
Now, I finally came up with an MWE that demonstrates this, so I'd like to ask about this in more generic terms - consider:
\documentclass{minimal}
\def\doubleCommand#1#2{testing-#1-#2}
\protected\def\tmpcmd#1{teststring#1} % concatenate, no spaces
\begin{document}
\typeout{--Test:--\doubleCommand{A}{B}--}
\edef\initArg{12}
\edef\dcArg{\tmpcmd\initArg}
\typeout{--Args:--\initArg--\dcArg--}
\edef\myResult{\doubleCommand{\dcArg}{Verbatim}}
\edef\myResult{\detokenize\expandafter{\myResult}}
\typeout{--Out :--\myResult--}
This: \doubleCommand{\dcArg}{Verbatim}
\end{document}
Now, this works fine, and typesets "This: testing-teststring12-Verbatim
", as expected. However, if we look at the terminal log output from pdflatex
, we get:
--Test:--testing-A-B--
--Args:--12--\tmpcmd 12--
--Out :--testing-\tmpcmd 12-Verbatim--
That is, the \edef
didn't expand the \tmpcmd
command - and its name is printed instead, along with the arguments (and notably, there is the space between the command and the first argument :)
).
However, since the content is typeset fine, it is obviously accesible somewhere - and it is this content that I would like to have as a "string" in a variable. To show this, all I need to do is remove the \protected
command, so I have:
\def\tmpcmd#1{teststring#1} % concatenate, no spaces
... and then the terminal log shows:
--Test:--testing-A-B--
--Args:--12--teststring12--
--Out :--testing-teststring12-Verbatim--
... that is, the command output ("teststring12-Verbatim
") is now a "string" value in a "variable" (command).
Now, I'm pretty sure there are good reasons for \protected
; however, many times I just want to get to the data which is typeset anyways. So is there a strategy that one could employ in these cases? The above links suggest there is not, and a solution - if possible - depends on a given package's command, and its implementation... However, I'd like a method that I could employ, without changing package style files (like, say, removing \protected
from diverse macros I might need, which even without further knowledge, I can tell is a bad idea).
I can already guess such a general method is not available - but could anyone explain why (maybe in terms of the above MWE)?
Many thanks in advance for any answers,
Cheers!
\protected
macros are used precisely because the do not expand inside\edef
or similar. That's usually because they contain material which will fail to\edef
correctly. Are you creating these macros, are are they from 'somewhere else'. If the later, it might be useful to say where.\edef
) the return of a\citefield
(or\printfield
) in biblatex, from a\newbibmacro
hook; the items typeset at the spot where I want them as command contents, but because of the\protected
I cannot capture them. However, I've met this in other contexts as well, which is why I'd like to have a better understanding of this generally. Cheers!\typeout
- how come those very same contents are typeset in the document, if I just issue the command normally at the very same spot in the code?\protect
and\protected
are very different beasts and mustn't be confused with each other. The protection of commands with optional arguments or defined via\DeclareRobustCommand
doesn't rely on\protected
.