15

Apologized for my unclear description. I wish I could explain my problem more clearly.

In document, I wish I can just write something as

"how to use \cmd \mbox in xxx" or "what is \cmd minipage xxx". 
The string with/without \ is the argument of \cmd. \cmd reads 
token until meeting space or .,; (any char except a-zA-Z)

Following \def taking next word as argument? I can try to do this.

Next, in the definition of \cmd, I wish there's a variable to store the string (without \), that is, \def\cmd#1{\def\A{} xxx}, then \A would store {mbox} (without \) or {minipage}. So I can use \A in index/toc/ etc.

I'm trying to write a manual of some commands of LaTeX (in Chinese). So, it's more easily to maintain the code by this way. (I use \verb and others to do this. But it becomes more and more difficult to maintain the code now).

So, I hope I can just type

"even though you specify \cmd \pagestyle to force an empty xxx" 
rather than "even though you specify \bscmd{mbox} to force xxx" 
(\bs for backslash) and "even though you specify \cmd{minipage} to 
force xxx" (\cmd for normal none-backslash)

Then, because of index/hyperref/footnote/etc, so I need something stores \mbox or minipage.

7 Answers 7

14

To convert \command into command, you can use an \expandafter\@gobble\string trick as mentioned in Zack's answer to How to make a real backslash (escape) character?. The code would thus be:

\makeatletter
\newcommand{\cmd}[1]{%
  \edef\cmdname{\expandafter\@gobble\string#1}%
  \index{\cmdname}%
  \texttt{\textbackslash\cmdname}%
}
\makeatother

Since from your comments you seem to want to be able to use both \cmd{\raisebox} and \cmd{minipage}, you have to check first if the argument begins by a backslash (more precisely, once \string has been applied, a catcode 12 backslash). To do this, you can use an uppercase trick. With the code given below, the result of

how to use \cmd{\raisebox}

what is \cmd{minipage}

\cmd{\par} also works \index{paragraph}

and \cmd{\@tfor} too

will be

result of the code

Here's the complete code. The xstring package is used to make the command names safe for the index (replacing @ by "@):

\documentclass{article}

% to get \, { and } to display right when using \texttt
\usepackage[T1]{fontenc}
\usepackage{lmodern}

\usepackage{xstring}

\usepackage{makeidx}
\makeindex


% This takes \cmdname and defines \escapedcmdname in which
% all the @ have been changed to "@ (which is safe in the index)
% example: if \cmdname is @tfor then \escapedcmdname is "@tfor
\newcommand{\sanitizecmdname}{% must not be inside a \makeatletter
  \StrSubstitute{\cmdname}{@}{"@}[\escapedcmdname]%
}

\makeatletter
\begingroup
\uccode`!=`\\ % ! is now a backslash character (catcode 12)
\uppercase{\endgroup
% macros need to be lon to work if #1 is \par
  \long\def\if@begins@by@backslash#1{%
    \expandafter\if@begins@by@backslash@aux\string#1!\@@@@@nil
  }
  \long\def\if@begins@by@backslash@aux#1!#2\@@@@@nil{%
    \ifx\\#1\\% if #1 is empty, the argument begins by a           \expandafter\@firstoftwo  % use the first argument that follows
    \else
      \expandafter\@secondoftwo % use the second argument that follows
    \fi
  }
}
\newcommand{\cmd}[1]{%
  \if@begins@by@backslash{#1}%
%   what to do when #1 begins by a backslash
    {% if #1 is \raisebox, \cmdname is raisebox
     \edef\cmdname{\expandafter\@gobble\string#1}%
     % if #1 is \@tfor, \escapedcmdname is "@tfor
     \sanitizecmdname % defines \escapedcmdname
     \index{\escapedcmdname @\texttt{\textbackslash\escapedcmdname}}%
     \texttt{\textbackslash\cmdname}}%
%   what to do when #1 does not begin by a backslash
    {\index{#1@\texttt{\{#1\}}}%
     \texttt{\{#1\}}}% remove \{ and \} if you don't like them
}
\makeatother

\begin{document}

how to use \cmd{\raisebox}

what is \cmd{minipage}

\cmd{\par} also works \index{paragraph}

and \cmd{\@tfor} too

\printindex

\end{document}

I've commented the code a little, but if you have questions on it, don't hesitate.

6
  • Thanks a lot. It works great! The next question is, how to make the index works correct? I mean \cmd{\raisebox} and \index{raisebox@\textbackslash raisebox} I wish these two can stand for the same index item. But in \cmd{\raisebox}, \cmdnamd is \raisebox, not raisebox, so they can't stand for the same item in index. (I wish to sort the command by the name itself, without '\'. Thanks again! Mar 4, 2011 at 6:30
  • 1
    @Kuang-Li Huang: in \cmd{\raisebox}, \cmdname is raisebox, not \raisebox, so changing \index{\cmdname} into \index{\cmdname @\textbackslash\cmdname} should do what you want (if I understood correctly). Mar 4, 2011 at 12:39
  • Thank you. It works perfect now. I changed some code and post it. The problem is the index for the command containing @. Can you help me to fix the code? Thank you so much! Mar 5, 2011 at 6:10
  • @Kuang-Li Huang: you're trying to do the same thing as the doc package does. Perhaps you could check its code to see how it deals with the problem. Mar 5, 2011 at 8:54
  • @Kuang-Li Huang: I've updated my answer to take this into account. You must change, inside \cmdname, all the @ into "@. The most user-friendly way of doing this is probably using the xstring package. Mar 5, 2011 at 10:08
7
\newcommand*\cmd[1]{\texttt{\string#1}}

And it is better to define

\makeatletter
\newcommand*\cmd[1]{{\verbatim@font\@noligs\string#1}}
\makeatother

like \verb do.

P.S. you may refer cprotect package for verbatim in macro arguments.

In TeX, you can \string followed by a macro to get the macro name with baskslash. But it is not convient for indexing. Yiannis Lazarides' solution is better in practice, which change the requested syntax a little.

1
  • Thanks a lot. I think I describe the question unclearly. I want to write like: "how to use \raisebox" or "what is minipage". In the main document, I just want to use one command, so I can use "how to use \cmd{\raisebox}" and "what is \cmd{minipage}". There are no problem for the later case. The previous case, I wish I can save "raisebox" in a variation, such as \def\name{raisebox}. Then, I can use \name to make index, adding color, and so on. Using two commands are much more easy (it's what I did). But \cmd is used for huge times (>1000), I think maintain them by only one command is more easy. Mar 3, 2011 at 6:23
2

For inline code you can try the shortvrb or the listings packages. These packages allow using a single character to begin and end verbatim text (\MakeShortVerb for shortvrb and \lstMakeShortInline for listings). Thus, you can write:

\documentclass{minimal}

\usepackage{shortvrb}    
\MakeShortVerb{\|}

\begin{document}

The \textsf{shortvrb} package provides a command |\MakeShortVerb|
for typesetting inline code in a convenient manner.

\end{document}
1
  • This is much easier than my current trick of making an emacs keyboard macro to type \lstinline|| and put me in the right place...
    – Seamus
    May 16, 2011 at 11:49
2

The command below shows you what is possible: It can typeset the text in the current paragraph, as well as print it in the margin and add it to the index.

\documentclass{article}
\usepackage{xcolor,palatino}
\newcommand{\pmac}[2]{\index{#1 package!#2}{\protect\color{red}
{\textbackslash #2}}
\protect\marginpar{\protect\color{red}
   {\textbackslash #2}}}
\begin{document}
This is a command \pmac{xcolor}{color}  
\end{document}
2

The ydoc-desc package (from the ydoc bundle; still in its alpha stage) provides the macros \cs{command} to print \command. Alternatively you can use \cmd{\command} or \cmd\command. For environments there is \env{environment name} which uses \envstyle to format the name.

You can also use the advanced \Macro macro to format a macro including its arguments using a very natural syntax \Macro\mymacro[<options>]{<argument>} is printed as \mymacro[〈options〉]{〈argument〉}.

You could also copy the definitions of the first two macros from the standard ltxdoc class. Also the standard doc package provides \cs but not \cmd or \env.


However, if you want to print macro names in messages instead you need something expandable. In this case use either \string\foo or \noexpand\foo to print \foo.

1

I'm not sure how to make a macro that does what you want, but I think that \verb+\commmand1+ does what you're asking.

1
  • Thank you. I know \verb can do the same thing, but it's a little difficult to use (I wrote something before, and used \verb. But, with the file becomes bigger and bigger, and more complex, \verb becomes more and more difficult to maintain the file.) If I can get the string of \command1, then I can do something as wish, such as using color, adding command1 to index (in index, I need to use command1, not \command1, and sort it by command1 only), and maybe I need to underline it. I try to change catcode, but it doesn't work correctly. (I think I use it in wrong way) Thank you for your help! Mar 3, 2011 at 3:24
0

you could use

\begin{verbatim}
type any stringwith\ or any character___
\end{verbatim}

and have it output to the pdf without any problem at all.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .