[Tex/LaTex] How to typeset the percent symbol inside \detokenize

detokenizemacros

I am writing some personal notes about R programming.
I defined a macro to typeset R functions and operators
using a different font style and color:

\newcommand{\rtext}[1]{%
  {\texttt{\detokenize{#1}}}%
}

The macro is able to detokenize underscore characters _
so that I can easily type R functions such as \rtext{seq_along}.

Today I found that the macro fails at detokenizing the percent character %,
for example when I try to typeset the %>% operator
which is from the R package magrittr.
I understand that this is because the percent character
is used to mark the start of a comment.
Unfortunately, trying to use \rtext{\%>\%} gives \%>\% as output,
which is not what is desired.

What is the right way to define the \rtext macro?

\documentclass{article}
\newcommand{\rtext}[1]{%
  {\texttt{\detokenize{#1}}}%
}
\begin{document}
You can write commands in a natural order
by using the \rtext{%>%} infix operator.
\end{document}

Gives the error:

Runaway argument?
{\end {document} 
! File ended while scanning use of \rtext.
<inserted text> 
                \par 

Edit in response to answers:
I added the use of \rtext in a sentence.
Unfortunately the answers provided seem to swallow the space after the command.
Is there any way to fix this?

Best Answer

You can do some catcode magic. The general idea is as follows

\documentclass{article}

\makeatletter
\newcommand\detokenizeWithComments{%%
  \bgroup
    \catcode`\%=12
    \ae@detokenize@with@comments
  }


\def\ae@detokenize@with@comments#1{%%
    \detokenize{#1}%%
  \egroup}

\makeatother

\begin{document}

  Hello world
  \detokenizeWithComments{This has % in it}

  %% back to normal

  back to normal (shouldn't be repeated)

  %% but this next line will fail if uncommented!!!
  %%\texttt{\detokenizeWithComments{This has % in it}}

\end{document}

enter image description here

To get your \rtext to work, you can approach it in this manner:

\documentclass{article}

\makeatletter

\newcommand\rtext{%%
  \bgroup
    \catcode`\%=12
    \ae@r@text
}

\def\ae@r@text#1{%%
  \texttt{\detokenize{#1}}%%
\egroup}

\makeatother

\begin{document}

  Detokenized: \rtext{{This has % in it}}

  Back to normal

\end{document}

As noted by @egreg This macro will not play nicely within another macro or environment that has already read in the arguments. This is similar to the issue with \verb not working nested within other macros. The catcodes are alrady set and the % is already seen as a comment character before the catcode magic ever has a chance to take effect: not even \scantokens can come to the rescue here. And hence the fact that I couldn't just define:

\newcommand\rtext[1]{\texttt{\detokenizeWithComments{#1}}

If you try that, you'll just get the same error you originally had.

Regarding category codes, you could set the category code to 11 for letters as I originally did in this answer. But since \detokenize sets the category codes to 12, setting

\catcode`\%=12 

makes an aesthetically cleaner choice.

Related Question