Another way to do this kind of thing is to use a \lccode
trick:
\begingroup\lccode`!=`\\\lowercase{\endgroup\def\@backslashchar{!}}
This avoids any need to change catcodes thanks to the special properties of \lowercase
. Compared to the \expandafter\@gobble\string
method, it's a bit more flexible as you can choose the catcode of the resulting character inside your macro. Compared to a change of catcodes, you don't have to use \global
because of how \lowercase
interacts with \endgroup
.
Here's the detail of the code. The \begingroup
is here to keep the lccode changes local. The
\lccode`!=`\\
means that when lowercasing !
you will get the backslash \
(the choice of !
is arbitrary, you just need a normal
character which will not appear elsewhere inside the \lowercase
). The important thing is that the lowercase version of !
wille be a normal character since \lowercase
doesn't change catcodes.
The code \lowercase{\endgroup\def\@backslashchar{!}}
is thus equivalent to \endgroup\def\@backslashchar{\}
but with \
not being special (so \
followed by }
won't be interpreted as \}
but as two separate entities).
At the end, the result is that you have defined \@backslashchar
to be a \
with normal catcode. It can thus be used inside a \write
command without causing the same problems as \
does.
This lccode trick works with all other special characters. For example if you want a space character (of course, for spaces, the macro \space
works fine):
\begingroup\lccode`!=`\ \lowercase{\endgroup\def\@spacechar{!}}
If ever you break the code on two lines, just be careful with the end of lines and put a %
after the \
:
\begingroup\lccode`!=`\ %
\lowercase{\endgroup\def\@spacechar{!}}
You can do with the help of the verbatim
command and some low level hackery:
\documentclass{article}
\usepackage{verbatim}
\newenvironment{spverbatim}
{\verbatim\splitchars}
{\endverbatim}
\newcommand{\splitchars}{%
\definesplitchar{\!}%
\definesplitchar{\.}%
\definesplitchar{\+}%
\definesplitchar{\-}%
\definesplitchar{\^}%
\definesplitchar{\;}%
}
\newcommand{\definesplitchar}[1]{%
\begingroup\lccode`~=`#1\relax
\lowercase{\endgroup\def~}{\char`#1\hspace{0pt plus 0.1pt minus 0.1pt}}%
\catcode`#1=\active
}
\begin{document}
\begin{spverbatim}
$ mylinuxcommand
!+.++++.....+++-+++-!^!^+............................................;+++-^^!--.........+++--!^!^+.++++.....+++-+++-^!^+............................................;+++-^^!--.........+++--!^!^+.++++.....+++-+++-!^!^+............................................;+++-^^!--.........+++--!^!^
$ myotherlinuxcommand
true
$ mylastcommand
"Thank you for your help"
\end{spverbatim}
\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:
Normally you should keep the scope of a catcode change to a minimum. Here you might keep the group open as well.