pgfmanual-en-macros.tex의 1099-1121행

pgfmanual-en-macros.tex의 1099-1121행

LaTeX 문서에서 사용하기 위해 명령을 조판하는 방법을 이해하려고 합니다. 명확히 하기 위해,~ 아니다LaTeX를 사용하여 LaTeX 사용에 대한 문서를 LaTeX로 작성하는 대신 LaTeX를 사용하여 문서를 작성합니다(설명서와 같이). 내가 아는 한, LaTeX 문서 작성과 LaTeX를 사용하여 문서 작성을 구별하는 용어는 없습니다(불행히도).

pgfmanual-en-macros.tex의 1099-1121행

https://www.ctan.org/pkg/pgf?lang=en

이 코드는 나에게 표지판을 제거하는 "것처럼 보이지만" 모르겠습니다. 이것이 왜 필요한가요? 어떻게 작동하나요?

{
  \makeatletter
  \global\let\myempty=\@empty
  \global\let\mygobble=\@gobble
  \catcode`\@=12
  \gdef\getridofats#1@#2\relax{%
    \def\getridtest{#2}%
    \ifx\getridtest\myempty%
      \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1}
    \else%
      \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1\protect\printanat}
      \getridofats#2\relax%
    \fi%
  }

  \gdef\removeats#1{%
    \let\strippedat\myempty%
    \edef\strippedtext{\stripcommand#1}%
    \expandafter\getridofats\strippedtext @\relax%
  }

  \gdef\stripcommand#1{\expandafter\mygobble\string#1}
}

추리

이것을 이해하고 싶은 이유는 다음과 같은 코드로 명령을 조판할 수 있을 것 같기 때문입니다. 내 아이디어가 작동하지 않는 경우가 있다고 생각합니다.

다음과 같은 제한 사항도 있습니다.

  • 설명 아래에 예를 들어 조판할 수 있도록 인수가 있는 명령을 포함합니다(예: \hello{input1} 및 에서 사용하면 NewEnviron작동 하지 않음 ).#1#1NewEnviron

\documentclass{article}
\usepackage{fontspec}
\usepackage{environ}
\NewEnviron{command}[1]{% 
\begin{minipage}[t]{.3\textwidth}
\texttt{\string#1}
\end{minipage}
\hfill
\begin{minipage}[t]{.7\textwidth}
\BODY
\end{minipage}
\xdef\putcommandexample{\BODY}% Set BODY to variable http://tex.stackexchange.com/a/14392/13552
}%
\begin{document}
\section{Friendly Commands}
\begin{command}{\hello}
This command greets the reader in a friendly manner.
\end{command}
\begin{command}{\goodbye}
This command greets the reader in a friendly manner.
\end{command}
\end{document}

관심 있는 분들을 위한 참고 사항: minipages 대신 패키지를 사용하여 여백에 명령을 넣었습니다 marginnote. 괜찮아 보인다.

\NewEnviron{command}[1]{% 
\reversemarginpar\marginnote{\texttt{\string#1}}
\BODY
\par
}%

산출

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

답변1

질문“왜 필요한가요?”모든 문서 소스를 읽어야 합니다. 작동 방식은 쉽게 확인할 수 있습니다.

매크로는 \getridofats입력 스트림에서 그 뒤에 오는 내용이 \relax카테고리 코드 12 를 포함하는지 여부를 결정합니다 @.

\removeats그러나 처음부터 어떻게 작동하는지 확인하는 것이 좋습니다 . 명령 이름을 그대로 받아야 합니다.보강된논쟁; 우선 \strippedat빈 토큰 목록으로 초기화됩니다. 그럼 그렇지

\edef\strippedtext{\stripcommand#1}

이는 \strippedtext백슬래시가 제거된 명령 이름을 포함하는 문자열로 설정됩니다.

\expandafter\mygobble\string#1

예를 들어, 먼저 카테고리 12 문자의 문자열로 변환한 다음(그러나 매크로가 컨텍스트에서 호출 되는 경우 다음에 나타나는 문자의 카테고리 코드 11 ) 백슬래시를 사용합니다 \removeats{\abc@def}.\expandafter\mygobble\string\abc@def\abc@def@\makeatother\mygobble

이 준비 후에는 \expandafter\getridofats\strippedtext @\relax입력 스트림에 다음 토큰을 생성하는 호출됩니다.

\getridofats abc@def@\relax

의 정의를 살펴보면 \getridofats는 이고 는 입니다 . 호출이 확인된 경우 입력 스트림에는 다음이 포함됩니다.#1abc#2def@\removeats{\abcdef}

\getridofats abcdef@\relax

이고 이고 #1비어 있을 것입니다 .abcdef#2

매크로는 \getridtest다음으로 확장되도록 정의되었습니다 #2. 첫 번째 경우에는 비어 있지 않지만 두 번째 경우에는 비어 있습니다.

그 후 \ifx\getridtest\myempty두 번째 경우에는 true를 반환하고 첫 번째 경우에는 false를 반환합니다.

테스트가 true를 반환한다고 가정합니다(두 번째 경우). 그 다음에

\expandafter\def\expandafter\strippedat\expandafter{\strippedat abcdef}

이 수행되며, 이는 이전 값에 #1(이 경우 ) 추가됩니다 . 비어 있도록 초기화되었기 때문에 쓸모없어 보일 수 있습니다 . 그러나 "거짓"의 경우에는 어떤 일이 일어나는지 나중에 살펴보겠습니다.abcdef\strippedat\strippedat

테스트가 false(첫 번째 경우)를 반환한다고 가정합니다. 그 다음에

  \expandafter\def\expandafter\strippedat\expandafter{\strippedat abc\protect\printanat}%
  \getridofats def@\relax

완료됨: 첫 번째 조각이 에 추가되고 \strippedat매크로 \protect\printanat\getridofats다시 호출되어 최종 청크를 처리합니다.

제 생각에는 특별히 잘 작성된 매크로는 아닙니다. 그러나 통화는

\removeats\abcdef
\removeats\abc@def
\removeats\ab@cd@ef

결과적 \strippedat으로 각각 다음을 포함하게 됩니다.

abcdef
abc\protect\printanat def
ab\protect\printanat cd\protect\printanat ef

여기서는 다음 \printanat으로 정의됩니다.

\def\printanat{\char`\@}

물론 \protect매크로가 로 정의된 경우에는 필요하지 않지만 \def\printanat{\char64 }이는 개인적인 선택입니다. 문서가 LaTeX로 처리되므로 아마도 LaTeX를 선택했을 것입니다.

\DeclareRobustCommand{\printanat}{\char`\@ }

(후행 공백에 유의하세요. 공백이 없으면 잘못된 것입니다).

@분명히 이 메커니즘은 파일 에 문자를 쓰는 것을 방지하여 .aux해당 범주 코드(LaTeX 보조 파일을 읽을 때 11로 설정됨) 문제를 방지하는 데 사용됩니다.


expl3@버전, 카테고리 코드 12가 있는 상황에서 발행됩니다 .

\ExplSyntaxOn
\cs_new_protected:Npn \removeats #1
 {
  \tl_set:Nx \strippedat { \cs_to_str:N #1 }
  \tl_replace_all:Nnn \strippedat { @ } { \protect\printanat }
 }
\ExplSyntaxOff

관련 정보