
두 개의 인수를 취하고 첫 번째 인수에서 두 번째 인수를 포함하는 상자의 오른쪽 여백이 해당 단락의 왼쪽 여백에 정렬되고 해당 상자의 참조점이 수직으로 있는 새 단락을 만드는 명령을 정의하는 방법 해당 단락 텍스트의 첫 번째 줄의 기준선은 무엇입니까?
만약 내가한다면
\long\def\Command#1#2{\leavevmode\llap{#2}#1}
\Command{The text of the paragraph.}{Left justified?}
\Command{\noindent The text of the paragraph.}{Left justified?}
\bye
, 그러면 (예상대로) \noindent
효과가 없으며 "왼쪽 정렬?"이라는 문구가 포함된 상자의 오른쪽 여백이 표시됩니다. 단락의 왼쪽 여백에 맞춰지지 않고 문자 왼쪽에 맞춰집니다 T
.
\leavevmode
I 대신에 \noindent
"Left justified?"라는 문구가 포함된 상자의 오른쪽 여백이 표시됩니다. 은 단락의 왼쪽 여백과 문자의 왼쪽 모두에서 정당화되지만 의 첫 번째 인수 의 일부로 "손으로" 추가하지 않는 한 문자 앞에 -glue T
가 없습니다 .\parindent
T
\Command
\long\def\Command#1#2{\noindent\llap{#2}#1}
\Command{The text of the paragraph.}{Left justified?}
\Command{\noindent The text of the paragraph.}{Left justified?}
\bye
그래서 TeXbook의 이해하기 어렵고 모호한 문구를 분석하는 데 며칠을 보낸 후에 나는 내가 원하는 것을 달성하지 못하는 방법을 찾았고 내 시도가 효과가 없는 이유만 알게 되었습니다.
누군가가 방법을 지적해 줄 수 있을까요?하다일하다?
답변1
답변2
나는 당신의 의견을 받아들였습니다
거의. 감사합니다.
\Command{\hbox{This box should be part of the paragraph, too} text text}{Left justified?}
잘 안 된다...
~에데이비드 칼라일의 답변계정에:
\parindent
가로모드 시작시 폭의 가로박스를 제작하여 후크를 걸지 않고 세팅합니다 \everyhbox
.
따라서 /가 이전에 트리거되는 \if...
경우 -스위치를 설정하는 메커니즘을 만들 수 있습니다 .\everyhbox
\everyvbox
\everypar
\Command
의 첫 번째 인수 에서 임시 수직 상자를 만듭니다 .
임시 수직 상자를 생성하는 동안 -스위치를 전역적으로 설정하는 후크 \everyhbox
/ \everyvbox
매크로 토큰 앞에 추가합니다 \if...
.
각 후크 앞에 \everyhbox
/ \everyvbox
및 \everypar
지시문을 추가하여 모든 후크를 복원합니다.
효과:
또는 \everypar
이전에 수행되는 경우 후크가 복원되므로 / 에 추가된 -스위치를 변경하라는 지시문이 사라지고 수행되지 않습니다.\everyvbox
\everyhbox
\if..
\everyhbox
\everyvbox
\everyvbox
또는 \everyhbox
이전에 수행되는 경우 -switch를 \everypar
설정하라는 지시문이 \if
한 번 수행되고 모든 후크가 복원됩니다.
세 개의 후크( \everypar
, \everyvbox
, \everyhbox
)가 포함되어 있으므로 튜플 목록을 제공할 수 있는 재귀 루틴을 정의했습니다 \prependtorestorehooks
. 첫 번째 구성 요소는 후크를 나타내고 두 번째 구성 요소는 튜플 목록의 모든 후크를 복원하고 전달하기 전에 이 후크가 전달할 토큰을 나타냅니다. 재정의하기 전에 후크가 전달한 토큰도 있습니다.
메커니즘/ \Command
이 중첩된 경우에도 몇 가지 예방 조치가 필요합니다.
주의사항:
후크에 추가/후크 복원은 후크 자체에 -token이 포함되어 있지 않은 경우에만 작동합니다
\outer
. 예를 들어, 다음 코드는 오류 메시지를 생성합니다! Forbidden control sequence found while scanning text of \everypar.
.\begingroup \everypar={\problem}% \outer\def\problem{How to overcome the problem?}% \everypar=\expandafter{\the\everypar Again: How to overcome the problem?}% \endgroup \bye
\everyhbox
/ 는 /\everyvbox
를 생성할 때 해당 상자가 출력 파일에 포함되거나 내용이 출력 파일에 포함되지 않는 박스 레지스터로 들어가는지 여부에 관계없이 트리거됩니다. 따라서 메커니즘은 예를 들어 의 인수 시작 부분에 -할당을 배치하여 속일 수 있습니다.\hbox
\vbox
\setbox
\Command
/ 가 이전에 트리거되는 경우 -switch를 설정하기 위한 의 첫 번째 인수 에서 임시가
\vbox
생성됩니다 . 따라서 의 첫 번째 인수의 자료는 두 번 처리됩니다. 한 번은 임시 상자를 생성하기 위한 것입니다. 출력 파일에 들어가야 하는 단락을 만들기 위한 것입니다. 두 번 다시 하고 싶지 않은 일이 있을 수도 있습니다 . 불행하게도 이러한 기능을 끌 수 있는 "get-box-properties"/"box-measuring" 모드는 없습니다.\Command
\if...
\everyhbox
\everyvbox
\everypar
\Command
\immediate\write
\long\def\firstoftwo#1#2{#1}%
\long\def\secondoftwo#1#2{#2}%
%\prependtorestorehooks{%
% {{hook 1}{prepend 1}}%
% {{hook 2}{prepend 2}}%
% ...
%}%
\long\def\prependtorestorehooks#1{%
\prependtorestorehookscreraterestore{}{#1}#1\relax
}%
\long\def\prependtorestorehookscreraterestore#1#2#3{%
% #1 - Restore-List created so far
% #2 - entire list
% #3 - next element
\ifx\relax#3\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{\prependtorestorehooksprependtohooks{}{#1}#2\relax}%
{%
\prependtorestorehooksextract#3{#1}{#2}%
}%
}%
\long\def\prependtorestorehooksextract#1#2{%
\expandafter\prependtorestorehooksextractinner\expandafter{\the#1}{#1}%
}%
\long\def\prependtorestorehooksextractinner#1#2#3{%
\prependtorestorehookscreraterestore{#3#2={#1}}%
}%
\long\def\prependtorestorehooksprependtohooks#1#2#3{%
%#1 prepend-list-created so far
%#2 restore-list
%#3 {hook}{prepend}
\ifx\relax#3\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{#1}{%
\prependtorestorehooksprependtohooksb#3{#1}{#2}%
}%
}%
\long\def\prependtorestorehooksprependtohooksb#1{%
\expandafter\prependtorestorehooksprependtohooksc\expandafter{\the#1}{#1}%
}%
\long\def\prependtorestorehooksprependtohooksc#1#2#3#4#5{%
\prependtorestorehooksprependtohooks{#4#2={#3#5#1}}{#5}%
}%
%------------------------------------------------------------------------------------
\newbox\MyBox
\newif\ifleadingbox
\newif\ifintestbox\intestboxfalse
\newif\ifhookdone\hookdonefalse
\def\firstindent{}%
\long\def\setifleadingboxandfirstindent#1{%
\begingroup
\ifintestbox\else\global\hookdonefalse\global\leadingboxfalse\fi
\setbox\MyBox=\vbox{%
\intestboxtrue
\prependtorestorehooks{%
{{\everypar}{\ifhookdone\else\setbox\MyBox=\lastbox\xdef\firstindent{\the\wd\MyBox}\box\MyBox\global\hookdonetrue\fi}}%
{{\everyhbox}{\ifhookdone\else\global\leadingboxtrue\global\hookdonetrue\fi}}%
{{\everyvbox}{\ifhookdone\else\global\leadingboxtrue\global\hookdonetrue\fi}}%
}%
#1%
}%
\endgroup
}%
\long\def\Command#1#2{%
\par
\setifleadingboxandfirstindent{#1}%
\prependtorestorehooks{{{\everypar}{\setbox\MyBox\lastbox\llap{#2}\box\MyBox}}}%
\ifleadingbox\leavevmode\else\noindent\hbox to\firstindent{\hfill}\fi#1%
}%
\leavevmode
\kern-1in
\noindent test \hfill test \hfill test
\setifleadingboxandfirstindent{a}%
\ifleadingbox some \else no \fi leading h-or vbox.
\ifleadingbox\else Paragraph is indented by: \firstindent\fi
\smallskip\hrule\smallskip
\setifleadingboxandfirstindent{\hbox{a}}%
\ifleadingbox some \else no \fi leading h-or vbox.
\ifleadingbox\else Paragraph is indented by: \firstindent\fi
\smallskip\hrule\smallskip
\setifleadingboxandfirstindent{\vbox{a}}%
\ifleadingbox some \else no \fi leading h-or vbox.
\ifleadingbox\else Paragraph is indented by: \firstindent\fi
\smallskip\hrule\smallskip
\setifleadingboxandfirstindent{\noindent\vbox{a}}%
\ifleadingbox some \else no \fi leading h-or vbox.
\ifleadingbox\else Paragraph is indented by: \firstindent\fi
\smallskip\hrule\smallskip
\noindent {\bf Test 1:}
\Command{The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 2:}
\Command{\noindent The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 3:}
\Command{\hbox to 5cm{The\hfill wide\hfill text} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 4:}
\Command{\noindent\hbox to 5cm{The\hfill wide\hfill text} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 5:}
\Command{\vtop{\hbox to 5cm{The\hfill wide\hfill text}\hbox to 5cm{The\hfill wide\hfill text}} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 6:}
\Command{\noindent\vtop{\hbox to 5cm{The\hfill wide\hfill text}\hbox to 5cm{The\hfill wide\hfill text}} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 7:}
\Command{\vbox{\hbox to 5cm{The\hfill wide\hfill text}\hbox to 5cm{The\hfill wide\hfill text}} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 8:}
\Command{\noindent\vbox{\hbox to 5cm{The\hfill wide\hfill text}\hbox to 5cm{The\hfill wide\hfill text}} of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 9:}
\newdimen\MyDimen
\setbox\MyBox=\hbox{Left justified?}
\MyDimen=\wd\MyBox
\Command{\noindent\kern\MyDimen The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 10:}
\Command{\leavevmode\kern\MyDimen The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 11:}
\Command{\noindent\kern\MyDimen \hbox{\vbox{\advance\hsize-\MyDimen\Command{\noindent The text of the paragraph.}{Left justified?}}}}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 12:}
\Command{\noindent\kern\MyDimen \hbox{\vbox{\advance\hsize-\MyDimen\Command{The text of the paragraph.}{Left justified?}}}}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 13:}
\Command{\leavevmode\kern\MyDimen \hbox{\vbox{\advance\hsize-\MyDimen\advance\hsize-\parindent\Command{\noindent The text of the paragraph.}{Left justified?}}}}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 14:}
\Command{\leavevmode\kern\MyDimen \hbox{\vbox{\advance\hsize-\MyDimen\advance\hsize-\parindent\Command{The text of the paragraph.}{Left justified?}}}}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 15:}
\Command{\kern\MyDimen The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 16:}
% `\Command` starts with `\par`, i.e., by resorting to (restricted) vertical mode. Thus \kerns at the beginning of \Command's first argument in any case are vertical.
\Command{\kern\MyDimen\noindent The text of the paragraph.}{Left justified?}
\smallskip\hrule\smallskip
\noindent {\bf Test 17:}
% `\Command` starts with `\par`, i.e., by resorting to (restricted) vertical mode. Thus \kerns at the beginning of \Command's first argument in any case are vertical.
\Command{\kern\MyDimen\hbox{T}he text of the paragraph.}{Left justified?}
\smallskip\hrule\bigskip
\noindent {\bf Test 18:}
\Command{The text of the paragraph. \par The text of the paragraph. \par The text of the paragraph.\Command{\noindent The text of the paragraph. \par The text of the paragraph. \par The text of the paragraph.}{Left justified?}}{Left justified?}
\smallskip\hrule\bigskip
\noindent{\bf !!!! But: !!!}
\bigskip
\noindent {\bf Test 19:}
\Command{\setbox\MyBox=\hbox{Something to trigger the every-hook}\noindent This text is indented although it should not be indented. The reason is the triggering of {\tt\string\everyhbox} by {\tt\string\setbox...} right at the beginning of {\tt\string\Command}'s first argument.}{Left justified?}
\bye
솔직히 말하자면:
왜 이 모든 것이 필요한지 모르겠습니다. 매뉴얼에는 \Command
TeX가 처리하기 전에 수직 모드로 전환된다고 나와 있습니다 #1
. 사용자는 명시적이 \leavevmode
거나 \noindent
수평 모드로 전환하는 데 필요한지 스스로 결정할 수 있습니다 .