3

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{AVAssetResourceLoadingContentInformationRequest} or
    \texttt{UIViewControllerTransitionCoordinatorContext} or even
    \texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
    (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}

MWE output

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

3
  • 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? Jan 8, 2015 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? Jan 8, 2015 at 18:20
  • 4
    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, 2015 at 20:57

2 Answers 2

3

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{AVAssetResourceLoadingContentInformationRequest} or
    \texttt{UIViewControllerTransitionCoordinatorContext} or even
    \texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
    (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}

enter image description here

3
  • 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? Jan 8, 2015 at 21:07
  • @Gilles I included a second version that might be more to your liking. Jan 8, 2015 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} Jan 8, 2015 at 21:31
4

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}}%
  \catcode`R=\active\catcode`I=\active\catcode`C=\active
  \scantokens{#1\noexpand}%
  \endgroup%
}
\let\texttt\ncs
\newcommand{\mytext}[2]{
  \subsubsection*{#1}
  { #2 %
    Some libraries define extremely long names such as
    \texttt{AVAssetResourceLoadingContentInformationRequest} or
    \texttt{UIViewControllerTransitionCoordinatorContext} or even
    \texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
    (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}

enter image description here

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
or UIViewControllerTransitionCoordinatorContext or even MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification
(yeech!). It is unacceptable to hy-
phenate these very long names or for them to disappear o 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 para-
graphs tend to look bad without right justication.
9
  • 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. Jan 8, 2015 at 18:21
  • 1
    @Gilles Can you then describe the breaking priorities? For example, I could make it so that the uppercase breakpoint appears as the last character on the prior line, with the rest of the word on the next line. That would alleviate your criticism, do you think? Also, do you want hyphens inserted or not? Jan 8, 2015 at 18:23
  • @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? Jan 8, 2015 at 18:26
  • 1
    @StevenB.Segletes Maybe, if it allows the text to be copy-pasted and search as though it was unbroken, AND if it can be made to work in all the PDF readers that my readers use (at least Acroread, Foxit, Sumatra, Evince, Okular, OSX's viewer, and probably a few more). I find it quite jarring when reading, I'd have to see if people are ok with the visual effect, it may be ok with a visual indicator that doesn't look like any ASCII character. Jan 8, 2015 at 18:45
  • 1
    @Gilles Thank you for that update. I will leave my answer stand, as it might help others with a related, but not identical problem, or for those who wish to focus only on Acrobat compatible solutions. But, by all means, wait for a better answer that suits your needs. Jan 8, 2015 at 20:22

You must log in to answer this question.

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