在包中,我根据传递给函数的选项值构建宏名。现在,这些值也应该允许内部-
,但我构建的命令名\csname
不允许。因此,我需要-
从内部的选项值中删除所有内容\csname...\endcsname
。我该怎么做呢?
简单示例:
\documentclass{report}
\makeatletter
% Create tex name of the form "test@ARGUMENT".
% PROBLEM: Need to remove - from #1...
\newcommand{\process}[1]{\typeout{Process called with `#1'} \csname test@#1\endcsname}
\newcommand{\test@mytag}{\typeout{test@mytag called} It worked}
\makeatother
\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag} % Doesn't work, needed for values like shade-tb-inverse
\process{mytag} % Works, but ugly with values like shadetbinverse
\end{document}
我想要一个带参数的命令(在我的情况下,选项值由 xkeyval 的 choicekey 过滤为某些有效值之一)。现在,我想调用一个命令\test@VALUE
。不幸的是,选项值应该允许破折号,如 my-tag 或 shade-lr。由于 LaTeX 不允许在命令中使用破折号,我需要过滤-
内的所有内容\csname
。我该怎么做?
答案1
\documentclass{report}
\makeatletter
\newcommand\textdash{-}
\begingroup
\catcode`\-=\active
\newcommand\dashtodash{}
\gdef\dashtodash{\def-{\textdash}}
\newcommand\ignoredash{}
\gdef\ignoredash{\def-{}}
\endgroup
\newcommand{\process}{\begingroup\catcode`\-=\active \@process}
\newcommand\@process[1]{\endgroup\dashtodash\typeout{Process called with `#1'}\ignoredash \csname test@#1\endcsname}
\newcommand{\test@mytag}{\typeout{test@mytag called} It worked}
\makeatother
\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag} % Doesn't work, needed for values like shade-tb-inverse
\process{mytag} % Works, but ugly with values like shadetbinverse
\end{document}
答案2
我不明白为什么你需要从字符串中删除破折号才能将其传递给构造\csname
函数,但这是一个无包解决方案。我假设没有空格并且 eTeX 可用,否则,你需要做更多工作。
\newcommand*{\csremovedashes}[1]
{\csname\expandafter\csremovedashes@\detokenize{#1}-\endcsremovedashes-}
\newcommand*{\csremovedashes@}{}
\long\def\csremovedashes@#1-{#1\csremovedashes@}
\newcommand*{\endcsremovedashes}[1]{\endcsname}
分两步\csremovedashes{ab-c}
展开为\abc
。
答案3
\documentclass{report}
\usepackage{xstring}
\makeatletter
\newcommand\process[1]{%
\StrDel{#1}{-}[\myString]%
\typeout{Process called with `\myString'} \csname test@\myString\endcsname}
\newcommand\test@mytag{\typeout{test@mytag called} It worked}
\makeatother
\begin{document}
% The following should actually try to execute \test@mytag (i.e. the - removed)
\process{my-tag}
\process{mytag}
\end{document}