여러 인수가 있는 매크로 정의 및 \csname 사용

여러 인수가 있는 매크로 정의 및 \csname 사용

다음 코드가 작동하지 않는 이유는 무엇입니까?

\Requirepackage{amsthm}
\renewcommand\newtheorem[2]{%
    \NewEnviron{\csname #1\endcsname}[1]{%
        ##1 : \BODY
    }
}

인수 없이 for 매크로를 사용하는 예를 본 적이 있지만 a 또는 여러 인수가 있는 \csname SOMENAME\endcsname경우 이를 수행하는 방법을 모르겠습니다 . 오류 메시지가 나타납니다 .\NewEnviron\newcommand! Missing \endcsname inserted

답변1

환경 이름에 대한 명령 이름을 원하지 않습니다. 이름만으로도 괜찮습니다.

따라서 다음과 같이 할 수 있습니다.

\documentclass{article}
\usepackage{amsthm,environ}
\renewcommand\newtheorem[2]{%
    \NewEnviron{#1}[1]{%
        ##1 : \BODY
    }%
}
\begin{document}
\newtheorem{acorns}{oaks}
\begin{acorns}{trees}
  leaves and things
\end{acorns}
\end{document}

이 코드는 필요하지 않습니다.amsthm\newcommand\newtheorem..., 다른 이유로 패키지가 필요한 경우가 아니면 그냥 사용할 수 있습니다 .

또한 필수 명령을 생성하더라도 두 번째 인수로는 아무 작업도 수행하지 않습니다. 위의 예에서는 oaks.

나는 이것이 정말로 당신이 원하는 것인지 확신하지 못합니다. 위 코드의 출력은 다음과 같습니다.

나무와 나뭇잎과 사물

처럼크리스티앙 후퍼(Christian Hupfer)는 다음과 같이 지적합니다., 이것은 물론 \newtheorem표준적인 의미에서 사용하는 모든 것을 깨뜨릴 것입니다. 처럼egreg 라고\newtheorem, 이와 같이 재정의하는 것이 어떤 목적에 도움이 되는지 전혀 명확하지 않습니다 . 조만간 문제가 발생할 것이 거의 보장된 것 같습니다. 아마도 더 빨리.

답변2

다음 코드가 작동하지 않는 이유는 무엇입니까?

어떤 역할을 하는지 자세히 살펴보겠습니다 \NewEnviron.

짧은 매크로 체인을 사용하여 사용자 입력을 적절하게 구문 분석한 후 처음에 사용 했던 것을 \NewEnviron사용합니다 .\env@newenvironment\let\newenvironment

이제 \newenvironment내부적으로 다음과 같은 작업을 수행합니다(약간 단순화됨).

\expandafter\def\csname <env-name>\endcsname{<begin-code>}

(기본적으로 당신은 내부가 이미 이 문제를 처리하고 있다는 사실을 모르고 올바른 일을 했습니다.)

" "를 설정하면 <env-name>=\csname SOMENAME\endcsname-- 다음과 같은 사용자 정의 매크로를 사용한 결과 \newtheorem{SOMENAME}{}-- 불필요한 쌍이 생성됩니다 \csname...\endcsname.

\expandafter\def\csname\csname SOMENAME\endcsname\endcsname...

\expandafter(아마 아시겠지만) 이 경우 \def다음 토큰을 미리 확인하기 위해 이를 잡아서 저장하고 이를 먼저 확장합니다. 여기서는 \csname다음을 찾고 그 \endcsname사이의 모든 것을 확장하고 그로부터 제어 시퀀스를 형성하는 항목을 찾습니다. 이것은 \csname후행에 의해 다시 올바르게 종료되는 또 다른 것입니다 \endcsname. 따라서 실제로 'SOMENAME'에 메커니즘을 두 번 적용하면 (계획한 대로) \csname끝나지 않고\def\SOMENAME{<begin-code>}

\def\<expansion of \SOMENAME>{<begin-code>}

가 정의되어 있으면 \SOMENAME아무런 문제가 없습니다.

\documentclass{article}
\usepackage{environ}

\def\SOMENAME{somename}
\NewEnviron{\csname SOMENAME\endcsname}{somename-content: \BODY}

\begin{document}
\begin{somename}
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Integer feugiat tempus urna, cursus placerat sapien mollis ac.
  Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}

하지만 당신은해야~ 아니다그것을 정의하십시오; 이 사용자 인터페이스는 다소 오해의 소지가 있습니다. 환경 이름 입력 \NewEnviron과 정확히 동일 하게 사용하십시오 .\newenvironment

\documentclass{article}
\usepackage{environ}

\newcommand{\FlorianEnvdefWrapper}[1]{%
  \NewEnviron{#1}[1]{##1: \BODY}
}

\FlorianEnvdefWrapper{somename}

\begin{document}
\begin{somename}{foo-bar}
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Integer feugiat tempus urna, cursus placerat sapien mollis ac.
  Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}

주목

패키지와의 충돌을 피하기 위해 예제 매크로의 이름을 변경했습니다 amsthm. 그런 것들은 대체로 그대로 두는 게 낫다고 생각해요. 물론 예외도 있지만, 단순히 명령에 다른 이름을 선택하여 이를 피할 수 있다면 기능을 완전히 잃는 것은 최선의 선택이 아닐 수도 있습니다.

관련 정보