Macro that takes any latex code as an argument
The near universal rule is that verbatim
material cannot be an argument to a command. With the cprotect
package, there is sometimes a workaround as shown in the MWE, but even that is not a universal fix.
EDIT: group added to prevent spillage of purple into subsequent material (thanks Ulrike).
\documentclass{article}
\usepackage{cprotect,xcolor}
\newcommand\purp[1]{{\color{purple} #1}}
\begin{document}
\cprotect\purp{
\begin{verbatim}
asdfadf
asdf
asdf
\end{verbatim}
}
\end{document}
If it's just about colours, you could fake a \textcolor
command, which seems to take an argument, but does support verbatim material. Note that this is no general solution, but just provides an argument taking syntax to \color
which is not really an argument.
(This way one could use any formatting switches not only colours, e.g. \bfseries
could be used this way, too)
EDIT: created a \switchhack
that allows arbitrary formatting switches not only colours, and \colorhack
calls \switchhack
now.
\documentclass[]{article}
\usepackage{xcolor}
\makeatletter
\begingroup\def\:#1{\endgroup\let\switchhack@sptoken= #1}\:{ }
\newcommand\switchhack[1]
{%
\def\switchhack@switch{#1}%
\switchhack@a
}
\newcommand\switchhack@a
{%
\futurelet\switchhack@gobbled\switchhack@b
}
\newcommand\switchhack@b
{%
\ifx\switchhack@gobbled\switchhack@sptoken
\switchhack@eatspace
\fi
\@firstofone
{%
\ifx\bgroup\switchhack@gobbled
\else
\GenericWarning
{}{Warning: Argument of \string\switchhack\space not delimited}%
\switchhack@undelimeted
\fi
\switchhack@delimited
}%
}
\long\def\switchhack@eatspace\fi#1#2%
{%
\fi
\afterassignment\switchhack@a
\let\switchhack@gobbled=
}
\long\def\switchhack@undelimeted\fi#1#2%
{%
\fi
{\switchhack@switch#2}%
}
\newcommand\switchhack@delimited
{%
\afterassignment\switchhack@do
\let\switchhack@gobbled
}
\newcommand\switchhack@do
{%
\bgroup\switchhack@switch
}
\long\def\colorhack#1#{\colorhack@{#1}}
\newcommand\colorhack@[2]
{%
\switchhack{\color#1{#2}}%
}
\makeatother
\newcommand\purp{\colorhack{purple}}
\newcommand\bfhack{\switchhack{\bfseries}}
\begin{document}
\colorhack[rgb]{.5 .4 .8}{foo}
\purp{\verb|this is blue|}
following text
\bfhack{this is bold}
\colorhack{red} Undelimeted
\purp{
\begin{verbatim}
This is
verbatim
purple (I lied up there, it never was blue)
\end{verbatim}
}
\end{document}
Another possibility to get macros which take verbatim material as arguments is to grab the arguments as boxes instead. Again this is no universal solution and you can't do arbitrary stuff with it (most importantly you can't change the appearance of the boxed material after it is boxed, that's what the optional arguments of grabbox
are for, to make some formatting possible).
The following defines \purp
to take its argument inside of a \hbox
and \purp*
to take it inside of a \vbox
(of course the macro name in both cases is \purp
, the second one is just followed by a star).
\documentclass[]{article}
\usepackage{grabbox}
\usepackage{xcolor}
\makeatletter
\newsavebox\purp@box
\newcommand\purp
{%
\begingroup
\@ifstar
{%
\grabbox\purp@box[\color{purple}]\vbox{\unvbox\purp@box\endgroup}%
}
{%
\grabbox\purp@box[\color{purple}]\hbox{\unhbox\purp@box\endgroup}%
}%
}
\makeatother
\begin{document}
\purp{\verb|this is blue|}
other text
\purp*{
\begin{verbatim}
This is
verbatim
purple (I lied up there, it never was blue)
\end{verbatim}
}
\end{document}