我一直在尝试创建一个小型的乳胶数学符号引用。我的列表将需要重复这样的行\textbackslash lfloor - $\lfloor$
。我想创建一个命令,该命令接受一个参数,该参数可以是符号名称lfloor
或命令本身\lfloor
。但在任何一种情况下,我都无法显示另一种情况。我该如何定义这样的命令?
答案1
如果它仅涉及单个控制序列标记并且如果 eTeX 扩展可用,则您可能可以使用\string
和\scantokens
-command的组合\verb
:
\documentclass{article}
\newcommand\myCsPrintCommand[1]{%
\expandafter\InnermyCsPrintCommand\expandafter{\string#1}%
}%
\begingroup
\makeatletter
\catcode`\?=14\relax
\catcode`\%=12\relax
\@firstofone{?
\endgroup
\newcommand\InnermyCsPrintCommand[1]{?
\scantokens\expandafter{\string\verb|#1| -- $#1$%}?
}?
}%
% The trickery above is needed for bringing a %-char/comment-char
% into \scantokens' argument. That in turn is needed for neutralizing
% the endline-character inserted at the end of \scantokens' argument.
\begin{document}
\myCsPrintCommand{\lfloor}
\myCsPrintCommand{\rfloor}
\end{document}
在我看来,这有点小题大做,但我还是决定展示底层的\scantokens
-trickery,因为它不仅可以与\verb
其他命令一起使用,还可以与其他命令一起使用,这些命令的参数通常不应该通过宏传递,而应该通过读取和标记输入来传递,因为这些参数应该在不同的 catcode-régime 下读取/标记,例如 \lstinline
从 listings-package 中,或者其他用于漂亮打印控制字的参数。
尽管如此,下面的例子是我尝试提供一个通用的宏,它允许你使用类似或的\myCsPrintCommand
命令来格式化控制序列的漂亮打印:\verb
\lstinline
\documentclass{article}
\usepackage{color, listings}
%%----------------------------------------------------------------------
%% Both pretty-print a control sequence and typeset the result
%% from carrying out the control sequence:
%%----------------------------------------------------------------------
%% \myCsPrintCommand{<stringified-printing-command>}%
%% {<verb-delimiter>}%
%% {<separator>}%
%% {<formatting-when-carrying-out-command>}%
%% {<control sequence to typeset>}%
%%
%% ->
%% either
%% <stringified-printing-command><verb-delimiter><control sequence to typeset><verb-delimiter>%
%% <separator><formatting-when-carrying-out-command>{<control sequence to typeset>}
%% or
%% <stringified-printing-command>{<control sequence to typeset>}%
%% <separator><formatting-when-carrying-out-command>{<control sequence to typeset>}
%%
%% <stringified-printing-command> prints the character-sequence that
%% forms the control sequence.
%% <stringified-printing-command> either can be something with \verb-syntax -
%% in this case you need to specify a <verb-delimiter>, e.g., |, or
%% can be something that does process one undelimited argument -
%% in this case you need to leave the <verb-delimiter>-argument empty.
%%
%% <formatting-when-carrying-out-command> influences how the result from
%% carrying out <control sequence to typeset> gets typeset.
%% <formatting-when-carrying-out-command> can be a control sequence that
%% processes one undelimited argument.
%%
%% e.g., \myCsPrintCommand{\verb}{|}{--}{\textbf}{\LaTeX}
%% -> \verb|\LaTeX|--\textbf{\LaTeX}
%% e.g., \myCsPrintCommand{\verb}{|}{ -- }{\ensuremath}{\lfloor}
%% -> \verb|\lfloor| -- \ensuremath{\lfloor}
%% e.g., \myCsPrintCommand{\myownstringifier}{}{--}{\ensuremath}{\lfloor}
%% -> \myownstringifier{\lfloor}--\ensuremath{\lfloor}
%%
\newcommand\myCsPrintCommand[5]{%
\expandafter\InnermyCsPrintCommand\expandafter{\string#5}{#1}{#2}{#3}{#4}%
}%
\begingroup
\makeatletter
\catcode`\?=14\relax
\catcode`\%=12\relax
\@firstofone{?
\endgroup
??----------------------------------------------------------------------
?? Expandably within two expansion steps check whether argument is empty:
??----------------------------------------------------------------------
?? \UDCheckWhetherNull{<Argument which is to be checked>}%
?? {<Tokens to be delivered in case that argument
?? which is to be checked is empty>}%
?? {<Tokens to be delivered in case that argument
?? which is to be checked is not empty>}%
??
?? The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
?? <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
??......................................................................
\newcommand\UDCheckWhetherNull[1]{?
\romannumeral0\expandafter\@secondoftwo\string{\expandafter
\@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
\@secondoftwo\string}\expandafter\expandafter\@firstoftwo{ }{}?
\@secondoftwo}{\expandafter\expandafter\@firstoftwo{ }{}\@firstoftwo}?
}?
\newcommand\InnermyCsPrintCommand[5]{?
\UDCheckWhetherNull{#3}{?
\scantokens\expandafter{\string#2{#1}#4#5{#1}%}?
}{?
\scantokens\expandafter{\string#2#3#1#3#4#5{#1}%}?
}?
}?
}%
% The trickery above is needed for bringing a %-char/comment-char
% into \scantokens' argument. That in turn is needed for neutralizing
% the endline-character inserted at the end of \scantokens' argument.
\begin{document}
%% \myCsPrintCommand{<stringified-printing-command>}%
%% {<verb-delimiter>}%
%% {<separator>}%
%% {<formatting-when-carrying-out-command>}%
%% {<control sequence to typeset>}%
Example with \verb|\verb|:
\myCsPrintCommand{\verb}{|}{ -- }{\ensuremath}{\lfloor}
\myCsPrintCommand{\verb}{|}{ -- }{\ensuremath}{\rfloor}
Example with \verb|\lstinline|:
\myCsPrintCommand{\lstinline[language={[LaTeX]TeX}]}{|}{ -- }{\ensuremath}{\lfloor}
\myCsPrintCommand{\lstinline[language={[LaTeX]TeX}]}{|}{ -- }{\ensuremath}{\rfloor}
Example with \verb|\mybluestringified|:
\newcommand\mybluestringified[1]{%
\textcolor{blue}{\texttt{\string#1}}%
}%
\myCsPrintCommand{\mybluestringified}{}{ -- }{\ensuremath}{\lfloor}
\myCsPrintCommand{\mybluestringified}{}{ -- }{\ensuremath}{\rfloor}
% You can put the call to \myCsPrintCommand into a macro:
\newcommand\printitwithverb{%
\myCsPrintCommand{\verb}{|}{ -- }{\ensuremath}%
}%
\newcommand\printitwithlstinline{%
\myCsPrintCommand{\lstinline[language={[LaTeX]TeX}]}{|}{ -- }{\ensuremath}%
}%
\newcommand\printitwithmybluestringified{%
\myCsPrintCommand{\mybluestringified}{}{ -- }{\ensuremath}%
}%
Example with \verb|\printitwithverb|:
\printitwithverb{\lfloor}
\printitwithverb{\rfloor}
Example with \verb|\printitwithlstinline|:
\printitwithlstinline{\lfloor}
\printitwithlstinline{\rfloor}
Example with \verb|\printitwithmybluestringified|:
\printitwithmybluestringified{\lfloor}
\printitwithmybluestringified{\rfloor}
\end{document}