![단락이 포함된 인수를 취하는 매크로를 어떻게 작성합니까?](https://rvso.com/image/391694/%EB%8B%A8%EB%9D%BD%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%9C%20%EC%9D%B8%EC%88%98%EB%A5%BC%20%EC%B7%A8%ED%95%98%EB%8A%94%20%EB%A7%A4%ED%81%AC%EB%A1%9C%EB%A5%BC%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%EC%9E%91%EC%84%B1%ED%95%A9%EB%8B%88%EA%B9%8C%3F.png)
단락이 포함된 인수를 사용하는 매크로를 작성하려고 합니다. 일반 매크로를 작성하고 해당 인수 중 하나에 단락이 포함되어 있으면 중단됩니다.
\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 명령( \def
LaTeX 문서에서는 사용하면 안 됨) 을 사용하는 경우 기본적으로 \newcommand
a를 만듭니다 . \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}
\endlinechar
TeX가 두 개의 토큰(기본적으로 공백임)을 볼 때 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
. \par
TeX가 텍스트 입력을 토큰으로 처리하는 단계에서 빈 줄이 변환되기 때문에 둘 다 허용되지 않습니다. \par
이 점에서 재정의는 쓸모가 없다는 점에 유의하십시오 .정확하게\par
의미와 관계없이 허용되지 않는 토큰입니다 .
해결 방법: 매크로를 만드세요 \long
.
\long\def\mymacro#1{#1}
더 나은 솔루션:
\newcommand{\mymacro}[1]{#1}
\newcommand
내부적으로 사용하기 때문입니다 \long\def
. \newcommand*
대신 변형은 \def
접두사 없이 사용됩니다.