如何在 \urldef 的参数中使用 \csname 和 \endcsname?

如何在 \urldef 的参数中使用 \csname 和 \endcsname?

唐纳德·阿瑟瑙的 网址软件包提供了宏\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}

注释//1. https://tex.stackexchange.com/questions//2. https://www.sciencedirect.com/science/article/abs/pii/S0304405X00000763

相关内容