唐纳德·阿瑟瑙的 网址软件包提供了宏\urldef
,当需要在脚注或尾注中排版 URL 字符串时,它非常方便。例如,
\documentclass{article}
\usepackage{url} % for \url and \urldef commands
\usepackage{enotez} % for \endnote and \printendnotes commands
\setenotez{backref = true}
\usepackage{hyperref}
\hypersetup{colorlinks,urlcolor=blue}
\begin{document}
\urldef{\basicurl}\url{https://tex.stackexchange.com/questions}
blabla\endnote{\basicurl}
\clearpage
\printendnotes
\end{document}
生成
在尾注页面上,红色数字1
是对主文档中出现该命令的位置的反向引用\endnote
。
到目前为止一切顺利。有没有办法通过将硬编码的宏名称替换为 来概括此设置\basicurl
?\csname zz\themycounter\endcsname
这里\themycounter
是计数器变量名称值的阿拉伯数字表达式,名为mycounter
。(背景:文档最终将保留许多尾注,每个都有一个 URL 字符串,并且不可能\basicurl
在每个\endnote
命令之前定义一个新的指令。我试图提出\urldef
唯一,以便与埃诺特兹包。有关更多背景信息,请参阅此查询。
我天真地尝试过
\documentclass{article}
\newcounter{mycounter}
\usepackage{url} % for \url and \urldef commands
\usepackage{enotez} % for \endnote and \printendnotes commands
\setenotez{backref = true}
\usepackage{hyperref}
\hypersetup{colorlinks,urlcolor=blue}
\begin{document}
\stepcounter{mycounter}
\urldef{\csname zz\themycounter\endcsname}\url{https://tex.stackexchange.com/questions}
blabla\endnote{\csname zz\themycounter\endcsname}
\clearpage
\printendnotes
\end{document}
但这会产生以下错误消息:
! Extra \endcsname.
\declare@robustcommand ...e \string #1 \endcsname
l.11 ...url{https://tex.stackexchange.com/questions}
是我做错了什么,还是\urldef
真的无法处理\csname ... \endcsname
-type 宏命令?
附录,在收到@JairoA.delRio的建议后发布,以替换
\urldef{\csname zz\themycounter\endcsname}\url{...}
和
\expandafter\urldef\expandafter{\csname zz\themycounter\endcsname}\url{...}
这种修改确实解决了上述问题。然而,它导致了另一个问题,最好的例子是以下扩展的(双关语)MWE:
\documentclass{article}
\newcounter{mycounter}
\usepackage{url} % for \url and \urldef commands
\usepackage{enotez} % for \endnote and \printendnotes commands
\setenotez{backref = true}
\usepackage{hyperref}
\hypersetup{colorlinks,urlcolor=blue}
\begin{document}
\stepcounter{mycounter}
\expandafter\urldef\expandafter{\csname zz\themycounter\endcsname}\url{https://tex.stackexchange.com/questions}
blabla\endnote{\csname zz\themycounter\endcsname}
\stepcounter{mycounter}
\expandafter\urldef\expandafter{\csname zz\themycounter\endcsname}\url{https://www.sciencedirect.com/science/article/abs/pii/S0304405X00000763}
more blabla\endnote{\csname zz\themycounter\endcsname}
\clearpage
\printendnotes
\end{document}
这基本上与以前相同 - 除了增加了一组\stepcounter{mycounter}
、\urldef
和\endnote
指令。不幸的是,尾注页面现在包含以下内容:
请注意,尽管 的两个实例分别使用了和\endnote
的等效项,但相同的 URL 字符串会显示两次。\zz1
\zz2
更新的问题:我的代码中是否还有其他不正确的地方,或者我是否可能遇到了错误埃诺特兹包裹?
答案1
使用\endnote{\csname zz\themycounter\endcsname}
,存储在尾注中的文本将具有,因此将使用\themycounter
当时的当前值。\printendnotes
您必须构建控制序列名称前 \endnote
开始工作。但有一个问题!总是有一个问题,你知道……
由于enotez
它所输入的令牌列表的处理方式\zz2
(由于您的\urldef
,将被单独处理(这是因为该内容存储在.aux
文件中)就像它\zz
后面跟着 一样2
。
如何修复?使用罗马数字代替阿拉伯数字。
\documentclass{article}
\usepackage{url} % for \url and \urldef commands
\usepackage{enotez} % for \endnote and \printendnotes commands
\usepackage{hyperref}
\setenotez{backref = true}
\hypersetup{colorlinks,urlcolor=blue}
\newcounter{mycounter}
\renewcommand{\themycounter}{\romannumeral\value{mycounter}}
\begin{document}
\stepcounter{mycounter}
\expandafter\urldef\csname zz\themycounter\endcsname
\url{https://tex.stackexchange.com/questions}
blabla\expandafter\endnote\expandafter{\csname zz\themycounter\endcsname}
\stepcounter{mycounter}
\expandafter\urldef\csname zz\themycounter\endcsname
\url{https://www.sciencedirect.com/science/article/abs/pii/S0304405X00000763}
more blabla\expandafter\endnote\expandafter{\csname zz\themycounter\endcsname}
\clearpage
\printendnotes
\end{document}
为什么不
\renewcommand{\themycounter}{\roman{mycounter}}
而不是使用原始的\romannumeral
?因为有些babel
模块重新定义\roman
的方式会与这项工作相冲突。
我们可以为这种尾注定义一个宏。
\documentclass{article}
\usepackage{url} % for \url and \urldef commands
\usepackage{enotez} % for \endnote and \printendnotes commands
\usepackage{hyperref}
\setenotez{backref = true}
\hypersetup{colorlinks,urlcolor=blue}
\ExplSyntaxOn
\NewDocumentCommand{\endnoteurl}{v}
{
\int_incr:N \__mico_endnoteurl_int
\exp_args:Nc \urldef { zz \int_to_roman:n { \__mico_endnoteurl_int } } \url{#1}
\exp_args:Ne \endnote
{ \exp_not:c { zz \int_to_roman:n { \__mico_endnoteurl_int } } }
}
\int_new:N \__mico_endnoteurl_int
\ExplSyntaxOff
\begin{document}
blabla\endnoteurl{https://tex.stackexchange.com/questions}
more blabla\endnoteurl{https://www.sciencedirect.com/science/article/abs/pii/S0304405X00000763}
\clearpage
\printendnotes
\end{document}
答案2
这是一个扩展问题。第一个问题已由杰罗·A·德尔里奥在评论中:您需要在尝试使用它\csname <string>\endcsname
之前进行扩展。所以\urldef
\expandafter\urldef\expandafter{\csname zz\themycounter\endcsname}
\url{https://tex.stackexchange.com/questions}
作品。
这是因为行为与这里\urldef
非常相似。使用\def
\def\csname zz\themycounter\endcsname{Hullo}
你重新定义\csname
。但
\expandafter\def\csname zz\themycounter\endcsname{Hullo}
你实际上重新定义了\zz<expansion of \themycounter>
。
类似的事情也适用于\endnote
,但是我们还需要考虑\endnote
将尾注的内容写入外部文件(需要小心扩展)。
\endnote
尝试按原样写入其参数而不进行扩展。您将希望\endnote
写入\csname zz<expansion of \themycounter>\endcsname
文件,而不是\csname zz\themycounter\endcsname
或其他任何内容(特别是我们也不想要\zz1
,我们需要\csname zz1\endcsname
)。
我放弃了尝试找出这里的最佳扩展数量(在这种情况下是三个),而是\edef
使用老\begingroup \edef...{\endgroup}
技巧进行了全面扩展(关于 \begingroup\edef\x{\endgroup)(只要\themycounter
是可扩展的,那么这就是安全的,当您说 时,您已经假设了这一点\csname zz\themycounter\endcsname
)。
这两件事可能最容易通过辅助定义来完成。
\documentclass{article}
\usepackage{url}
\usepackage{enotez}
\setenotez{backref = true}
\usepackage{hyperref}
\hypersetup{colorlinks,urlcolor=blue}
\newcounter{mycounter}
\newcommand*\zzurldef{\zzurldednr{\themycounter}}
\newcommand*\zzurldednr[1]{\expandafter\urldef\expandafter{\csname zz#1\endcsname}}
\newcommand*\zzendnote{%
\begingroup
\edef\temp{\endgroup
\noexpand\zzendnotenr{\themycounter}}%
\temp}
\newcommand*\zzendnotenr[1]{\endnote{\csname zz#1\endcsname}}
\begin{document}
\stepcounter{mycounter}
\zzurldef\url{https://tex.stackexchange.com/questions}
blabla\zzendnote
\stepcounter{mycounter}
\zzurldef\url{https://www.sciencedirect.com/science/article/abs/pii/S0304405X00000763}
more blabla\zzendnote
\printendnotes
\end{document}