2

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

  • Welcome to TeX.SX! You're probably looking for \verb|F#| – egreg Jan 24 '16 at 8:47
  • @egreg thanks. I read about \verb what I also read it has some disadvantages. tex.stackexchange.com/a/2791/91093 – LEDfan Jan 24 '16 at 8:50
2

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.

  • Your second code snippet does everything I want. (Even in descriptions) Why does everybody use % at the end of their line? – LEDfan Jan 24 '16 at 8:58
  • @LEDfan That's for avoiding spurious spaces. I added a final comment: \mon{F#} will produce the wrong result with \detokenize. – egreg Jan 24 '16 at 9:01
  • Oh, I just saw the ##, I got that problem too. – LEDfan Jan 24 '16 at 9:02
0

Thanks to all information in the answers and other questions on tex, I finally found a 100% working solution for my situation. I was probably not clear enough in my question.

What I want is:

  • use \mon everywhere I want, inside tables and items, but also in other commands. (Which doesn't work for verbatim)
  • use monospace
  • maybe use a gray background

Some users reported it here that I should use lstinline which turned out to be the solution. I'm using this code in my class:

\newenvironment{stable}{
    \begin{longtable}{ p{6cm}  p{10cm} }
}{
    \\
\end{longtable}
}
\lstset{%
    basicstyle=\tt
}

\newcommand{\mon}[1]{%
    \colorbox{lightgray!30}{\lstinline{#1}}
}

\newcommand{\sitem}[1]{%
    \\ { \bfseries #1} &    
}

And know I can create a "two column page" like this in my document:

\begin{stable}      
    \sitem{Use \mon{const string*}} lorem ipsum \mon{string}
\end{stable}

With this as result:

result

  • I am not sure if a 100% working solution can contain \\ \\ \bf{#1} &, which is asking for trouble. – Johannes_B Jan 24 '16 at 10:03
  • I understand that it isn't beautiful latex and it's an hack. It's just to easily type \sitem instead of copy pasting the same commands over and over again. – LEDfan Jan 24 '16 at 10:11
  • The code will fail in normal text. You cannot have a double line break, \bf is deprecated for 20 years and you cannot have an ampersand in normal text. It seems you are using this within a table, but this might be a clue that something else isn't designed right. – Johannes_B Jan 24 '16 at 10:20
  • Thanks for the information. The double line break was a typo. I replaced the \bf by \bfseries. My intention of these macro's is to easily use the same layout in all my documents. So when I want may first column to be bigger, I only have to change it in the global class. The left column is basically a description for the right column. – LEDfan Jan 24 '16 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.