명령을 정의하거나 재정의하는 방법(\providecommand + \renewcommand 혼합)은 어떻게 됩니까?

명령을 정의하거나 재정의하는 방법(\providecommand + \renewcommand 혼합)은 어떻게 됩니까?

어떤 상황에서는 명령을 정의하는 방법이 있었으면 좋겠습니다 \tmp.

  • \tmp존재하지 않는 경우 : 정의됨\tmp
  • if \tmp가 종료되면: 재정의\tmp

나의 현재 접근 방식은 단순히 \newcommand또는 중 하나를 사용하는 것입니다 \renewcommand. 그러나 이는 문서의 순서를 변경하는 경우 한 버전에서 다른 버전으로 변경해야 하는 경우가 많고 때로는 코드의 전체 재사용성이 제한된다는 의미입니다.

~ 안에이 질문내 문제를 거의 해결한 에 대해 배웠습니다 \providecommand. 정의 여부에 관계없이 사용할 수 있지만 \tmp첫 번째 발생 시에만 정의하고 덮어쓰지 않습니다. 이것은 나를 순진한 시도로 이끌었습니다.

\newcommand{\overwritecommand}[2]{
  \providecommand{#1}{#2}
  \renewcommand{#1}{#2}
}

그러나 이 접근 방식은 분명히 충분히 일반적이지 않습니다.

% it works for
\overwritecommand{\tmp}{test}

% but not for commands with arguments like
\overwritecommand{\tmp}[1]{test: #1} 
% Error: You can't use `macro parameter character #' in horizontal mode.

달성할 수 있는 다른 방법이 있나요?정의 또는 덮어쓰기행동?

답변1

예, 다음과 같은 방법이 있습니다.

\newcommand{\declarecommand}[1]{\providecommand{#1}{}\renewcommand{#1}}

왜 작동합니까? TeX은 매크로 확장을 사용하고 \providecommand정의된 것이 무엇 #1인지는 중요하지 않습니다 . #1정의되지 않은 경우 즉시 재정의하기 때문입니다.

이제 방법을 알았으니 시도해 보세요.

\declarecommand{\box}[1]{\fbox{#1}}

그리고 난파선을 즐겨라!

거기~이다LaTeX가 기능을 제공하지 않는 이유 \declarecommand: 당신해야 하다기존 명령을 재정의하고 있는지 확인하십시오.

선택 사항을 허용하려면 *다음을 수행하십시오.

\makeatletter
\newcommand\declarecommand{\@star@or@long\@declarecommand}
\newcommand\@declarecommand[1]{%
  \provide@command{#1}{}%
  \renew@command{#1}%
}
\makeatother

할 것입니다.

답변2

나는 당신이 필요하다는 것을 이해 \def하지만 \newcommand. \newcommand정의된 제어 시퀀스에 의미가 있는지 여부를 무시하는 자체 정의가 가능합니다 . 예를 들어 다음 코드를 사용할 수 있습니다.이 페이지:

\def\newcommand#1{\isnextchar[{\newcommandA#1}{\newcommandA#1[0]}}
\def\newcommandA#1[#2]{\edef\tmpp{\ifcase#2%
   \or1\or12\or123\or1234\or12345\or123456\or1234567\or12345678\or123456789\fi}%
   \edef\tmpp{\expandafter\addhashs\tmpp.}%
   \isnextchar[{\newcommandB#1}{\long\expandafter\def\expandafter#1\tmpp}%
}
\def\newcommandB#1[#2]{%
   \def#1{\isnextchar[{\runcommand#1}{\runcommand#1[#2]}}%
   \long\expandafter\def\csname\string#1X\expandafter\endcsname\tmpp
}
\def\addhashs#1{\ifx.#1\else #####1\expandafter\addhashs\fi}
\long\def\runcommand#1[#2]{\csname\string#1X\endcsname{#2}} 

답변3

xparse고전적인 예제가 이미 표시되었으므로 매우 사용자 친화적인 방법을 추가하겠습니다 .

\documentclass{article}
\usepackage{xparse}
\DeclareDocumentCommand{\foo}{m}
 {Foo: #1}
\begin{document}

\foo{bar}

\DeclareDocumentCommand{\foo}{om}
 {\IfNoValueTF{#1}%
   {Bar: no optional, just #2}%
   {Bar: optional = #1, plus #2}%
 }%

\foo{Baz}

\foo[Bar]{Baz}

\end{document}

관련 정보