여기서 건너뛰기 해제가 작동하지 않는 이유는 무엇입니까?

여기서 건너뛰기 해제가 작동하지 않는 이유는 무엇입니까?

다음과 같이 사용할 매크로를 정의하려고 합니다.

\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
% underlining required by school - I know, I know

% later...

\thesis{
  This is the beginning of a multi-line thesis statement.
  I use one sentence on each line throughout my document.
  Thus, the thesis is broken as in XKCD 1285.
}

문제는 \unskip마지막 줄 바꿈을 삼키지 않는다는 것입니다. 주석(예: as in XKCD 1285.%)을 추가하면 예상대로 작동하지만 이것이 \unskip해야 할 일이 아닌가요?

초기 공간이 올바르게 먹혔습니다. 없이 \ignorespaces처음에 밑줄 친 공백이 있지만 \ignorespaces제거합니다. \unskip마지막에 밑줄 친 설명을 제거해야 하지만 그렇지 않습니다 .

내 이해는 그것이 \unskip일종의 \ignorepreviousspace. 이 올바른지?

MWE:

\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
\begin{document}
\thesis{
  Foo.
  Bar.
  Baz.
} % comment at end of previous line gives desired output
\end{document}

답변1

\uline인수를 구문 분석하여 텍스트를 단어로 나눕니다. 구문 분석된 단어를 상자에 넣어 너비를 측정하고 표시(선, 이중선, 물결 등)와 오버레이합니다. 따라서 \unskip새 단어의 시작 부분에서 상자의 시작 부분으로 이동합니다. 떼어낼 공간이 없습니다. 따라서 효과가 없습니다.

퍼팅\unskip ~ 후에 \uline{...}접착제를 제거하기 때문에 더 좋습니다. 하지만 \uline삽입그 중 공간의 장소에 있습니다. 첫 번째는 밑줄이 그어진 공간( \leaders)이고, 두 번째는 작은 음수 공간(-1/300인치)으로, 아마도 밑줄 부분이 더 잘 겹치도록 추가되었을 것입니다.

\unskip뒤에 하나만 추가 \uline하면기타, 현재 삭제된 답변(10,000명 이상의 사용자에게만 표시됨) 주석으로 줄 끝 부분을 \thesis제거하면 실수로 작동합니다. 단락 끝에서 TeX는 암시적 \unskip.

두 가지로 해결\unskip

\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand*{\thesis}[1]{%
  \uline{\ignorespaces #1}%
  \unskip\unskip
}

\begin{document}
Before. \thesis{
  Foo.
  Bar.
  Baz.
} After.
\end{document}

결과

패키지 솔루션trimspaces

다음 예에서는 패키지를 사용하여 trimspaces텍스트를 에 전달하기 전에 공백을 제거합니다 \uline. 이로 인해 솔루션이 \uline.

\documentclass{article}
\usepackage[normalem]{ulem}
\usepackage{trimspaces}
\makeatletter
\newcommand*{\thesis}[1]{%
  \def\thesis@text{#1}%
  \trim@spaces@in\thesis@text
  \expandafter\uline\expandafter{\thesis@text}%
}
\makeatother

\begin{document}
Before. \thesis{
  Foo.
  Bar.
  Baz.
} After.
\end{document}

답변2

Heiko는 문제 해결 방법에 대한 자세한 설명을 제공했기 때문에 하위 질문에 대한 의견만 제한하겠습니다.

내 이해는 그것이 \unskip일종의 \ignorepreviousspace. 이 올바른지?

기본적으로 아니요, 그 이해는 정확하지 않습니다. 완전히 다른 수준에서 작업합니다(그리고 \unskip 줄 바꿈이 다른 수준에서 다시 작동하기 전에).\ignorespaces%

약간 단순화된 TeX는 다음의 시퀀스를 읽습니다.문자파일에서 다음으로 변환토큰(문자 그룹을 명령 이름으로 읽거나 문자 토큰에 catcode 값을 할당하여) 그런 다음 이러한 토큰 목록이 처리되어 결국 수평 또는 수직을 생성할 수 있습니다.기울기조판 상자와 접착제.

%수준에서 작동합니다.문자. a가 %표시되면 해당 줄의 나머지 문자와 줄 끝의 줄 바꿈을 건너뛰고 전혀 토큰으로 변환되지 않습니다.

\ignorespaces수준에서 작동합니다.토큰. 명령이 끝에 영향을 미칠 때 공백이 아닌 첫 번째 토큰이 표시될 때 까지 \ignorespaces모든 공백 토큰(일반적으로 수직 모드에서 무시되거나 수평 모드에서 단어 간 접착 추가)이 무시됩니다.

\unskip수준에서 작동합니다.기울기. 이전 항목이 현재 가로 목록에 추가된 경우(공간에서 나오든 명시적 또는 암시적에서 나오든 현재 목록에서 제거 \vskip되어 \hskip폐기됩니다. (추가된 항목을 제거할 수 없는 페이지의 기본 세로 목록 제외) , \unskip작동하지 않습니다).

\ignorespaces연속된 공백 수를 무시하지만 \unskip하나의 글루 노드만 제거하는 다른 구조 참고(이 질문의 단락 끝 처리와 관련됨)에서 작동한다는 사실 외에도 . 물론 일반적으로 \ignorespaces두 개의 연속 토큰을 연속 공간으로 얻으려면 작업해야 하기 때문에 무시할 하나의 공간 토큰만 표시됩니다.문자단일 공간 토큰으로 토큰화됩니다. 그러나 예를 들어 \ignorespaces\space\space둘 다 무시합니다.

관련 정보