如何获取带有 \ 的字符串

如何获取带有 \ 的字符串

抱歉我的描述不清楚。我希望可以更清楚地解释我的问题。

在文档中,我希望我可以写一些内容

"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)

接下来\def以下一个单词作为参数?我可以尝试这样做。

接下来,在 的定义中\cmd,我希望有一个变量来存储字符串(不带\),即 ,\def\cmd#1{\def\A{} xxx}然后\A将存储{mbox}(不带\) 或{minipage}。所以我可以\Aindex/ toc/ 等中使用。

我正在尝试写一份 LaTeX 的一些命令手册(中文)。这样,代码维护起来会更容易一些。(我使用\verb和其他人来做这件事。但现在代码维护变得越来越困难了)。

所以我希望我可以打字

"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)

然后,因为index/ hyperref/ footnote/etc,所以我需要一些东西存储\mboxminipage

答案1

要转换\command成命令,你可以使用\expandafter\@gobble\stringZack 的回答中提到的技巧如何制作真正的反斜杠(转义)字符?。因此代码如下:

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

由于从您的评论来看,您似乎希望能够同时使用\cmd{\raisebox}\cmd{minipage},因此您必须首先检查参数是否以反斜杠开头(更准确地说,一旦\string应用,则为 catcode 12 反斜杠)。为此,您可以使用大写字母技巧. 使用下面给出的代码,结果

how to use \cmd{\raisebox}

what is \cmd{minipage}

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

and \cmd{\@tfor} too

代码结果

以下是完整代码。字符串包用于使命令名称对于索引来说是安全的(替换@"@):

\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}

我对代码做了一些评论,但如果您有任何疑问,请不要犹豫。

答案2

\newcommand*\cmd[1]{\texttt{\string#1}}

最好定义

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

喜欢\verb做。

PS 您可以参考cprotect包中有关宏参数的逐字说明。

在 TeX 中,你可以\string在宏后面加上斜杠来获取宏名。但这不方便索引。Yiannis Lazarides 的解决方案在实践中更好,它稍微改变了请求的语法。

答案3

对于内联代码,您可以尝试shortvrb或者listings包。这些包允许使用单个字符来开始和结束逐字文本(\MakeShortVerbforshortvrb\lstMakeShortInlinefor listings)。因此,您可以编写:

\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}

答案4

ydoc-desc包(来自ydoc捆绑包;仍处于 alpha 阶段)提供了\cs{command}要打印的宏\command。或者,您可以使用\cmd{\command}\cmd\command。对于环境,有\env{environment name}用于\envstyle格式化名称的宏。

您还可以使用高级\Macro宏来格式化宏(包括其参数),使用非常自然的语法\Macro\mymacro[<options>]{<argument>}打印为\mymacro[〈options〉]{〈argument〉}

您也可以从标准类中复制前两个宏的定义ltxdoc。此外,标准doc包提供了\cs但没有\cmd\env


但是,如果您想在消息中打印宏名称,则需要一些可扩展的东西。在这种情况下,使用 或\string\foo\noexpand\foo打印\foo

相关内容