4

I use \texttt to markup code. Sometimes I get lines like this which overflow the page since Latex doesn't line-break in \texttt

deserunt mollit anim id est laborum. The std::ostream::traits_type::eq function ...

I think I want to allow line breaks to happen before a :: in one of these, so line-braking the above to this would be acceptable:

deserunt mollit anim id est laborum. The std::ostream

::traits_type::eq function ...

This answer approaches what I want -- it allows line-breaking after a given single character -- but I can't see how to adapt it.

How do I write something which will line-break before a : in \texttt but only before the first : in a ::?

2

You can massage the string a bit:

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\cppstring}{m}
 {
  \tl_set:Nn \l_spraff_cppstring_tl { #1 }
  % change _ to a printable underscore
  \regex_replace_all:nnN { _ } { \cO\_ } \l_spraff_cppstring_tl
  % change :: to \linebreak[0]::
  \regex_replace_all:nnN { :: } { \c{linebreak}[0]:: } \l_spraff_cppstring_tl
  % print the result
  \texttt{ \tl_use:N \l_spraff_cppstring_tl }
 }
\tl_new:N \l_spraff_cppstring_tl
\ExplSyntaxOff

\begin{document}

\noindent % just for the example
unrecoverable error occurs during the transformation, then a
\cppstring{std::ostream::traits_type::eq}

\end{document}

enter image description here

This can be improved, for example, by doing \linebreak[0] only after the first ::. The simplest way is adding a further replacement

% remove the first \linebreak[0]
\regex_replace_once:nnN { \c{linebreak}\[0\] } {} \l_spraff_cppstring_tl

before printing the result.

Note that, differently from the strategy of making characters active, the command \cppstring can also go in the argument to other commands.

This has the advantage of also working with babel-french where colons are treated specially.


This does not do magic. The example with the text

lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum

\noindent % just for the example
unrecoverable error occurs during the transformation, then a
\cppstring{stdxxxxx::ostreamxxxxxx::traits_typexxxxx::eqxxxxxxx} lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum 

will not justify the paragraph, because the first opportunity at :: cannot be taken as it would create too wide spaces in the line.

In an emergency, when rewriting is impossible or unsuccessfull, you can use sloppypar:

lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum lorem ipsum  lorem ipsum

\begin{sloppypar}
\noindent % just for the example
unrecoverable error occurs during the transformation, then a
\cppstring{stdxxxxx::ostreamxxxxxx::traits_typexxxxx::eqxxxxxxx} lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum  lorem ipsum 
\end{sloppypar}

enter image description here

  • This doesn't quite work, it will break lines before the :: but it adds line breaks too late to prevent the box from overflowing. imgur.com/a/UKlcs – spraff Mar 17 '17 at 18:05
  • @spraff It's not magic: that paragraph simply cannot be split reasonably. Splitting before ::ostreamxxxxxx would stretch too much the spaces in the line. Unless you allow hyphenation or reformulate your text, you're doomed. It's a completely different problem. – egreg Mar 17 '17 at 18:08
  • @spraff If you enclose the offending paragraph in the sloppypar environment, you get awful word spacing, but the break is taken at the first ::. Leave these adjustments for the final revision stage. – egreg Mar 17 '17 at 18:12
0

Starting with the accepted answer at the cited question, I here, in addition, make : active and test to see if the next character is a :. If so, I \allowbreak.

\documentclass[a4paper]{article}
\let\svcolon:
\catcode`:=\active %
\makeatletter
\def:{\@ifnextchar:{\allowbreak\svcolon}{\svcolon}}
\makeatother
\catcode`:=12 %
\renewcommand\texttt{\catcode`:=\active \texttthelp}
\newcommand{\texttthelp}[1]{%
  \begingroup
  \ttfamily
  \begingroup\lccode`~=`/\lowercase{\endgroup\def~}{/\discretionary{}{}{}}%
  \begingroup\lccode`~=`[\lowercase{\endgroup\def~}{[\discretionary{}{}{}}%
  \begingroup\lccode`~=`.\lowercase{\endgroup\def~}{.\discretionary{}{}{}}%
  \catcode`/=\active\catcode`[=\active\catcode`.=\active
  \scantokens{#1\noexpand}%
  \endgroup
}
\usepackage{lipsum}
\begin{document}
\lipsum[4]

unrecoverable error occurs during the transformation, then a
\texttt{std::ostream::traits\_type::eq}

coverable error occurs during the transformation, then a
\texttt{std::ostream::traits\_type::eq}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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