如何将字符串转换为命令?

如何将字符串转换为命令?

如何使用字符串运行命令?

例如,我创建了新命令:

\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

相关内容