如何存储宏的当前值?

如何存储宏的当前值?

我定义了一个宏\test,如下:

\usepackage{xstring}
\newcommand{\test}[1]{
    \StrGobbleRight{#1}{1}[\temp]
    \expandafter\newcommand\csname\temp\endcsname{Name: \temp}
}

它用其参数的名称创建一个新的宏,然后将这个名称存储在这个新宏中(我创建这个宏只是为了说明我的问题,并不是说我真的需要这个宏的功能)。因此,

\test{aaa}
\aaa

会得到Name: aaa。但是,如果在这之后有一个\test{bbb},则\aaa变成Name: bbb,因为\aaa存储的是宏\temp,而不是它的值。

我希望保持aaa一个常数的值。为此,我\expandafter之前尝试添加\temp,但没有成功。正确的方法是什么?

\newcommand(我知道我可以将这个例子中的第二个改为来\edef解决这个问题。但如果我使用,这将不起作用\newtheorem。我真正想知道的是如何获得价值\temp。)

下面是 MWE。

\documentclass{article}

\usepackage{xstring}
\newcommand{\test}[1]{
    \StrGobbleRight{#1}{0}[\temp]
    \expandafter\newcommand\csname\temp\endcsname{Name: \temp}
}

\begin{document}

\test{aaa}
\aaa

\test{bbb}
\aaa

\end{document}

答案1

您必须\edef使用\def

\def\test#1{%
   \def\temp{#1}% It emulates your \StrGobble
   \expandafter\edef\csname#1\endcsname{Name: \temp}
}

或者更直接一点:

\def\test#1{\expandafter\def\csname#1\endcsname{Name: #1}}

编辑好的,当您使用时\newtheorem,您的工作就更多了。(我从不使用诸如\newcommand或 之类的东西\newtheorem,只使用\def\edef\gdef\xdef,因此,我使用 TeX 的生活更简单)。

您可以使用\edef\tempi三个\expandafter

\def\test#1{%
    \def\temp{#1}%
    \edef\tempi{name: \temp}%
    \expandafter\newtheorem\expandafter\temp\expandafter{\tempi}%
}

答案2

您可以使用 来完成此操作xstring,但使用 更简单expl3

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\test}{O{0}m}
 {
  \jinwen_test:nn { #1 } { #2 }
 }

\cs_new_protected:Nn \jinwen_test:nn
 {% #1 = how many characters to gobble from the right
  % #2 = string
  \cs_new:cpx { #2 } { Name: ~ \tl_range:nnn { #2 } { 1 } { - 1 - #1 } }
 }
\ExplSyntaxOff

\frenchspacing 

\begin{document}

\test{aaa}
\test[3]{abcdef}

\texttt{\meaning\aaa}

\texttt{\meaning\abcdef}

\end{document}

在此处输入图片描述

xstring可以使用参数交换技术来避免\edef

\documentclass{article}
\usepackage{xstring}

\makeatletter
\newcommand{\test}[2][0]{%
  \StrGobbleRight{#2}{#1}[\jinwen@temp]
  \expandafter\jinwen@makecommand\expandafter{\jinwen@temp}{#2}%
}
\newcommand{\jinwen@makecommand}[2]{%
  \expandafter\newcommand\csname#2\endcsname{Name: #1}%
}
\makeatother

\frenchspacing

\begin{document}

\test{aaa}
\test[3]{abcdef}

\texttt{\meaning\aaa}

\texttt{\meaning\abcdef}

\end{document}

答案3

只要所讨论的字符串不包含哈希值(),\temp定义临时宏的方法就可以起作用。\StrGobbleRight#


您可以将顶层扩展\temp作为另一个执行实际工作的宏的参数:

\documentclass{article}

\usepackage{xstring}

\newcommand{\test}[1]{%
    \begingroup
    \StrGobbleRight{#1}{1}[\temp]%
    \expandafter\endgroup\expandafter\innertest\expandafter{\temp}%
}%
\newcommand\innertest[1]{%
  \expandafter\newcommand\csname#1\endcsname{Name: #1}%
}%


\begin{document}

\test{aaax}

\test{bbbx}

\texttt{\string\aaa:\meaning\aaa}

\texttt{\string\bbb:\meaning\bbb}

\end{document}

在此处输入图片描述


如果允许 ε-TeX 扩展,您可以使用\protected@edef并包装所有内容,但\temp实际上\unexpanded在这个例子中\unexpanded不需要,因为字符Name:不可扩展,但可能有类似的东西\newtheorem

\documentclass{article}

\usepackage{xstring}

\makeatletter
\newcommand{\test}[1]{%
    \StrGobbleRight{#1}{1}[\temp]%
    \expandafter\@ifdefinable\csname\temp\endcsname{%
      \expandafter\protected@edef\csname\temp\endcsname{\unexpanded{Name: }\temp}%
    }%
}%
\makeatother

\begin{document}

\test{aaax}

\test{bbbx}

\texttt{\string\aaa:\meaning\aaa}

\texttt{\string\bbb:\meaning\bbb}

\end{document}

在此处输入图片描述


如果您喜欢复杂的东西,您可以在ing 标记\expandafter之前应用。 您可以使用它来保持扩展,直到找到非正数。 (默默地丢弃非正数而不提供任何标记作为回报。)\Exchange
\romannumeral
\romannumeral

使用下面的示例来\Stopromannumeral表示数字0,其中您不会不必要地删除尾随空格标记,并且不0涉及可能受 / 影响\uppercase/更改的显式字符标记\lowercase

在的\expandafter扩展过程中启动的 -chain 启动了-expansion 。反过来又触发了-token后面的两个的扩展,这又产生了 的顶层扩展。 然后触发。 之后\csname\romannumeral
\romannumeral\expandafter\romannumeral\temp
\romannumeral\Exchange
\Stopromannumeral,即 TeX-⟨数字⟩- 发现数量为“0”的值,结尾\romannumeral\romannumeral形成该标记的标记⟨数字⟩-数量,但不提供代币作为回报。

\documentclass{article}

\usepackage{xstring}

\makeatletter
\newcommand\Exchange[2]{#2#1}%
\@ifdefinable\Stopromannumeral{\chardef\Stopromannumeral=`\^^00}%
\makeatother


\newcommand{\test}[1]{%
    \StrGobbleRight{#1}{1}[\temp]%
    \expandafter\newcommand
    \csname\temp\expandafter\endcsname
                \expandafter{%
                  \romannumeral
                  \expandafter\Exchange\expandafter{\temp}{\Stopromannumeral Name: }%
                }%
}%


\begin{document}

\test{aaax}

\test{bbbx}

\texttt{\string\aaa:\meaning\aaa}

\texttt{\string\bbb:\meaning\bbb}

\end{document}

在此处输入图片描述

相关内容