0

The Short Story

If some text won't all fit on the current line, we want all of that text moved to the next line instead. How can we do this?

The Medium-Length Story

Suppose we have a string of text, "banana banana." Having the first few characters of "banana [...]" on the current line and the second half of the banana string the next line is undesirable.

If the entire string will fit on the current line, then good, put the string on the current line. Otherwise put the string on the next line.

Undesirable:

apples apples apples banana
banana. cantaloupe cantaloupe

Desirable:

% a line break is inserted at the beginning
% of the bananas because they won't all fit
% on the current line.

apples apples apples 
banana banana. cantaloupe cantaloupe

How can we write LaTeX code which makes this happen?

The Long Story

Consider the following test file. It will not compile because "KEEP TOGETHER" is not yet defined. The question can be viewed as: What do we need to do the make the following file produce the desired behavior?

\documentclass{minimal}
\begin{document}

apples apples apples apples
apples apples apples apples
apples apples apples apples 

\begin{KEEP TOGETHER}
    Banana tincidunt ante banana.
\end{KEEP TOGETHER}

cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe.

\end{document}

Suppose that STRYNG is the text block enclosed by \begin{KEEP TOGETHER} and \end{KEEP TOGETHER}. We wish to have the following behavior:

SPACER = four character indent based on
         current font size and other settings.

if (STRYNG will fit on what remains
               of the current line) { 
    WILL_FIT_HERE = true;
}
if (STRYNG will fit on an almost empty
    blank line, SPACER at the beginning) {
    WILL_FIT_NEXT = true;
}    
if [(not WILL_FIT_HERE) and (WILL_FIT_NEXT)] {
    print a line break
    print SPACER on the brand new empty line.
    print all of STRYNG after the indent
    print a line-break.
else {
    print STRYNG in the output document as if STRYNG
    were not inside of a "KEEP TOGETHER" block.

    Exhibit the same behavior as if the
    lines \begin{KEEP TOGETHER} and
    \end{KEEP TOGETHER} were commented out.

    This probably means that STRYNG (or at least
    the beginning of string) will be printed on
    the current line.
}

Similar, but Different, Stack Exchange Questions

Q1

There is a question which embodies the same sentiments as the current question, but that question was much too vague. It was not clear what was wanted. Some people interpreted the question to mean, "how can we prevent a line break in the middle of a word?" They thought it was okay to have half of the string on on the current line and the second half on the next line. There were other interpretations as well.

Q2

The asker of prevent-line-break-in-a-span-of-text was interested in displaying URLs containing no space characters. Like me, they want a line break inserted at the very beginning of their text, instead of in the middle. However, they do not describe what behavior they want if the URL cannot all fit on one line. In the question you are reading, I do describe what behavior is desired in that instance. Also, for the other asker, maybe LaTeX was inserting line break into their urls before the right-margin was reached. Maybe they wanted characters in the URL to run all the way to the right-margin, and only then have a line break inserted then, but not any earlier than that. I am not sure what they wanted.

Q3

The question How to do a conditional line-break is about using \\ in LaTeX code on a line with no proceeding text:

blah blah \\ % no error
\\           % Error. no text proceeds `\\`

Unacceptable Solutions

Unacceptable: Always put a line break at the beginning

always inserting a line-break looks funny if there was plenty of space on the line above to fit the text you want to keep together.

Unacceptable: Non-breaking spaces (~)

Writing things like Cras~mattis~tincidunt~ante is not okay for a few reasons. For one, ~ must be inserted everywhere, which is a nuisance. Another is that the string to be "kept together," might not contain any space characters, won't all fit on the current line, but could fit on a new line all by itself. We want something similar to \begin{command}{BLOCK OF TEXT}\end{command}.

Unacceptable: \nolinebreak

\nolinebreak works once EXACTLY where you put it and then is not in effect after that point. Inserting \nolinebreak in a dozen different places would make the source code unreadable. The issue is similar to using ~.

8
  • Off-topic. I like very much the way you tell us your "story". It is for all the public. :)
    – manooooh
    Jan 13, 2019 at 4:32
  • One can create an unbreakable group using \mbox, although it will look awful without \raggedright. OTOH, getting the parser to recognize repeated words would be difficult, at best. See tex.stackexchange.com/questions/233085/… as a start. Jan 13, 2019 at 18:23
  • It is not at all clear what your example is intended to demonstrate or how it can be used to test answers. The string Banana tincidunt ante banana. is at the start of a paragraph so it will be on one line unless you make it wider than the text width, at which point your algorithm suggests the environment should be ignored, so just removing \begin{KEEP TOGETHER} and \end{KEEP TOGETHER} would meet the requirements. Jan 14, 2019 at 22:51
  • @DavidCarlisle You are getting a little too fixated on that example. We seek a general solution which will work for many different input strings. Suppose someone asks, how can I implemented a square root function? This persons says, "as an example, we want sqrt(25) to return 5" Well, you could say, "Regardless of the input, write a function which always returns 5. That will work great, so long as you only ever try to take the square root of 25. In my case, the LaTeX solution should work even if the strings are different than the example I gave. Jan 15, 2019 at 0:53
  • @DavidCarlisle If it can all fit on the same line as the last of [...] apples apples apples, thenBanana tincidunt ante banana should not be the beginning of a new paragraph. The idea is to put Banana [...] banana on the same line as the apples if all of it will fit. We don't want Banana [...] banana interrupted by line breaks. If Banana [...] banana` won't all fit on the same line as the last of apple [...] apples, we insert a line break before Banana [...] banana. Jan 15, 2019 at 1:00

1 Answer 1

2

enter image description here

Probably does what you need

\documentclass{minimal}
\newcommand\zz[1]{\leavevmode
\hskip 0pt plus 1fill\penalty0 \hskip 0pt plus -1fill
\sbox0{#1}\ifdim\wd0>\linewidth\unhbox0\else\usebox0\fi\relax
}

\begin{document}

apples apples apples apples
apples apples apples apples
apples apples apples apples 
appples apples appples apples
appples apples
\zz{Banana tincidunt ante banana.}
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe.

apples apples apples apples
apples apples apples apples
apples apples 
appples apples
\zz{Banana tincidunt ante banana.}
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe.

apples apples apples apples
apples apples apples apples
apples apples apples apples 
appples apples
\zz{Banana tincidunt ante banana.
Banana tincidunt ante banana.
Banana tincidunt ante banana.
Banana tincidunt ante banana.}
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe cantaloupe
cantaloupe cantaloupe.

\end{document}
3
  • Your answer creates line overflow. If we add a large amount of additional text to the end of Banana tincidunt ante banana. then the result runs past the right margin of the page and into oblivion. Jan 15, 2019 at 3:09
  • @IdleCustard As I said in comments last night, you should have provided a file that tested the problem you were asking about... However try now. Jan 15, 2019 at 8:06
  • Suppose we want a mathematical formula. The following example is quite short: \zz{$F(x) = x$} However, even if there is plenty of room to print the F(x) = x on the current line, your \zz command moves F(x) = x to the next line. If the entire formula fits on the current line, we want the formula on the current line. We only want the formula to be moved to the next line if the formula won't fit on the current line. Jan 19, 2019 at 2:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .