[Tex/LaTex] How listing and verbatim do to escape special character

catcodesdetokenizelistingsverbatim

I use one macro to display text using texttt style. For the moment this macro is very basic. For example, if I want to use the character _, its catcode must be changed.

Is there a clever way to escape all the special characters like listing and verbatim do ? Can detokenize be helpfull ?

% Sources : 
%   * http://forum.mathematex.net/latex-f6/forcer-le-retour-a-la-ligne-dans-texttt-t13246.html#p127511
%   * http://tex.stackexchange.com/questions/33465/changing-the-catcode-of-in-one-command

\documentclass{article}
    \makeatletter
    \newcommand\breakabletexttt[1]{%
        \begingroup\ttfamily
        \scantokens{\catcode`\_12\makeatletter\breakable@texttt#1\@nil}%
        \endgroup%
    }
    \def\@gobble@fi#1\fi{\fi#1}
    \def\breakable@texttt#1#2\@nil{%
        #1\hspace{0pt plus 0.1pt minus 0.1pt}%
        \ifx\relax#2\relax
        \else
            \@gobble@fi\breakable@texttt#2\@nil
        \fi
    }
    \makeatother


\begin{document}

\breakabletexttt{rangerangerangerange_rangerangerange_rangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerange}

\end{document}

Best Answer

Usually you change the catcode first and then read the argument. Direct after reading the argument you can close the group and end the temporary catcode change:

\newcommand\breakabletexttt{%
    \begingroup
    \catcode`\_=12
    \@breabletexttt
}
\newcommand\@breabletexttt#1{%
    \endgroup
    % do something with #1 which now contains `_' with catcode 12
    % even if that catcode is now different again
}

Normally you should keep the scope of a catcode change to a minimum. Here you might keep the group open as well.

\documentclass{article}

\makeatletter
\newcommand\breakabletexttt{%
    \begingroup
    \catcode`\_=12
    \@breakabletexttt
}
\newcommand\@breakabletexttt[1]{%
    \ttfamily
    \breakable@texttt#1\@nil%
    \endgroup%
}
\def\@gobble@fi#1\fi{\fi#1}
\def\breakable@texttt#1#2\@nil{%
    #1\hspace{0pt plus 0.1pt minus 0.1pt}%
    \ifx\relax#2\relax
    \else
        \@gobble@fi\breakable@texttt#2\@nil
    \fi
}
\makeatother


\begin{document}

\breakabletexttt{rangerangerangerange_rangerangerange_rangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerangerange}

\end{document}
Related Question