在字符串中创建“静态”参数

在字符串中创建“静态”参数

是否有一个技巧可以“静态地”集成给定字符串中的参数,然后在另一个命令中使用该字符串,然后处理该参数?

就像是 :

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

可以这样做:

\mydynamicstring{world} % "Hello world" 

答案1

是的,这是可能的:

%! 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}

但考虑到代码最终会变得多么复杂(而且参数数量通常不固定),更简单的方法是将所有参数传递(复制)给子命令,\mystring如 egreg 所建议的那样。它不会太长,而且更明确。

(为了在 Python 中进行比较,如果您想在另一个命令中使用某个函数,最好明确传递参数,而不是将值分配给全局变量等。)

请注意,将 TeX 代码视为“字符串”并不完全正确,因为每个字符都有一个同样重要的“类别代码”。

答案2

您可以使用##而不是#

\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}

您可以使用不同的方法#

\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}

相关内容