我可以定义一个接受参数但不评估参数的命令吗?
答案1
好的,看来你的意思是所谓的逐字模式为“不评估参数”。在 TeX 中,这是通过更改类别代码, 短的猫代码,特殊字符。这是通过使用 来完成的\catcode<ASCII number of character>=<catcode><space or \relax>
。字符的 ASCII 编号可以通过<character>`` or
\`` 接收。请注意,一旦 TeX 读取了字符,其 catcode 就会固定,因此必须事先进行更改,并且只能是本地更改!
正常做法是 (1) 更改组中的 catcode (2) 调用第二个宏,该宏读取参数并关闭组 (3) 处理参数并根据需要读取其他参数。LaTeX 在这方面提供了一点帮助,它提供了\dospecials
包含所有以 开头的特殊字符\do
(例如 )的宏\do\\\do\%\do\& ...
,因此您只需定义\do
一个宏,将这些字符的 catcode 更改为中性字符,即 catcode 12“其他”。宏\@makeother
会为您完成此操作!但是,在这种情况下,必须将{
和}
改回原始 catcode 1 和 2,才能读取参数。
\documentclass{article}
\usepackage{hyperref}
\makeatletter
\def\hreffootnote{%
%\unskip
\begingroup
\let\do\@makeother
\dospecials
\catcode`\{=1\relax
\catcode`\}=2\relax
\href@footnote
}
\def\href@footnote#1{%
\endgroup
\href@@footnote{#1}%
}
\let\realhref\href
\def\href@@footnote#1#2{%
\footnote{\realhref{#1}{#2}}%
}
\begin{document}
Text\hreffootnote{http://foobar.com/~test/%^&*$_##/test}{there} after
Text \href{http://foobar.com/~test/%^&*$_##/test}{there} after
\let\href\hreffootnote
Text \href{http://foobar.com/~test/%^&*$_##/test}{there} after
Hello\href{http://www.google.com/#sclient=psy&hl=en&site=&source=hp&q=numbers&aq=f&aqi=&aql=&oq=&pbx=1&fp=d5033c56880e0199}{b} world.
\end{document}
更新2011-07-27:
我现在发布了新版本newverbs
它提供\collectverb
并\Collectverb
轻松收集逐字论据。请参阅我的回答将 href 更改为脚注作为脚注的示例。
答案2
为了回答评论中问题的澄清,这似乎是有效的(虽然我不是这个hyperref
软件包的专家,所以这可能会破坏其他东西,但如果确实如此,我相信有人会停下来并这么说)。
\documentclass{article}
\usepackage{hyperref}
\let\oldhref=\href
\def\href#1#2{\footnote{\oldhref{#1}{#2}}}
\begin{document}
Hello\href{a}{b} world.
\end{document}
答案3
我已经在 Dick 的博客上发布了此内容。我认为有一种更简单的方法可以完成 Dick 想要做的事情(如果我理解正确的话),即使用包\url
提供的命令hyperref
。在这种情况下,您可以像这样定义宏:
\newcommand\hreffootnote[2]{#2\footnote{\url{#1}}}`
编辑:这无法正确处理 URL 中的特殊字符。但这似乎有效(使用hyperref
):
\makeatletter
\newcommand\myhref@[2]{#2\footnote{\url@{#1}}}
\DeclareRobustCommand{\myhref}{\hyper@normalise\myhref@}
\makeatother
答案4
只是为了澄清马丁的回答,同时试图将这种行为置于更多的编程语言理论背景中,并解决你博客中的一些问题。
这里的问题是 Tex 对其输入采取的高度动态的分阶段方法,Knuth 将其描述为与消化道的类比。Tex 每次输入一个字符,同时用“眼睛”评估和“查看”它们 - 在此阶段发生的事情是字符获得 catcode。当这些标记被“嘴巴”咀嚼时,接下来会发生扩展。当宏“接受”参数时,它会提前分配 catcode,以便它拥有所有参数:您无法避免这种情况,但您可以在发生这种情况之前更改 catcode。Martin 的答案使用他的包将 catcode 更改为所有字母(我认为),以便在读入参数时将 URL 视为普通字符串。
如果有效 Tex 程序集是通过执行\bye
原语后面的命令而终止的程序,而纯 Tex 程序是仅从一个 .tex 文件读取而不写入该文件的程序,那么很明显,纯有效 Tex 程序集不是递归的。要真正证明这一点,我认为需要证明一些有关 Tex 程序的事情,因为它没有正式的规范。再说一遍。Knuth 确实有一个独立于实现的 Tex 正确性概念,因为他已经给漏洞猎人开出了支票。
Knuth 从来不是软件工程师所提倡的那种纪律的人。事实上,他在 Dijkstra 的“Goto 被视为有害”论文之后的讨论中发表了这样的看法:如果你知道自己在做什么,goto 是可以的,甚至是一件好事(Knuth,1974 年,《使用 go to 语句进行结构化编程》,计算调查6:261–301)。我猜这种编程风格的真正问题在于它不具备可扩展性:两个 Knuth 无法很好地合作。
Tex 作为一种编程语言并不完全古怪。它可以被视为 Strachey 的 GPM 的子语言。但我见过的其他 GPM 衍生语言都没有采用如此激进的动态语法方法。