我用来\csdef{}
定义给定开/闭括号的含义:
\csdef{Bracket Meaning \CsToStr{\lvert}}{Left |}
\csdef{Bracket Meaning \CsToStr{\rvert}}{Right |}
\csdef{Bracket Meaning \CsToStr{(}}{open (}
\csdef{Bracket Meaning \CsToStr{)}}{close )}
前两个和最后一个似乎可以正常工作,但第三个有问题。当我尝试通过#1~\csuse{Bracket Meaning \CsToStr{#1}}
(其中#1
是四个给定括号之一\lvert
,\rvert
和)访问它们时(
,)
输出为:
我原本期望用红色突出显示的是( open (
。
那么,这里发生了什么,我应该如何重组它以获得所需的括号结果(
?
代码:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{xcolor}
%% Following package not needed with newer binaries
\usepackage{expl3}% \cs_to_str:N
\ExplSyntaxOn
%% https://tex.stackexchange.com/a/100543/4301
\newcommand{\CsToStr}[1]{\cs_to_str:N #1}%
\ExplSyntaxOff
\csdef{Bracket Meaning \CsToStr{\lvert}}{Left |}
\csdef{Bracket Meaning \CsToStr{\rvert}}{Right |}
\csdef{Bracket Meaning \CsToStr{(}}{open (}% FAILS !!
\csdef{Bracket Meaning \CsToStr{)}}{close )}
\newcommand{\ShowBracketMeaning}[1]{%
#1~
\ifcsdef{Bracket Meaning \CsToStr{#1}}{%
\csuse{Bracket Meaning \CsToStr{#1}}%
}{\text{No Meaning Defined}}%
}%
\begin{document}
$\ShowBracketMeaning{\lvert}$
$\ShowBracketMeaning{\rvert}$
{\color{red}%
$\ShowBracketMeaning{(}$% <---- ????? This should show "open ("
}
$\ShowBracketMeaning{)}$
\end{document}
答案1
如果你试试
\edef\test{\CsToStr{(}}
\show\test
你会发现答案是
> \test=macro:
->.
该\cs_to_str:N
功能应该仅有的应用于控制序列;否则其结果是不可预测的(好吧,它是可预测的,但无论如何似乎不是你想要得到的)。
由于和都\CsToStr{(}
返回\CsToStr{)}
空,因此涉及它们的第二个定义将覆盖第一个。
解决方案:如果你真的想要那个,不要使用\CsToStr
:
\csdef{Bracket Meaning \CsToStr{\lvert}}{Left |}
\csdef{Bracket Meaning \CsToStr{\rvert}}{Right |}
\csdef{Bracket Meaning (}{open (}
\csdef{Bracket Meaning )}{close )}
另一方面,当您形成控制序列时,不需要删除反斜杠,只要反斜杠是“其他”即可。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\TokenToStr}{m}{\token_to_str:N #1}%
\NewExpandableDocumentCommand{\csdefinedTF}{mmm}
{
\cs_if_exist:cTF { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\ExpandArgs{c}\newcommand{Bracket Meaning \TokenToStr{\lvert}}{Left |}
\ExpandArgs{c}\newcommand{Bracket Meaning \TokenToStr{\rvert}}{Right |}
\ExpandArgs{c}\newcommand{Bracket Meaning \TokenToStr{(}}{open (}
\ExpandArgs{c}\newcommand{Bracket Meaning \TokenToStr{)}}{close )}
\newcommand{\ShowBracketMeaning}[1]{%
#1~
\csdefinedTF{Bracket Meaning \TokenToStr{#1}}{%
\UseName{Bracket Meaning \TokenToStr{#1}}%
}{\text{No Meaning Defined}}%
}
\begin{document}
$\ShowBracketMeaning{\lvert}$
$\ShowBracketMeaning{\rvert}$
$\ShowBracketMeaning{(}$
$\ShowBracketMeaning{)}$
\end{document}
答案2
在 egreg 发布详细的解决方案之前,我发现使用\detokenize{}
而不是依赖\CsToStr{}
可以产生预期的结果。
我发布此信息是为了查看这种方法是否存在我不知道的问题。
代码:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{xcolor}
\csdef{Bracket Meaning \detokenize{\lvert}}{Left |}
\csdef{Bracket Meaning \detokenize{\rvert}}{Right |}
\csdef{Bracket Meaning \detokenize{(}}{open (}
\csdef{Bracket Meaning \detokenize{)}}{close )}
\newcommand{\ShowBracketMeaning}[1]{%
#1~
\ifcsdef{Bracket Meaning \detokenize{#1}}{%
\csuse{Bracket Meaning \detokenize{#1}}%
}{\text{No Meaning Defined}}%
}%
\begin{document}
$\ShowBracketMeaning{\lvert}$
$\ShowBracketMeaning{\rvert}$
$\ShowBracketMeaning{(}$
$\ShowBracketMeaning{)}$
\end{document}