為什麼 unskip 在這裡不起作用?

為什麼 unskip 在這裡不起作用?

我正在嘗試定義一個要使用的宏,如下所示:

\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。它是否正確?

微量元素:

\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其他,現已刪除的答案(僅對 10K+ 使用者可見),如果後面的行尾\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

下一個範例使用 packagetrimspaces在將文字傳遞給 之前刪除空格\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會忽略兩者。

相關內容