상황

상황

#명령과 환경 내에서 파운드 기호/숫자 기호/해시 기호를 사용할 때 이는 인수를 나타냅니다. 하지만, 그러면 안 된다 \detokenize{#}.아니다논쟁?

상황

파운드 기호는 로그 파일에서 멋진 구분선을 만듭니다.

\detokenize오류가 발생하려면 두 번째 항목의 주석 처리를 해제해 보세요 .

\documentclass{article}
\usepackage{fontspec}% compile with xelatex
\newenvironment{detokenizetest}[1]
{% firstoftwo
 \detokenize{##############################################################################}%
 %\detokenize{##BEGIN#######################################################################}% uncommenting this causes a compile error
}%
{% secondoftwo
}%
\begin{document}
\null
\end{document}

오류 출력

이 오류는 포함된 행의 주석 처리를 제거할 때만 발생합니다 BEGIN.

! Illegal parameter number in definition of \detokenizetest.
<to be read again>
                   }
l.9 }
     %
?

답변1

카테고리 코드 6이 있으므로 #TeX에서는 매우 특별한 의미를 갖습니다. 매크로 정의에서 매개변수를 표시하는 데 사용되기 때문입니다.

TeX의 규칙은 당신이 원할 때가게#매크로의 대체 텍스트에서는 이를 두 배로 늘려야 합니다 .

매크로 정의에 대한 대체 텍스트를 처리할 때 단일 #뒤에는 해당 인수에 대한 포인터를 나타내는 숫자(1~9)가 와야 하지만 ##로 저장됩니다 #. 이것은 다음과 같은 것을 허용하는 트릭입니다.

\def\foo{\def\baz##1{-##1-}}

\foo따라서 is 의 대체 텍스트 \def\baz#1{-#1-}와 호출은 단일 인수 매크로로 \foo정의됩니다 .\baz

\detokenize대체 텍스트의 기본 요소가 해당 작업을 수행합니다.매크로가 호출되어 확장될 때, 정의 시점이 아닌 로 정의가 완료되지 않는 한 \edef대체 텍스트를 메모리에 저장하기 전에 먼저 전체 확장을 수행합니다.

위의 정의를 가정하면 \meaning\foo다음과 같은 메시지가 표시됩니다.

macro:->\def \baz ##1{-##1-}

\detokenize동일한 메커니즘을 사용하는 경우 에도 동일한 일이 발생합니다 . 따라서 다음과 같은 것

\edef\hashmarks{\detokenize{####}}

실제로 #대체 텍스트에는 두 개가 표시되지만 최종 결과는 그 중 네 개가 됩니다. 처리 시 표준 메커니즘은 \edef먼저 개수를 절반으로 줄인 #다음 \detokenize다시 두 배로 늘립니다. 특히 당신은캔트이런 식으로 홀수 개의 #.

구분 기호 라인을 생성하려면 간접적인 방법을 사용하여 #범주 코드 12로 구성된 필수 토큰 목록을 미리 만드는 것이 훨씬 좋습니다. 이 예에서는 홀수이기 때문에 그 중 3개를 사용합니다.

\documentclass{article}

\begingroup\lccode`?=`# \lowercase{\endgroup
  \newcommand{\lineofhashsigns}{???}
}

\newenvironment{delimitedtext}
  {\par\lineofhashsigns\par}
  {\par\lineofhashsigns\par}

\begin{document}

\begin{delimitedtext}
abc
\end{delimitedtext}

\end{document}

여기에 이미지 설명을 입력하세요

\lineofhashsigns필요하지 않은 다른 정의는 \lowercase카테고리 코드를 변경하는 것입니다.

\catcode`#=12
\newcommand{\lineofhashsigns}{###}
\catcode`#=6

매크로에 인수가 포함되지 않도록 하려면 대체 텍스트에 어떤 토큰이라도 추가할 수 있습니다.

답변2

프리미티브 \detokenize는 실제로 #매개변수로 처리되지 않고 확장될 때 매개변수로 처리됨을 의미합니다. 일반적인 할당( \newcommandLaTeX에서는 \defTeX 기본 형식)에서는 확장이 발생하지 않는다는 점을 기억하세요. 여기서는 \newenvironment토큰을 '그냥 저장'하는 것과 정확히 동일한 작업을 수행합니다 \newcommand. 이는 매크로 생성 시 각 현재에 대해 일치하는 매개변수를 갖 #거나 토큰을 두 배로 늘려야 한다는 일반적인 TeX 규칙이 있음을 의미합니다 #.

궁극적 으로 \newenvironmenta 로 해결 되면 \def다음을 사용하여 원하는 작업을 수행할 수 있습니다 \edef.

\edef\detokenizetest#1{%
 \detokenize{##############################################################################}%
 \detokenize{##BEGIN#######################################################################}%
}
\def\enddetokenizetest{}% As \newenvironment will do this
\show\detokenizetest

관련 정보