나는 \span
원시적인 것에 몇 번 부딪혔습니다. .NET 프로그램이 아니라 TeX 프로그램에 정의되어 있다는 인상을 받았습니다 plain.tex
. 그렇죠? 그리고 뭐하다그 명령은 무엇을 위한 것입니까?
답변1
프리미티브는 본문의 서문 이나 본문에 \span
나타나는 경우 매우 다른 두 가지 의미를 갖습니다 .\halign
그것이 서문에 있는 경우, 이는 첫 번째 토큰 이전에 \cr
다음 토큰을 "확장"한다는 의미입니다. 본문에 나타나면 현재 셀을 종료하지만 다음 셀과 병합합니다. 이 경우 일반적으로 와 결합됩니다 \omit
.
가장 간단한 예는 다음과 같습니다.
\halign{\hfil#\tabskip1em&#\hfil\cr
a&b\cr
c\span d\cr
}
여기서 두 번째 행에는 셀이 하나만 있습니다. 출력은 다음과 같습니다
"c"와 "d" 사이에 공백이 없습니다 \tabskip
. 두 번째 행은 \hfil
내용 앞뒤가 있는 하나의 셀이지만 TeX는 \tabskip
셀 너비를 결정할 때 이를 고려합니다.
그러나 일반적 \omit
으로 제거하기 위해 추가하기도 합니다.유그리고V부속 (유앞에 오는 것을 가리킨다 #
.V그 뒤에 오는 것).
TeX가 서문을 읽을 때 \halign
발견하지 않는 한 토큰을 확장하지 않습니다 \tabskip
(적절한 글루 사양을 찾기 위해 토큰을 확장할 때). 토큰 확장은 토큰 앞에 를 붙여 강제로 수행할 수 있습니다 \span
.
예는 다음과 같습니다.amsmath.sty
\def\align@#1#2{%
\inalign@true \intertext@ \Let@ \chardef\dspbrk@context\z@
\ifingather@\else\displ@y@\fi
\let\math@cr@@@\math@cr@@@align
\ifxxat@\else \let\tag\tag@in@align \fi
\let\label\label@in@display
#1% set st@r
\ifst@rred\else \global\@eqnswtrue \fi
\measure@{#2}%
\global\row@\z@
\tabskip\eqnshift@
\halign\bgroup
\span\align@preamble\crcr
#2%
}
align
이것은 및 친구를 위해 사용되는 도우미 매크로입니다 . 프리앰블은 매크로에서 단번에 정의됩니다.\align@preamble
\def\align@preamble{%
&\hfil
\strut@
\setboxz@h{\@lign$\m@th\displaystyle{##}$}%
\ifmeasuring@\savefieldlength@\fi
\set@field
\tabskip\z@skip
&\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
\ifmeasuring@\savefieldlength@\fi
\set@field
\hfil
\tabskip\alignsep@
}
\align@
이는 매크로에 많은 양의 코드를 배치하여 정의를 크게 단순화합니다 . 또한 align
수정하여 동작을 변경할 수도 있습니다 \align@preamble
(참조:홀수 열에 암시적으로 접두사 {}를 붙이는 것이 가능합니까?).
LaTeX 커널은 에 대해 다른 방법을 사용합니다 tabular
. 왜냐하면 규칙, 즉 lcrp
문자 조합 등에 따라 서문을 작성해야 하기 때문입니다.
의 두 번째 사용법 \span
은 \halign
. Plain TeX에서 우리는 다음을 찾습니다.\multispan
\def\multispan#1{\omit \mscount#1\relax
\loop\ifnum\mscount>\@ne \sp@n\repeat}
\def\sp@n{\span\omit\advance\mscount\m@ne}
이는 인수에 명시된 만큼 \omit
의 쌍을 추가하고 추가합니다 (1 빼기). \span\omit
so는 , to 등과 \multispan{1}
동일합니다 . LaTeX의 매크로 는 동일한 아이디어를 바탕으로 구축되었습니다.\omit
\multispan{2}
\omit\span\omit
\multicolumn
% latex.ltx, line 5053:
\long\def\multicolumn#1#2#3{\multispan{#1}\begingroup
\@mkpream{#2}%
\def\@sharp{#3}\set@typeset@protect
\let\@startpbox\@@startpbox\let\@endpbox\@@endpbox
\@arstrut \@preamble\hbox{}\endgroup\ignorespaces}
먼저 수행한 다음(Plain에서와 정확히 동일하게 정의됨) 필수 인수를 평가 하고 사용된 것과 \multispan{#1}
동일한 것을 사용하여 "로컬" 정렬 프리앰블을 구축합니다 .\@mkpream
tabular
array
Knuth는 왜 두 가지 매우 다른 의미에 동일한 기본 단어를 사용했습니까? 공간을 절약하기 위해; TeX는 컴퓨터 메모리 공간이 부족할 때 작성되었으며 정의를 저장하는 것이 중요했습니다. (또는 물론) \span
에만 나타날 수 있으므로 문제 가 되지 않습니다.\halign
\valign
첫 번째 의미 의 의 잘못된 사용법은 \span
TeXbook의 연습 20.16 솔루션에 나타납니다.
다음 사항을 너무 심각하게 받아들여서는 안 되지만 실제로는 효과가 있습니다.
{\setbox0=\vbox{\halign{#{\c\span\d}\cr \let\next=0\edef\next#1{\gdef\next{\b#1}}\next\cr}}} \let\a=\next
연습에서는 및 를 사용하지 않고 (완전히 확장됨) 다음에 (확장되지 않음) 및 (한 번만 확장됨)이 \a
오는 것을 정의하는 방법에 대해 설명합니다 . 예를 들어,\b
\c
\d
\noexpand
\the
\def\foo{xy\baz}
\def\baz{z}
\def\b{\foo\foo}
\def\c{--}
\def\d{\baz}
\a
대체 텍스트로 포함하도록 정의하고 싶습니다.
xyzxyz\c\baz
그 부분은 아무런 출력 없이 \setbox0=\vbox{
그냥 사용하는 것입니다 . \halign
이제 TeX는 \halign
프리앰블을 로 평가합니다 #{\c\baz}\cr
. 왜냐하면 의 \span
한 수준 확장이 발생하기 때문입니다 \d
. 유일한 셀에는 다음이 포함됩니다.
\let\next=0\edef\next#1{\gdef\next{\b#1}}\next
규칙에 따라 #
서문 대신 사용되므로 입력 스트림은 다음과 같습니다.
\let\next=0\edef\next#1{\gdef\next{\b#1}}\next{\c\baz}\cr
셀이 종료 되므로 \cr
관련이 없습니다. 때문에 는 \let\next=0
확장 \next
할 수 없게 되므로 마치 확장할 수 없었던 것처럼 정의됩니다 \edef
.\next
\def\next#1{\gdef\next{<full expansion of \b>#1}}
그래서 \next{\c\baz}
충실하게 실행될 것입니다
\gdef\next{<full expansion of \b>\c\baz}
그리고 결승전이 \let\a=\next
모든 것을 끝낸다.
이것은 잘 설명 \span
됩니다.하나확장 단계.
e-TeX를 사용한 다른 솔루션( 결국 \noexpand
및 를 사용하지 않음 \the
)은 다음과 같습니다.
\edef\a{\b\unexpanded\expandafter{\expandafter\c\d}}