2

I sometimes have long words that are unbreakable and end up sticking out into the right margin. I realize that there's nothing magical to be done about this and the only real solution is to break them or rewrite the text.

However, I'm trying to change the last-resort behavior so it breaks the line before the long word and sets it at its natural spacing, while justifying the rest of the paragraph.

I already found an answer on tex.sx that defines a command on a per-word basis, but this doesn't change the default behavior. Also, the \lword command from the linked answer causes the preceding line to be stretched slightly and inserts line breaks where they're not strictly necessary. I've attempted to fix these issues in my \Lword command.

Ideally, I'd also like the [draft] option to highlight these emergency line breaks.

Here are some examples of what I've tried so far:

output

\documentclass[draft]{article}
\usepackage{showframe}
\usepackage{ragged2e}
\usepackage{color}

% https://tex.stackexchange.com/a/62347/99343
\newcommand*\lword[1]{%
    \leavevmode
    \nobreak
    \hskip0pt plus\linewidth
    \penalty50
    \hskip0pt plus-\linewidth
    \nobreak
    \textcolor{red}{#1}%
}

% same as above, but with higher penalty and infinite stetch
\newcommand*\Lword[1]{%
    \leavevmode
    \nobreak
    \hskip0pt plus 1fil
    \penalty9999
    \hskip0pt plus -1fil
    \nobreak
    \textcolor{blue}{#1}%
}

\newcommand*\test[4]{{%
    #2%
    \strut\llap{\smash{\begin{minipage}[t]{8em}\RaggedLeft #1\end{minipage} }}%
    Aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
    #3{bbbbbbbbbbbbbbbbbbbbbbbbbbbbb}
    aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
    aaaa aaaa aaaa aaaa aaaa aaaa aaaaa
    #4{bbbbbbbbbbbbbbbbbbbbbbbbbbbbb}
    aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa.
    \par
}}

\setlength\parindent{0pt}
\setlength\parskip{1ex}

\begin{document}
    \test{default rendering}                           {}{}{}
    \test{manually inserted linebreak (desired result)}{}{\\}{}
    \test{lword macro}                                 {}{\lword}{\lword}
    \test{Lword macro (desired result)}                {}{\Lword}{\Lword}
    \test{sloppy}                                      {\sloppy}{}{}
    \test{emergencystretch}                            {\emergencystretch10em}{}{}
    \test{RaggedRight}                                 {\RaggedRight}{}{}
    \test{sloppy and RaggedRight}                      {\sloppy\RaggedRight}{}{}
\end{document}

Here's my actual question:

  • Is it possible to get this line breaking behavior without wrapping potential problem words in an extra command, and if so, how?
  • Failing that, do my changes to \lword have any possible side effects?
wrtlprnft
  • 3,859
  • 1
    I am curious, which language has bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb? At least in english, this is impossile. – Johannes_B Mar 14 '16 at 11:28
  • These are of course just placeholders. Imagine it to be an URI or some long CamelCase identifier that can't or shouldn't be hyphenated. – wrtlprnft Mar 14 '16 at 11:30
  • 2
    your Lword looks OK, and It's probably best to explicitly wrap each such word in the command (usually url and identifiers are already wrapped in some markup so it should not require much additional markup in the document) trying to do it automatically is bound to be fragile and break something. – David Carlisle Mar 14 '16 at 11:48
  • check this out http://tex.stackexchange.com/a/241355/90297 – Elad Den Mar 14 '16 at 12:14
  • @EladDen while that answer is (of course!) completely accurate, I'm not sure it helps here. – David Carlisle Mar 14 '16 at 12:18
  • @EladDen: Yes, I've read that answer before composing this question. It nicely summarizes \emergencystretch and \sloppy, but these commands never produce a short line in the middle of a paragraph. I consider a short line to be less disrupting than an extremely stretched one. – wrtlprnft Mar 14 '16 at 12:21
  • @DavidCarlisle: Thanks for looking at my macro. I've just noticed a problem with wrapping macros like \url: If there is a line break opportunity near the beginning of the word, I would need the \Lword magic to happen there, too. Maybe I should edit my question... – wrtlprnft Mar 14 '16 at 12:29
  • while logically that ought to be a different problem you Lword code is really a prefix it doesn't need to take the word as argument (other than for colour here) so should not interfere with \url line breaking – David Carlisle Mar 14 '16 at 12:36
  • @DavidCarlisle: Maybe I should have done so earlier, but now I'm thinking about something like \url{http://www.somelongdomainnamethatdoesnotwrap.com/} where the first period is too early and the second too late, but breaking at the first period would still reduce the shortness of the line. If I effectively do \Lword{\url{...}}, TeX will not break there. I guess I'll look if hyperref can be sufficiently customized for this. – wrtlprnft Mar 14 '16 at 12:39
  • 1
    you can not (easily) add glue-penalty-negativeglue combination mid url as it just uses the math \binopenalty to allow line breaking, but \Lword{\url{...}} should allow breaking anywhere within the url or breaking short and moving the whole url over. – David Carlisle Mar 14 '16 at 12:42

1 Answers1

1

In real life cases you'd just put \usepackage{microtype} into your preamble, which would help to solve most of your trouble.

Keks Dose
  • 30,892
  • I already do, but I still sometimes get them (URLs in bibliographies are especially annoying, because there's little one can do about an individual entry). Microtype definitely helps a lot in long paragraphs, though. – wrtlprnft Mar 17 '16 at 18:48