단락이 포함된 인수를 취하는 매크로를 어떻게 작성합니까?

단락이 포함된 인수를 취하는 매크로를 어떻게 작성합니까?

단락이 포함된 인수를 사용하는 매크로를 작성하려고 합니다. 일반 매크로를 작성하고 해당 인수 중 하나에 단락이 포함되어 있으면 중단됩니다.

\documentclass{article}
\usepackage[utf8]{inputenc}

\title{test}

\begin{document}

\maketitle

\section{Introduction}

\def\mymacro#1{#1}

\mymacro{This

contains a paragraph}

\end{document}

오류가 발생합니다.

Runaway argument?
{This
! Paragraph ended before \mymacro was complete.
<to be read again> 
                   \par
l.15

\par그래서 매크로의 인수를 확장하기 위해 재정의하려고 했지만 이제 컴파일이 중단되지 않습니다.

\documentclass{article}
\usepackage[utf8]{inputenc}

\title{test}

\begin{document}

\maketitle

\section{Introduction}

\gdef\oldpar{\par}

\def\mymacro{\gdef\par{}\mymacroi}

\def\mymacroi#1{#1\gdef\par{\oldpar}}

\mymacro{foo

bar}

\end{document}

답변1

TeX이 작성될 당시에는 문서의 한 페이지를 처리하는 데 몇 분이 걸렸고 구문 강조는 별거 아니었기 때문에 }. A 는 기본적으로 다음과 같이 명시적으로 명시하지 않는 한 토큰 \def을 허용하지 않습니다 .\par\long\def

\def\mymacro#1{#1}

반면에 LaTeX는 이를 기본적으로 사용하므로 적절한 LaTeX 명령( \defLaTeX 문서에서는 사용하면 안 됨) 을 사용하는 경우 기본적으로 \newcommanda를 만듭니다 . \long\def"짧은"을 원하면 \def를 사용하십시오 \newcommand*.

xparse짧은 인수 기본값을 반환하지만 인수 수정자를 \long사용하여 매크로를 정의할 수 있습니다 +.

\NewDocumentCommand\mymacro{ m}{#1}% \def
\NewDocumentCommand\mymacro{+m}{#1}% \long\def

두 번째 시도는 영리하며 두 가지를 제외하고는 효과가 있을 수 있습니다.

첫 번째는 을 사용하고 있다는 것 \gdef\oldpar{\par}입니다 \gdef\par{\oldpar}. 일단 당신은확장하다 \par\oldpar확장되면 결과가 나오고 \par확장되면 결과가 나오고 \oldpar확장되면 결과 \par가 나오고 ... 영원히 실행 됩니다 \oldpar./

이 경우에는 다음을 사용해야 합니다 \let(또는 전역 효과가 있어야 함) . 이것은 무엇이 무엇인지에 의존하지 않는 명명된 정확한 복사본을 생성합니다 .\global\let\let\oldpar\par\par\oldpar\par

둘째, 런어웨이 인수 검사는 의 정의와 관계없이 낮은 수준에서 구현되므로 \par동일한 오류로 인해 실패합니다.

\let\par\relax
\def\mymacro#1{#1}
\mymacro{foo

bar}

\endlinecharTeX가 두 개의 토큰(기본적으로 공백임)을 볼 때 TeX는 암시적 \par토큰을 삽입하여 오류를 발생시키기 때문입니다 Runaway argument. 그렇다면 다음과 같습니다.

\newcount\oldELchar
\oldELchar=\endlinechar
\def\mymacro{\endlinechar=-1\relax\mymacroi}
\def\mymacroi#1{#1\endlinechar=\oldELchar}
\mymacro{foo

bar}

오류는 발생하지 않지만 새 줄은 더 이상 공백이 아닙니다.

답변2

로 정의된 매크로의 인수는 토큰을 \def허용하지 않습니다 \par. \parTeX가 텍스트 입력을 토큰으로 처리하는 단계에서 빈 줄이 변환되기 때문에 둘 다 허용되지 않습니다. \par이 점에서 재정의는 쓸모가 없다는 점에 유의하십시오 .정확하게\par의미와 관계없이 허용되지 않는 토큰입니다 .

해결 방법: 매크로를 만드세요 \long.

\long\def\mymacro#1{#1}

더 나은 솔루션:

\newcommand{\mymacro}[1]{#1}

\newcommand내부적으로 사용하기 때문입니다 \long\def. \newcommand*대신 변형은 \def접두사 없이 사용됩니다.

관련 정보