Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to define a macro to be used as follows:

\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.
}

The problem is that the \unskip doesn't gobble the final line break. If I add a comment (like as in XKCD 1285.%) then it works as expected, but isn't this what \unskip is supposed to do?

The initial space is gobbled correctly. Without \ignorespaces there is an underlined space at the beginning, but \ignorespaces removes it. The \unskip is supposed to remove the underlined statement at the end, but doesn't.

My understanding is that \unskip is kind of like \ignorepreviousspace. Is this correct?

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}
share|improve this question
2  
+1. Good question. –  Heiko Oberdiek Mar 18 at 0:41

2 Answers 2

up vote 16 down vote accepted

\uline parses its argument to divide the text into words. A parsed word is put into a box to measure its width and overlay it with the markings (line, double line, wave, ...). Therefore \unskip goes at start of a new word to the begin of a box. There is no space to remove. Thus it is without effect.

Putting \unskip after \uline{...} is better because it removes glue. But \uline inserts two of them at the place of a space. The first is the underlined space (\leaders), the second is a small negative space (-1/300 in), probably added to get a better overlapping of the underline segments.

Adding only one \unskip after \uline in the other, now deleted answer (visible only for 10K+ users), if the line end after \thesis is removed by a comment, works by an accident. At the end of a paragraph TeX removes the last space by an implicit \unskip.

Solution with two \unskip

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

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

Result

Solution with package trimspaces

The next example uses package trimspaces to remove the spaces before passing the text to \uline. This makes the solution more independent from the implementation of \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}
share|improve this answer
    
Heiko, the other answer is deleted and therefore only visible for users with reputation from 10000 on. I added regarding information, but perhaps you find yourself a better solution. –  Speravir Mar 20 at 0:18

Heiko has given a full description of how to solve the problem so I'll restrict to commenting on the sub-question

My understanding is that \unskip is kind of like \ignorepreviousspace. Is this correct?

Basically no, that understanding is not correct. \unskip and \ignorespaces work at completely different levels (and % before a linebreak works at another level again).

Simplified slightly, TeX reads a sequence of characters from the file, turning then into tokens (either by reading a group of characters as a command name, or assigning catcode values to character tokens) Then these lists of tokens are processed and may eventually produce horizontal or vertical lists of typeset boxes and glue.

% works at the level of characters. If a % is seen the rest of the characters on that line, and the linebreak at the end of the line are skipped and not turned into tokens at all.

\ignorespaces works at the level of tokens. After \ignorespaces all space tokens (which normally are ignored in vertical mode, or add inter-word glue in horizontal mode) are ignored until the first non-space token is seen when the commands affect ends.

\unskip works at the level of lists. If the previous item added to the current horizontal list (whether coming from a space or from an explicit or implicit \vskip or \hskip is removed from the current list and discarded. (Except on the main vertical list on the page where you may not remove items once added, and \unskip is a no-op).

Apart from the fact that they are operating on different structures note (which is relevant to the processing at the end of a paragraph in this question) that \ignorespaces ignores any number of consecutive spaces but \unskip only ever removed one glue node. Usually of course \ignorespaces only sees one space token to ignore as you have to work to get two consecutive tokens as consecutive space characters are tokenised as a single space token. But for example \ignorespaces\space\space would ignore both.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.