[Tex/LaTex] Force latex to parse command as raw text

codetypewriter

I'm writing a text about programming and want to include some inline small code snippets. In markdown one would simply use backticks for this test. This automatically becomes monospace font. I want a simple command for this. (Backticks would even be better)

I tried using:

\newcommand{\mon}[1]{
    \mbox{\texttt{\detokenize{#1}}}
}

My command is \mon with one parameter, the \texttt is for the monospace and detokenize is for characters which would otherwise be parsed by Latex.(Like $, & etc) However this doesn't work for #. If I want to use \mon{F#} I get this error:

Illegal parameter number in definition of \reserved@a. \mon{F#}

Here is a test document:

\documentclass{article}

\newcommand{\mon}[1]{
    \mbox{\texttt{\protect\detokenize{#1}}}
}

\begin{document}
    \mon{F#}
\end{document}

I also tried with using a custom environment. I guess it must be possible since lstlistings is doing it.

Thanks

Best Answer

You can possibly do it with \verb. But let's look what happens with your attempt. In

\newcommand{\mon}[1]{%
  \mbox{%
    \texttt{%
      \protect\detokenize{#1}%
    }%
  }%
}

there is a misplaced \protect that however does nothing bad. The problem is that TeX sees #6 before the “detokenization” actually takes place and this results in a bad token list to be passed as argument to \texttt. Indeed, if you use \ttfamily the problem is solved:

\newcommand{\mon}[1]{%
  \mbox{%
    \ttfamily
    \detokenize{#1}%
  }%
}

A different strategy could be performing \detokenize before doing anything else:

\newcommand{\mon}[1]{%
   \expandafter\monAUX\expandafter{\detokenize{#1}}%
}
\newcommand{\monAUX}[1]{%
  \mbox{\texttt{#1}}%
}

This however doesn't solve the problem with F#, because you'll clearly see the # is doubled. That's part of how \detokenize works (and TeX is designed), so for this particular application I'm afraid \verb is the solution. Or some less heavy trick that changes the category code of # (so it can't be used in the argument to another command).


A different approach might be with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\tl_const:Nx \c_ledfan_doublehash_tl { \tl_to_str:n { # } }
\tl_new:N \l_ledfan_mon_tl

\NewDocumentCommand{\mon}{m}
 {
  \tl_set:Nf \l_ledfan_mon_tl { \tl_to_str:n { #1 } }
  \tl_replace_all:NVV \l_ledfan_mon_tl \c_ledfan_doublehash_tl \c_hash_str
  \texttt{ \tl_use:N \l_ledfan_mon_tl }
 }
\cs_generate_variant:Nn \tl_replace_all:Nnn { NVV }
\ExplSyntaxOff

\begin{document}

\mon{F#}

\mon{C##}

\end{document}

The assumption is that any ## in the token list we build comes from \tl_to_str:n (which is \detokenize in disguise) applied to a #6 token, so it's replaced by a single one.

enter image description here

This has still some limitations, because it can't go in the argument of any argument that performs some \protected@edef or \protected@write; for instance \textbf and similar commands or \section, \caption and friends.

Related Question