# Hyphenating identifiers printed in typewriter font

I'm typesetting identifier documentation by generating them from a database. These identifiers that are very free-format, i.e. using a mixture of camel-Case and underscores etc. I want to print them in typewriter font, hyphenated.

I have managed the printing of the underscores identifiers with the help of TeX.SX, thanks very much.

However... hyphenation. I want to allow a linebreak between a lowercase character and an uppercase character, and after _ and -, and replace the normal hyphen with another character (\cdot would be nice, but that's not a character in T1) to prevent ambiguity for the latter case.

I think I'd want keep the original hyphenation points (useful for the string "modification" in my example). I guess breaking before or after a number does not need special treatment.

Here is an example of my current \identifier command that does not add extra hyphenation points. I'm not understanding it well enough to mix in the code from e.g. Automatic camel case breaking though - could someone have a go at it for me please?

\documentclass{article}
\usepackage[T1]{fontenc} % better underscore
\usepackage[htt]{hyphenat}
\makeatletter%
\DeclareRobustCommand*{\identifier}[1]{%
\begingroup\@activeus\scantokens{%
\ifmmode%
\expandafter\texttt%
\else%
\expandafter\textnhtt%
\fi{#1}%
\endinput}\endgroup}%
\begingroup\lccode\~=\_\relax
\lowercase{\endgroup\def\@activeus{\catcode\_=\active \let~\_}}
\makeatother

\begin{document}
\parbox{0pt}{\hspace{0pt}%
\identifier{SmartModificationSense}
\identifier{SmartModification_Sense}
\identifier{Smart_Modification_Sense2}
\identifier{smartModification_Sense2}
\identifier{smartModi-fication_Sense2}
\identifier{enable_SPI_1}
}
\end{document}


This adds a centered dot if an identifier is split before an uppercase letter (not preceded by another uppercase letter) or after an underscore and allows normal hyphenation in word fragments.

\documentclass{article}
\usepackage[T1]{fontenc} % better underscore
\usepackage[htt]{hyphenat}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\identifier}{m}
{
\cmarqu_identifier:n { #1 }
}

\tl_new:N \l_cmarqu_identifier_tl

\cs_new:Nn \cmarqu_identifier:n
{
\tl_set:Nn \l_cmarqu_identifier_tl { #1 }
\regex_replace_all:nnN
{ \B([^A-Z])([A-Z]) }
{ \1 \c{cmarqu_period:} \2 }
\l_cmarqu_identifier_tl
\regex_replace_all:nnN
{ \cD.}
{ \cO_\c{cmarqu_period:} }
\l_cmarqu_identifier_tl
\regex_replace_all:nnN
{ \c{cmarqu_period:}\c{cmarqu_period:} }
{ \c{cmarqu_period:} }
\l_cmarqu_identifier_tl
\texttt{\tl_use:N \l_cmarqu_identifier_tl}
}
\cs_new:Nn \cmarqu_period:
{
\nobreak
\discretionary{\textperiodcentered}{}{}
\nobreak\hspace{0pt}
}
\ExplSyntaxOff

\begin{document}
\parbox{0pt}{\hspace{0pt}%
\identifier{SmartModificationSense}
\identifier{SmartModification_Sense}
\identifier{Smart_Modification_Sense2}
\identifier{smartModification_Sense2}
\identifier{smartModification_Sense2}
`