変更されたマクロ定義は元の状態に戻ります

変更されたマクロ定義は元の状態に戻ります

2 つのコマンドがあり\testone\testtwo.\testtwoは関連するコマンドが以前存在し\testone、同じ引数を取る場合にのみ表示されます。したがって、\testoneその引数を\@repeat@mewhereに\testtwo格納して、再度取得し、2 回入力しなくても済むようにしたいと思います。

ただし、これは両方が同じ環境にある場合にのみ機能します。ただし、場合によっては、の変更された値を\@repeat@me無視する必要があると判断されます。

\documentclass{article}
\makeatletter

\def\@repeat@me{}

\newcommand\testtwo{\bf{\@repeat@me}% print what is currently defined.
% reset the definition so it does not interfere with next call
\def\@repeat@me{}}

% print it and then remember it.
\newcommand\testone[1]{\def\@repeat@me{#1}\emph{\@repeat@me}}%

\makeatother
\begin{document}

% prints: \emph{Hello World} \bf{Hello World}
\testone{Hello World} \testtwo{}

% prints: \bf{\emph{Hello World}}
% intended: \bf{\emph{Hello World}} \bf{Hello World}
\bf{\testone{Hello World}} \testtwo{}

\end{document}

答え1

グローバル割り当てが必要な場合(グループと環境を回避するには、以下が必要です)\global\def(または\gdef):

\documentclass{scrartcl}

\makeatletter
\newcommand*\@repeat@me{}
\newcommand*\testtwo{\textbf{\@repeat@me}\gdef\@repeat@me{}}
\newcommand\testone[1]{\gdef\@repeat@me{#1}\emph{\@repeat@me}}
\makeatother

\begin{document}

\testone{Hello World} \testtwo
\textbf{\testone{Hello World}} \testtwo

\end{document}

答え2

TeX は、(再)定義が存続し、外部で元に戻されるスコープを強制することに注意してください。これがここで起こっていることです。展開を見てみましょう。

\testone{Hello World} \testtwo{}

展開すると(コメント付き)

\def\@repeat@me{Hello World}\emph{\@repeat@me} % \testone{Hello World}
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}

これは次のように展開される

\emph{Hello World} \textbf{Hello World}% Using the new definition of \@repeat@me

ここに画像の説明を入力してください

次に、2 番目のマクロ セットの展開を見てみましょう。

\textbf{\testone{Hello World}} \testtwo{}

展開すると(コメント付き)

\textbf{% <--- start of a group/scope
  def\@repeat@me{Hello World}\emph{\@repeat@me}% \testone{Hello World}
} % <--- end of a group/scope
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}

これは次のように展開される

\textbf{\emph{Hello World}} % At scope-end, \@repeat@me reverts to its original definition
\textbf{}% Since \@repeat@me is empty {}

ここに画像の説明を入力してください

のようなグローバル定義を使用すると、 survive\gdefの再定義が\@repeat@meによって提供される範囲を超えてしまいます\textbf{..}


ここに画像の説明を入力してください

\documentclass{article}
\makeatletter

\def\@repeat@me{}

% print it and then remember it.
\newcommand\testone[1]{\gdef\@repeat@me{#1}\emph{\@repeat@me}}%

\newcommand\testtwo{\textbf{\@repeat@me}% print what is currently defined.
  % reset the definition so it does not interfere with next call
  \def\@repeat@me{}}

\makeatother
\begin{document}

% prints: \emph{Hello World} \textbf{Hello World}
\testone{Hello World} \testtwo{}

% prints: \textbf{\emph{Hello World}} \textbf{Hello World}
\textbf{\testone{Hello World}} \testtwo{}

\end{document}

関連情報