将宏插入`\label`并且`保护`宏时代码崩溃无法修复

将宏插入`\label`并且`保护`宏时代码崩溃无法修复

此代码崩溃是因为我将宏包含tmplabel命令中。阅读此论坛,尤其是脆弱命令和坚固命令之间有什么区别?,我以为\protect我放在前面的\tmp应该可以解决问题,但事实并非如此。有人能解释一下如何让它工作吗?非常感谢您的任何建议

\documentclass{amsart}
\usepackage{soul}
\usepackage{xstring}
\begin{document}
\def\tmp{fig:\StrBefore{file.png}{.}}
\tmp
\begin{figure}
\caption{nothing}
\label{\protect\tmp}
%\label{\tmp}
\end{figure}
\end{document}

答案1

xstring我只想使用将提取结果存储在宏中的能力。

\documentclass{amsart}
\usepackage{soul}
\usepackage{xstring}
\begin{document}
\StrBefore{file.png}{.}[\tmp]
\edef\tmp{fig:\tmp}
\tmp
\begin{figure}
\caption{nothing}
\label{\tmp}
\end{figure}
\end{document}

在此处输入图片描述

答案2

的宏xstring通常不可扩展,但这里需要它。因此,我将其改为listofitems,它会产生可扩展的结果。

\documentclass{amsart}
\usepackage{soul}
\usepackage{listofitems}
\begin{document}
\setsepchar{.}
\readlist\fileroot{file.png}
\edef\tmp{fig:\fileroot[1]}
\tmp
\begin{figure}
\caption{nothing}
\label{\tmp}
\end{figure}

I refer to figure \ref{fig:file}
\end{document}

在此处输入图片描述

这是一个甚至不需要的版本listofitems

\documentclass{amsart}
\usepackage{soul}
\newcommand\fileroot[1]{\filerootaux#1.\relax}
\def\filerootaux#1.#2\relax{#1}
\begin{document}
\edef\tmp{fig:\fileroot{file.png}}
\tmp
\begin{figure}
\caption{nothing}
\label{\tmp}
\end{figure}

I refer to figure \ref{fig:file}
\end{document}

答案3

的参数\label应该是最终变成字符串的东西,但\StrBefore最终变成打印某些字符的说明,这是一件非常不同的事情。

这更简单,除非您的文件名中可以​​包含多个句点。

\documentclass{article}

\makeatletter
\newcommand{\stripext}[1]{\strip@ext#1.\@nil}
\def\strip@ext#1.#2\@nil{#1}
\makeatother

\begin{document}

\stripext{file.png}
\label{\stripext{file.png}}

\stripext{filenoext}
\label{\stripext{filenoext}}

\end{document}

诀窍是使用带有分隔参数的宏。如果我们这样做\stripext{file.png},我们会得到

\strip@ext file.png.\@nil

并且宏\strip@ext将使用#1任何出现的直到第一个.;在这种情况下它是file

在的情况下\stripext{filenoext},我们得到

\strip@ext filenoext.\@nil

一切也都很好。在第一种情况下#2png.,在第二种情况下它是空的;但第二个参数被简单地丢弃了。

.aux上述代码中的文件将包含

\relax
\newlabel{file}{{}{1}}
\newlabel{filenoext}{{}{1}}

所以你看它正如预期的那样。

相关内容