如何使用字符串运行命令?
例如,我创建了新命令:
\newcommand\footn{\footnote}
现在,我不想直接使用这个命令,
我想用@footn{*}
这个来代替:\footn{*}
我不想使用\catcode
,因为使用它,我无法@
在文本中正常使用字符。我想将@
字符设置为活动状态,仅当它被footn
命令使用时。我该怎么做?谢谢。
答案1
您可以将其@
激活并定义它以提前查看下一个字符是什么。根据这一点,它可以插入普通的 @ 或扩展宏。请注意,LaTeX 的内部宏\@ifnextchar
会吞噬空格。
\documentclass{article}
\newcommand\footn{\footnote}
\makeatletter
\DeclareRobustCommand{\myAt}{%
\@ifnextchar f
{\expandafter \myAt@f \@gobble}%
{@}%
}
\newcommand{\myAt@f}{%
\@ifnextchar o
{\expandafter \myAt@fo \@gobble}%
{@f}%
}
\newcommand{\myAt@fo}{%
\@ifnextchar o
{\expandafter \myAt@foo \@gobble}%
{@fo}%
}
\newcommand{\myAt@foo}{%
\@ifnextchar t
{\expandafter \myAt@foot \@gobble}%
{@foo}%
}
\newcommand{\myAt@foot}{%
\@ifnextchar n
{\expandafter \footn \@gobble}%
{@foot}%
}
\makeatother
\catcode`@=\active
\let@=\myAt
\begin{document}
\tableofcontents
\section{@@@}
e-mail@footn{[email protected]}
\end{document}
这种代码写起来很烦人,如果你决定重命名命令,那就更烦人了。因此,我编写了一个工厂命令来自动创建这些命令,Manuel 提供了一个实现\ifnextchar
它确实不是吞噬空间:
\documentclass{article}
\newcommand\footn{\footnote}
\makeatletter
\protected\def\ifnextchar#1#2#3{%
\let\@tmpA=#1%
\def\@tmpB{#2}%
\def\@tmpC{#3}%
\futurelet\@nextToken\@doIfNextChar
}
\def\@doIfNextChar{%
\ifx\@nextToken\@tmpA
\let\@doNext\@tmpB
\else
\let\@doNext\@tmpC
\fi
\@doNext
}
\newcommand{\newAlias}[2]{% #1: control sequence to define (@), #2: name
\def\newAlias@gobbledChars{\string#1}%
\expandafter \DeclareRobustCommand \expandafter #1\expandafter {\csname newAlias@\newAlias@gobbledChars\endcsname}%
\newAlias@iter#2\relax
\expandafter \let \csname newAlias@\newAlias@gobbledChars\expandafter\endcsname \csname#2\endcsname
}
\newcommand{\newAlias@iter}[1]{%
\ifx\relax#1
% stop
\else
\expandafter \edef \csname newAlias@\newAlias@gobbledChars\endcsname {%
\unexpanded{\ifnextchar#1}%
{\noexpand\expandafter \expandafter\noexpand\csname newAlias@\newAlias@gobbledChars#1\endcsname \noexpand\@gobble}%
{\unexpanded\expandafter{\newAlias@gobbledChars}}%
}%
\expandafter \def \expandafter \newAlias@gobbledChars \expandafter {\newAlias@gobbledChars #1}%
\expandafter \newAlias@iter
\fi
}
\makeatother
\catcode`@=\active
\newAlias{@}{footn}
\begin{document}
\tableofcontents
\section{@@@}
e-mail@footn{[email protected]}
\end{document}
请注意,如果您使用此类黑客手段,您可能会让未来阅读您代码的其他人感到困惑,甚至可能让您自己感到困惑。
答案2
如果您可以自由使用 LuaLaTeX,以下解决方案可能会让您感兴趣。它设置了一个充当预处理器的 Lua 函数,扫描所有输入行并将所有 实例替换为@footn
。\footnote
通过将 Lua 函数分配给process_input_buffer
回调,工作在 TeX 开始其自己的工作之前完成,即 LuaTeX@footn
在其自己的处理过程中永远不会“看到”。
请注意,无需\footn
单独定义,因为 Lua 函数直接用 替换了 的所有@footn
实例\footnote
。
话虽如此,我不明白为什么写作\footnote
可能会带来麻烦和/或为什么写作@footn
可能会带来实质性的改进\footnote
。
% !TEX TS-program = lualatex
\documentclass{article}
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function change_at ( s )
return string.gsub ( s , "@footn" , "\\footnote" )
end
\end{luacode}
%% TeX-side code
\AtBeginDocument{\directlua{luatexbase.add_to_callback(
"process_input_buffer", change_at, "change_at" )}}
\setlength\textheight{1.5cm} % just for this example
\begin{document}
A thought.@footn{Hello, world.}
A ``@!@?@'' thought.@footn{@Goodbye@, world.}
\end{document}
答案3
如果你使用 csplain,那么 encTeX 和\mubyte
原语将被激活。因此,你可以通过以下方式将字节序列转换为控制序列:
\mubyte\footn @footn\endmubyte
\def\footn{SOMETHING SPECIAL}
Aha @ uff@footo, @footn, etc.
\bye