我想定义一个自定义环境,它接受一个可选参数,并且我希望能够使用链接到该环境nameref
。为此,我尝试了类似于以下 MWE 的方法:
\documentclass{article}
\usepackage{hyperref}
\usepackage{caption}
\usepackage{trace}
\newenvironment{myenv}[1][]
{
% define auxiliary variable, as #1 is not allowed in the end part of a newenvironment
\def\myarg{#1}
}
{
\captionof{table}{\myarg}
}
\begin{document}
\begin{myenv}[A title.\label{myenv:title}]
Something that pretends to be a table.
\end{myenv}
\traceon
\nameref{myenv:title}
\traceoff
\end{document}
跟踪显示 hyperref 正在定义以下宏:
\r@myenv:title ->{1}{1}{\myarg \relax }{table.1}{}
不出所料,这给了我一个
! Undefined control sequence.
<argument> \myarg
我想这是有道理的,因为 \myarg 仅在环境范围内定义。我现在的问题是:如何强制 \myarg 在传递给 之前进行扩展\r@myenv:title
?
我已经看过了关于扩展的类似问题,但无法采用该解决方案。
答案1
如果您使用xparse
,则\NewDocumentEnvironment
可以直接使用末尾部分的参数。在下面的代码中,我曾经\IfValueT
检查是否给出了可选参数,然后才使用\caption
。如果不进行此检查,则每次省略可选参数时都会设置一个空标题。另一种选择是首先使用强制参数,因为您要直接将其转发给\caption
(这可以使用\NewDocumentEnvironment{myenv}{ m }
而不是 来完成o
)。
不相关的注释:hyperref
应该作为文档中的最后一个包加载(这个经验法则有一些例外,例如cleveref
应该在它之后加载)。
\documentclass{article}
\usepackage{caption}
\usepackage{trace}
\usepackage{xparse}
\NewDocumentEnvironment{myenv}{ o }
{}
{%
\IfValueT{#1}{\captionof{table}{#1}}%
}
\usepackage{hyperref}
\begin{document}
\begin{myenv}[A title.\label{myenv:title}]
Something that pretends to be a table.
\end{myenv}
\traceon
\nameref{myenv:title}
\traceoff
\end{document}
答案2
关键是\myarg
在环境定义的结束部分进行扩展。
\documentclass{article}
\usepackage{hyperref}
\usepackage{caption}
\usepackage{trace}
\newenvironment{myenv}[1][]
{
% define auxiliary variable, as #1 is not allowed in the end part of a newenvironment
\def\myarg{#1}
}
{
\def\tmp{\captionof{table}}%
\expandafter\tmp\expandafter{\myarg}
}
\begin{document}
\begin{myenv}[A title.\label{myenv:title}]
Something that pretends to be a table.
\end{myenv}
\traceon
\nameref{myenv:title}
\traceoff
\end{document}