# How can I hyphenate before capital letters in \ttfamily?

A while ago I asked How can I allow line-breaks before a double-colon (::) in \texttt? This question is about extending the line-breaking behaviour to include hypenation.

The given solution solves the problem as it was originally asked:

\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
{\normalfont\ttfamily \tl_use:N \l_spraff_cppstring_tl }
}
\tl_new:N \l_spraff_cppstring_tl
\ExplSyntaxOff


(I have tweaked this slightly from the given solution, I use \normalfont\ttfamily instead of \texttt because of this question.)

This solution doesn't always work for my document:

I think it would be an improvement to allow hyphenation in some cases. Specifically, before a capital letter in CamelCase names. I would like to allow hyphenation such as this:

lorem ipsum lorem ipsum lorem ipsum MyNamespaceName::SomeType::Nested-
Type::member_function


I want to retain the line-break-before-double-colon behaviour that I already have. How can I extend this \cppstring command to hyphenate before capital letters?

I don't know what the hyphenation rules are in detail, but this will ideally happen as little as possible -- i.e. only when an overfull hbox would otherwise be drawn. Minimising the hyphenation is desirable, preventing the overfull hboxes is critical.

Add to the replacement that a capital letter <capital letter> which is not preceded by a word boundary is changed into \-<capital letter>.

\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
% change capital letter X to \-X
\regex_replace_all:nnN { (\B[A-Z]) } { \c{-}\1 } \l_spraff_cppstring_tl
% print the result
{\normalfont\ttfamily \tl_use:N \l_spraff_cppstring_tl }
}
\tl_new:N \l_spraff_cppstring_tl
\ExplSyntaxOff

\begin{document}

lorem ipsum lorem ipsum lorem ipsum
\cppstring{MyNamespaceName::SomeType::NestedType::member_function}

\bigskip

\parbox{0pt}{
lorem ipsum lorem ipsum lorem ipsum
\cppstring{MyNamespaceName::SomeType::NestedType::member_function}
}

\end{document}


The second example shows all added hyphenation points, in order to see you don't get them between :: and a capital letter.