随着我对这个问题的了解越来越多,我对这个问题进行了大量的编辑。
如果我足够优秀,我就可以创建带有多个可选参数的宏,但我不仅不能,而且在这种情况下,我还试图调整现有结构。我编写这个boxhandler
包是为了能够调整图形/表格标题布局(特别是调整我所在组织的一种奇怪风格)。除此之外,图形的语法是
\bxfigure[htbp]{caption}{figure content}
有人请求能够使用 的\caption
可选参数,但当前结构不允许。因此,我认为我可以提供一种与上述语法或以下语法兼容的语法
\bxfigure[htbp]{[LOF caption]full caption}{figure content}
我认为可以做到这一点的代码是
\documentclass{article}
\usepackage{boxhandler}
\usepackage{etoolbox}
\makeatletter
\renewcommand\bx@caption[1]{%
\expandafter\optcaption\expandafter[#1]\relax%
}
\def\optcaption[#1]#2\relax{%
\ifstrempty{#2}{\caption{#1}}{\caption[\@gobble#1]{\striptrailingbracket#2}}}
%\ifstrempty{#2}{Full caption is \fbox{#1}}
% {LOF caption is \fbox{\@gobble#1} Full caption is \fbox{\striptrailingbracket#2}}}
\def\striptrailingbracket#1]{#1}
\makeatother
\begin{document}
\listoffigures
%\def\x{my caption}
%\expandafter\optcaption\expandafter[\x]\relax
\def\x{[LOF caption]my caption}
%\expandafter\optcaption\expandafter[\x]\relax
\bxfigure[h]{my caption}{\fbox{TEXT}}
\bxfigure[h]{[LOF caption]my caption}{\fbox{TEXT}}
\bxfigure[h]{\x}{\fbox{TEXT}}
%\optcaption[[LOF caption]my caption]\relax
\end{document}
但是如你所见,\optcaption
解析器不会从参数中提取括号内的内容,并且始终认为#1
的参数\def\optcaption[#1]#2\relax{}
没有右括号。
为了简化问题,\optcaption
除了将其包含在 中之外,我还专门研究了 的行为\bxfigure
。这里,
\documentclass{article}
\usepackage{boxhandler}
\usepackage{etoolbox}
\makeatletter
\renewcommand\bx@caption[1]{%
\expandafter\optcaption\expandafter[#1]\relax%
}
\def\optcaption[#1]#2\relax{%
%\ifstrempty{#2}{\caption{#1}}{\caption[\@gobble#1]{\striptrailingbracket#2}}}
\ifstrempty{#2}{Full caption is \fbox{#1}}
{LOF caption is \fbox{\@gobble#1} Full caption is \fbox{\striptrailingbracket#2}}}
\def\striptrailingbracket#1]{#1}
\begin{document}
All of these work...\par
\bx@caption{[LOF caption]my caption}\par
\def\x{my caption}
\bx@caption{\x}\par
\def\x{[LOF caption]my caption}\par
\bx@caption{\x}\par
~\\The following does not work (and boxhandler passes the caption via a
csname; this is the root of the problem)\par
\bx@caption{\csname x\endcsname}\par
~\\This fixes it, but it requires me to change the code that calls bx@caption\par
\expandafter\bx@caption\expandafter{\csname x\endcsname}
\end{document}
我们看到,它能够检测]
并提取可选参数,即使该参数是通过宏传递的\x
,但当它以的形式传递时则不行\csname x\endcsname
。
所以我想我可以回去并改变boxhandler
调用\bx@caption
以预先扩展,\csname
就像我在上一个例子中所做的那样(请参阅下面的答案)。
但是如果有人可以重写\bx@caption
以便能够正确地消化一个\csname
论点(无需修补\ReciteFigure
),我会接受这个答案。
答案1
LaTeX 可选参数是通过以下方式定义的分隔参数\def\foo[#1]{...}
(除非您通过 latex3 声明定义它们),[]
因此不是匹配,并且参数在第一个]
\optcaption[[LOF caption]my caption]\relax
#1
是[LOF caption
要使用[]
可选参数,您需要
\optcaption[{[LOF caption]my caption}]\relax
LaTeX3 声明定义命令使用更慢、更谨慎的方式来选择匹配的可选参数[]
。
目前尚不清楚
\caption[\@gobble#1]
是预期要做的事情,但它几乎肯定会做错事。
如果#1
是, [LOF caption]full caption
那么上面是
\caption[\@gobble[LOF caption]full caption]
因此,可选参数是\caption
和\@gobble[LOF caption
将\@gobble
吞噬,[
但是,以下强制参数\caption
是就只是f
。和ull caption]
被留作尾随标记,执行它们所做的任何操作。
在您编辑的问题中,您需要扩展两次,或者更简单地扩展,直到出现不可扩展的标记,然后再[
寻找
\renewcommand\bx@caption[1]{%
\expandafter\optcaption\expandafter[\romannumeral-`x#1]\relax%
}
答案2
好吧,一旦我确定问题在于消化传递\csname
给 的\bx@caption
,我就会确定一个解决方案是修补boxhandler
以预扩展传递的参数。使用我的第一个示例中的定义,并修补对 的调用即可\bx@caption
解决此问题。
如果其他人无需诉诸 就能解决这个问题xpatch
,我会接受这个答案。
David 使用这个技巧的编辑\romannumeral
,
\renewcommand\bx@caption[1]{%
\expandafter\optcaption\expandafter[\romannumeral-`x#1]\relax%
}
而不是我在这个答案中所说的,减轻了对 的需求xpatch
,所以他得到了分数!谢谢你,大卫。
\documentclass{article}
\usepackage{xpatch}% http://ctan.org/pkg/etoolbox
\usepackage{boxhandler}
\usepackage{etoolbox}
\makeatletter
\xpatchcmd{\ReciteFigure}% <cmd>
{\bx@caption}% <search>
{\expandafter\bx@caption\expandafter}% <replace>
{}{}% <success><failure>
\xpatchcmd{\ReciteTable}% <cmd>
{\bx@caption}% <search>
{\expandafter\bx@caption\expandafter}% <replace>
{}{}% <success><failure>
\renewcommand\bx@caption[1]{%
\expandafter\optcaption\expandafter[#1]\relax%
}
\def\optcaption[#1]#2\relax{%
\ifstrempty{#2}{\caption{#1}}{\caption[\@gobble#1]{\striptrailingbracket#2}}}
\def\striptrailingbracket#1]{#1}
\makeatother
\begin{document}
\listoffigures
\bxfigure[ht]{my caption}{\fbox{TEXT}}
\bxfigure[ht]{[LOF caption]my caption}{\fbox{TEXT}}
\end{document}