명령 앞에 인수가 있는 TeX 명령

명령 앞에 인수가 있는 TeX 명령

\mycmd하나의 인수를 취하는 명령을 얻기 위해 TeX 마법을 사용할 수 있습니까?~ 전에명령과 하나나중에. 그래서 <arg1>\mycmd<arg2>. 나는 노력했다

\documentclass{memoir}
\def#1\mycmd#2{Hello World of #1 and #2}
\begon{document}

{foo}\mycmd{bar}

\end{document}

하지만 분명히 실패했다. 어쨌든 그것이 효과가 있을 것이라고 기대했다고 말할 수는 없습니다.

답변1

문제는 다른 관점에서 검토되었다.명령 앞뒤에 인수가 있는 명령이 가능합니까?그러나 상황은 다릅니다. 주 명령 앞이나 뒤에 배치될 개체 자체가 매크로입니다.

"뒤를 돌아보는" 매크로를 갖는 것은 불가능합니다. TeX은 매크로 확장 이후 엄격하게 "선입 선출" 방식입니다. 게다가 매크로나 프리미티브에 인수를 제공하는 데 필요한 경우에만 입력을 토큰화합니다.

매크로 확장 후에는 확장 불가능한 토큰만 남게 되며, 발견된 순서대로 실행되어 제거됩니다. 그래서 다음과 같은 상황에서는

{abc}\macro{def}

검사할 때 그 {abc}부분은 이미 사라졌습니다 \macro. 이에 대한 추적은 일부 내부 목록에 남아 있을 수 있습니다. 예를 들어 TeX는 \unskip실행 시 현재 목록에서 마지막 노드를 제거하는 명령을 실행할 수 있습니다. , 그러나 이것은 기본적으로 진실입니다).

다음과 같은 명령것 같다당신이 원하는 것을 하는 것은 \over. 그러나 이것은 매크로가 아니라 프리미티브입니다.

그 작업은 내부 목록 수준에서 수행됩니다. TeX가 을 찾으면 \over확장할 수 없기 때문에 이를 실행합니다. 실행은 현재 수학 목록에 있는 모든 것을 특별한 장소에 저장하고 계속 진행하는 것으로 구성됩니다. 현재 수학 목록의 끝이 발견되면 TeX는 해당 목록과 저장된 부분을 사용하여프락머리 부분 목록을 분자로 하고 꼬리 부분 목록을 분모로 하는 원자입니다. 그러나 매크로 확장 수준에서는 이런 일이 발생하지 않습니다.

~할 수 있다\first인수 이후에 매크로가 \second나오는지 확인하고 수행할 작업에 대해 적절한 결정을 내리는 매크로가 있습니다 .

매크로 프로세서를 수정하지 않는 한 LuaTeX도 이를 수행할 수 없습니다. 왜냐하면 현재 목록에 있는 모든 유형의 노드를 검사하고 관리할 수 있기 때문입니다. 반면 TeX 기능은 더 제한적입니다(페널티, 글루, 커른 및 상자만 가능하며 모든 상황에 적용되는 것은 아닙니다). ).

답변2

귀하의 요구 사항가능하다예를 들어 encTeX를 사용합니다. 형식 별로 컴파일된 다음 코드를 시도해 보세요 csplain.

\mubyte \phantomcmd #1 {\endmubyte

\mubytein=0
\def\phantomcmd#1\mycmd#2{1=#1, 2=#2}
\def\mycmd{my}
\def\normalcmd#1{normal=#1}

\mubytein=1

\normalcmd{hello}    % gives: normal=hello 
...{foo}\mycmd{bar}  % gives: ...1=foo, 2=bar

\bye

\mubytein=1특수 입력이 활성화된 경우 : \phantomcmd문자가 나타날 때마다 이 삽입됩니다 {. 이는 토큰 및 확장 프로세서 이전에 수행됩니다. 그러나 예외가 있습니다. {토큰 프로세서에 의해 토큰화된 제어 시퀀스 바로 뒤에 오는 경우에는 \phantomcmd삽입되지 않습니다. 따라서 두 예제 모두 작동합니다: \normalcmd{hello}{foo}\cmd{bar}. 두 번째는 내부적으로 다음과 같이 작동합니다.

\phantomcmd{foo}\mycmd{bar}

원하는 대로 확장됩니다. 그러나 이 기술은 매우 취약합니다. 각 발생이 {제어 시퀀스 직후가 아니고 자동으로 \phantomcmd(when \mybytein=1) 앞에 오기 때문입니다. 예를 들어 다음과 같이 충돌이 발생합니다.

\normalcmd {hello}   % this is transformed to \normalcmd\phantomcmd{hello}
bb {foo}\mycmd{bar}  % 

이 예제와 이전 예제의 차이점을 확인하세요. 바로 뒤에 공백이 있습니다 \normalcmd.

이러한 취약성을 두려워하지 않는다면 \pfantomcmd다양한 프로세스를 정의할 수 있습니다 \mycmds.

\mubyte \phantomcmd #1 {\endmubyte
\mubytein=0
\def\phantomcmd#1{\def\tmp{#1}}
\def\mycmdA#1{I am A. before: \tmp, after: #1}
\def\mycmdB#1{I am B. before: \tmp, after: #1}
\mubytein=1
... {a}\mycmdA{b} ... {x}\mycmdB{y}
\bye

답변3

OP의 의견에서 해당 응용 프로그램은 서예 문자 이전에 미리 결정된 인용문 중 하나였다고 언급되었습니다. 내 의견 답변에서 말했듯이 문제가 더 제한될 수 있다면 희망이 있을 수 있습니다. 예를 들어, <arg1>가 제한된 catcode 12 가능성 세트에서 항상 단일 글리프인 경우 해당 글리프를 만들어 원하는 결과를 얻을 수 있으며 이를 따르는지 여부를 \active미리 확인할 수 있습니다 .\mycmd

이 접근 방식 은 소수점을 통해 치수를 지정하는 데 자주 사용되기 때문에 마침표 와 <arg1>같이 다른 매크로 내부에 가능성이 필요한 경우가 아니면 사용할 수 있습니다..<arg1>

MWE에서는 <arg1>\mycmd<arg2>Huge \fbox{<arg1><arg2>}. 에 대한 큰따옴표나 물음표를 가로채도록 설정했지만 <arg1>다른 catcode 12 <arg1>문자 모양을 추가할 수도 있습니다.

"불법" 값이 있는 호출을 무시하도록 편집되었습니다 <arg1>.

\documentclass{article}
\let\precommand\relax
\let\mycmd\relax
\def\testnext#1#2{\ifx#1\mycmd\myactualcmd\precommand{#2}\else\precommand#1#2\fi}
\def\myactualcmd#1#2{\if#1\precommand\fbox{\Huge#1#2}\else#1#2\fi}
\let\svquote"
\catcode`"=\active
\def"{\let\precommand\svquote\testnext}
\let\svqmark?
\catcode`?=\active
\def?{\let\precommand\svqmark\testnext}

\begin{document}
Is this is a "test"\textbf{?}  This is a "\mycmd{BIG} test?\mycmd{!}

Here mycmd is used with illegal precommand =\mycmd{which} is ignored.
\end{document}

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

관련 정보