Who ate my space? (How to stop \exp_args:Nf from consuming a space?)
I would simply use the new e
-type approach here (i.e. using the \expanded
primitive or equivalent):
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\cs_new:Npn \__printf_pre_output:n #1 { [ \tl_to_str:n {#1} ] }
\cs_set:Npn \__printf_tmp:w #1
{
\cs_new:Npn \__printf_format_final_print:n ##1
{
\exp_args:Ne \__printf_pre_output:n
{ \prg_replicate:nn {##1} {#1} }
}
}
\__printf_tmp:w { ~ }
\ttfamily
Wrong,~4~spaces:~\__printf_format_final_print:n {5}\par
Right,~5~spaces:~[\ \ \ \ \ ]\par
\ExplSyntaxOff
\end{document}
This will likely become the standard approach for such cases: f
-type expansion is much less important now that we have e
-type either directly using the \expanded
primitive or (where necessary) emulated. Note that MiKTeX already has \expanded
in pdfTeX and XeTeX, and that this will appear in TeX Live 2019. Also note that LuaTeX has had \expanded
from day one. (Emulation is reliable but does have a performance impact: at present, it probably is best avoided for any code which needs to work in tight loops or similar.)
Like @jfbu mentioned, expanding twice is enough for \prg_replicate:nn
. So using \exp_args:No
twice on it suffices:
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\cs_new:Npn \__printf_pre_output:n #1 { [ \tl_to_str:n {#1} ] }
\cs_set:Npn \__printf_tmp:w #1
{
\cs_new:Npn \__printf_format_final_print:n ##1
{
\exp_args:NNo \exp_args:No \__printf_pre_output:n
{ \prg_replicate:nn {##1} {#1} }
}
}
\__printf_tmp:w { ~ }
\ttfamily
Wrong,~4~spaces:~\__printf_format_final_print:n {5}\par
Right,~5~spaces:~[\ \ \ \ \ ]\par
\ExplSyntaxOff
\end{document}
I can only second @JosephWright and @Skillmon answers but speaking of what I know, with xint
you only need to expand once \romannumeral\xintreplicate{100}{ }
to get 100 spaces. So if inside a macro
\def\x{\romannumeral\xintreplicate{100}{ }}
you only need to expand \x
twice.
Or
\def\x{\xintreplicate{100}{ }}
then you can do \romannumeral\x
.
Oh wait, I completely forgot: \romannumeral\xintreplicate
basically IS (up to different user interface) \prg_replicate:nn
, I COPIED its underlying implementation ;-)
.