# Pleasing line breaks with extremely long words that must fit on the page

I'm typesetting some technical documentation that includes identifiers with very long names. It is unacceptable to break or hyphenate these names because that would look confusingly like juxtaposed identifiers or subtraction and make the output PDF not searchable. It is also unacceptable if a name extends outside the physical page. It's ok to have the occasional overfull hbox, allowing the identifiers to extend into the right margin, as long as they remain inside the page.

Within these constraints, I of course want the output to look as nice possible. However, I can't afford to spend time fine-tuning each paragraph to add \sloppy or \raggedright or similar declarations. In some parts of the document, I simply cannot do it because the LaTeX code is generated by a tool that does not allow me to inject arbitrary LaTeX inside the text. It's up to TeX to find the right method from the parameters I set once and for all.

The tools I've found to solve the basic problem are \sloppy, \raggedright, and \RaggedRight from ragged2e. None of them work well for me.

MWE:

\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}

\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{UIViewControllerTransitionCoordinatorContext} or even
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
\par
}
}

\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}


\sloppy meets the hard constraints but allows spaces to stretch a lot which reduces readability. \raggedright also meets the hard constraints but the white space on the right is huge (waste of paper) and uneven (ugly). \RaggedRight fails to make everything fit on the physical page. \RaggedRight plus \sloppy is my best bet, but it's markedly inferior to normal left-and-right justification for long stretches of text.

How can I both meet the hard constraints (fit some ridiculously long words without breaking), and get good-looking output (especially in paragraphs with no long identifiers)? For example, in the sample paragraph above, I'd like the output from “Default”, but with a line break after “even”.

• is it possible to identify these as something other than \texttt? if so, it might be possible to precede them with an explicit local encouragement to break. also, is your default paper lettersize or a4? – barbara beeton Jan 8 '15 at 17:39
• @barbarabeeton I have documents generated by pandoc which produces \texttt. These are whole documents so I could redefine \texttt if that helps. (I also have handwritten documents, and possibly in the near future other code generators which might generate \verb or something else.) My default paper size is a4, why does it matter? – Gilles 'SO- stop being evil' Jan 8 '15 at 18:20
• There is no way to have pleasant line breaks with such unbreakable monstrosities. Forget it and try making it less bad as possible, that is, with \raggedright. – egreg Jan 8 '15 at 20:57

This answer is a completely different approach than my other answer. It's goal is to lead the \textt expressions with breakable fill, so that the long words can, if necessary, occupy lines by themselves.

The method does not break up any of the identifier words.

The heart of the method is

\let\svtexttt\texttt
\newcommand\Texttt[1]{\hfil\discretionary{}{}{}\relax\svtexttt{#1}}


which can be used independently or, as I have done here, \let to replace \texttt.

One issue the OP noted is if the paragraph ends on a \texttt, there can be excessive horizontal space. One can manually overcame that (possibly rare) situation by adding a double \hfill to the end of the paragraph, which I call \Hfill in my MWE.

\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}

\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{UIViewControllerTransitionCoordinatorContext} or even
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
But some names are \texttt{Short} too.
\texttt{ThisIsSuchAnExtremelyLongName} \texttt{TheNameGoesOnAndOnMyFriend}
\Hfill% THIS CAN HELP WHEN \texttt FOUND AT PARAGRAPH ENDS
\par
}
}
\def\Hfill{\hfill\hfill}
\let\svtexttt\texttt
\newcommand\Texttt[1]{\hfil\discretionary{}{}{}\relax\svtexttt{#1}}
\let\texttt\Texttt
\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}


• Ah, now that looks promising, but why did you include \hfill at the end? That makes “or” stick out, which ws basically my problem with sloppy. I think this should be a negatively stretchable space (I might not remember the terminology correctly, my TeX is a bit rusty), so as to allow the identifier to stick in the margin a bit, can you remind me how to do this? – Gilles 'SO- stop being evil' Jan 8 '15 at 21:07
• @Gilles I included a second version that might be more to your liking. – Steven B. Segletes Jan 8 '15 at 21:16
• Unfortunately, that looks good when the long identifier happens to be at the end of a line, but I don't see how not to make things really bad when the identifier isn't at the end of a line. E.g. add But some names are \texttt{short} too. at the end of the text. Or \texttt{ThisIsSuchAnExtremelyLongName} \texttt{TheNameGoesOnAndOnMyFriend} – Gilles 'SO- stop being evil' Jan 8 '15 at 21:31

This answer does not satisfy the needs of the OP, because the accsupp approach, while working with Adobe Acrobat, does not work across the full range of PDF readers that the OP needs to support. Nonetheless, I leave it here as it may be of use to others with similar challenges.

Applying a variation of egreg's use of the lowercase trick (How to emulate \url hyphenating without using the url package?), I create \Texttt{} which makes, in this case 3 uppercase letters active (you might want to extend that to more letters for general use case), to allow discretionary line breaks. As you see, for the OP's MWE, it works in the default case, allowing breaks at those specified uppercased (now active) letters.

Here's where the EDIT comes in.

However, the OP stressed that linebreaks in the identifiers would disturb a requirement of PDF search and copy/paste. So I then drew on my answer at Is there such thing as "visual-only whitespace"? to cast the answer in "visual only" whitespace, so that the identifiers remain intact in copy/paste, even as they experience linebreaks on the visual page (this uses the accsupp package). At this point, it is the \ncs{} macro that should be called for these long identifier arguments, which in turn calls on \Texttt{}.

Further, the OP agreed (in comments that follow this post) to allow/consider special hyphen markings (not a -), as long as they too (like the linebreaks themselves) were not part of a PDF copy/paste. So, for demonstration purposes, I am using a right arrow $\rightarrow$ as the identifier hyphen. Since the \IDhyphen is in a box, any notation may be used for the identifier hyphen.

Ideally, the user's code should call on \ncs{} for these long identifiers. However, for this MWE, I \let\texttt\ncs as a full replacement for \texttt. However, that can be dangerous if you call on upper-cased named macros within a \texttt argument. Better would be to just use \ncs for these special long words.

\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}
\usepackage{accsupp}
\newcommand\ncs[1]{%
\def\actual{}\ncshelper#1 \relax%
\BeginAccSupp{method=escape,ActualText=\actual}%
\Texttt{#1}%
\EndAccSupp{}%
}
\def\ncshelper#1 #2\relax{\edef\actual{\actual#1}%
\if\relax#2\relax\else\ncshelper#2\relax\fi}
%
\newcommand{\Texttt}[1]{%
\begingroup
\ttfamily
\begingroup\lccode~=R\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{R}{R}}%
\begingroup\lccode~=I\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{I}{I}}%
\begingroup\lccode~=C\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{C}{C}}%
\catcodeR=\active\catcodeI=\active\catcodeC=\active
\scantokens{#1\noexpand}%
\endgroup%
}
\let\texttt\ncs
\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{UIViewControllerTransitionCoordinatorContext} or even
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
\par
}
}
\newsavebox\IDhyphenbox
\savebox\IDhyphenbox{$\rightarrow$}
\def\IDhyphen{\usebox{\IDhyphenbox}}
\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}


A copy paste of the Default paragraph, using Adobe Acrobat as the viewer, yields the following, demonstrating that the identifiers remain intact. Furthermore, the Adobe search on the full identifier string meets with success, even if the identifier is broken across lines. (Note there are ligature issues during copy/paste, but that is a different problem the OP will have to grapple with, though ligatures will not affect the \ttfamily content)

Some libraries dene extremely long names such as AVAssetResourceLoadingContentInformationRequest

• I do not want to break identifiers! This is even worse than hyphens — it looks like there's an identifier AVAssetResourceLoadingContent and a different identifier InformationRequest. – Gilles 'SO- stop being evil' Jan 8 '15 at 18:21
• @Gilles When you say you don't want to break identifiers, am I to understand that these long \texttt` words must remain wholly intact on a single line? No exceptions? – Steven B. Segletes Jan 8 '15 at 18:26