1

Is there a trick to integrate arguments "statically" in a given string, to use this string in another command that will then process the argument ?

Something like :

\edef\mystring{Hello #1 !} % this code does not work, of course
\newcommand\mydynamicstring[1]{\mystring}

that could allow to do :

\mydynamicstring{world} % "Hello world" 
4
  • 3
    I'm guessing you want to detokenize the # so it's a 'normal' character - correct?
    – Joseph Wright
    Jan 12, 2023 at 16:37
  • Yes, if detokenizing #1 allows \mydynamicstring to use it as a real argument, I am very interested to know how it is done, than you. Jan 12, 2023 at 16:45
  • 3
    My impression is that you want to do \newcommand{\mystring}[1]{Hello #1!} and \newcommand{\mydynamycstring}[1]{\mystring{#1}}.
    – egreg
    Jan 12, 2023 at 17:01
  • Not really,.. the idea is to be able to create strings with static placeholder(s) (represented by#1, #2 and son on) that could then be used in a context (a command) where the static placeholders would become dynamic (really arguments) for the command. Jan 13, 2023 at 8:26

2 Answers 2

0

Yes it's possible:

%! TEX program = lualatex
\documentclass{article}
\begin{document}

\edef\mystring{\unexpanded{Hello #1 !}}
% equivalently
\def\mystring{Hello ##1 !}

% either do this (use \expanded to inject the content of \mystring into inside `\newcommand` before executing `\newcommand`)
\expanded{\noexpand\newcommand\noexpand\mydynamicstring[1]{\mystring}}
\mydynamicstring{world}

% or (injection by parameter)
\def\tmp#1{
  \renewcommand\mydynamicstring[1]{#1}
}
\expandafter\tmp\expandafter{\mystring}
\mydynamicstring{world}

\end{document}

but given how complicated the code ends up being (and usually the parameter numbers are not fixed anyway), it's easier to just pass (copy) all the parameters to the sub-command \mystring as in the suggestion of egreg. It's not much longer, and more explicit.

(for comparison in Python if you want to use some function inside another command, it's also better to explicitly pass the arguments in instead of assign the values to global variables etc.)

Note that thinking of TeX code as "strings" is not entirely correct, as each character has a "category code" that is also important.

0

You can use ## instead of #.

\documentclass{article}

\makeatletter
\NewDocumentCommand{\newdynamiccommand}{mO{0}m}{%
  \expandafter\@newdynamiccommand\expandafter{#3}{#1}{#2}%
}
\newcommand{\@newdynamiccommand}[3]{%
  \newcommand{#2}[#3]{#1}%
}
\makeatother

\newcommand\mystring{Hello ##1!}

\newdynamiccommand{\mydynamicstring}[1]{\mystring}

\begin{document}

\mydynamicstring{World}

\end{document}

With a different approach you can use #.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\newdynamicstring}{mm}
 {
  \tl_clear_new:N #1
  \tl_set:Nn #1 { #2 }
 }

\NewDocumentCommand{\newdynamiccommand}{mO{0}m}
 {
  \brabant_dyncom:nnV { #1 } { #2 } #3
 }

\cs_new_protected:Nn \brabant_dyncom:nnn
 {
  \newcommand{#1}[#2]{#3}%
 }
\cs_generate_variant:Nn \brabant_dyncom:nnn { nnV }

\ExplSyntaxOff

\newdynamicstring\mystring{Hello #1!}

\newdynamiccommand{\mydynamicstring}[1]{\mystring}

\begin{document}

\mydynamicstring{World}

\end{document}

You must log in to answer this question.

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