如何对按图号索引的列表进行排序?

如何对按图号索引的列表进行排序?

我想按项目编号对带有图表参考索引的列表进行排序。我的 MWE 如下:

\documentclass{article}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{duckuments}

\captionsetup[subfigure]{list=true}

\begin{document}

\begin{itemize}
    \item[\ref{fig:gimel}.] gimel
    \item[\ref{fig:alef}.] alef
    \item[\ref{fig:bet}.] bet
\end{itemize}

% Desired output:
% 1. alef
% 2a. bet
% 2b. gimel

\begin{figure}[b]
\centering
\includegraphics{example-image-a}
\caption{Alef.}
\label{fig:alef}
\end{figure}

\begin{figure}
    \begin{subfigure}[]{\textwidth}
    \centering
    \includegraphics[width=\textwidth]{example-image-b}
    \caption{Bet.}
    \label{fig:bet}
    \end{subfigure}
    
    \begin{subfigure}[]{\textwidth}
    \centering
    \includegraphics[width=\textwidth]{example-image-c}
    \caption{Gimel.}
    \label{fig:gimel}
    \end{subfigure}
    
    \caption{Double figure.}
\end{figure}

\end{document}

有什么技巧可以自动执行这种排序吗?

答案1

你可能想看看是否\listoffigures是你想要的,但我已经做了你要求的。在序言中添加

\makeatletter

% We store all the labels in a list
\def\orderedlabels{}
\def\addorderedlabel#1{%
    \expandafter\gdef\expandafter\orderedlabels\expandafter{\orderedlabels\do{#1}}%
}

% Hook on aux label entries
\let\orig@newl@bel\@newl@bel
\def\@newl@bel#1#2#3{%
    \addorderedlabel{#2}%
    \orig@newl@bel{#1}{#2}{#3}%
}

% For debugging
\def\rawprintorderedlabels{%
    \def\do##1{(##1),}%
    \orderedlabels
}

% Provide appearance of label item
\def\providelabelitem#1#2{%
    \expandafter\def\csname orderedlabel@#1\endcsname{#2}%
}

% Use appearance of label item
\def\placelabelitems{%
    \def\do##1{%
        \csname orderedlabel@##1\endcsname
        \expandafter\let\csname orderedlabel@##1\endcsname\relax
    }%
    \orderedlabels
}

\makeatother

并在您的文档中使用

\providelabelitem{fig:gimel}{
    \item[\ref{fig:gimel}.] gimel
}
\providelabelitem{fig:alef}{
    \item[\ref{fig:alef}.] alef
}
\providelabelitem{fig:bet}{
    \item[\ref{fig:bet}.] bet
}

\begin{itemize}
    \placelabelitems
\end{itemize}

这里发生了什么?

  • .aux我在文件的\newlabel命令中添加了一个钩子。该.aux文件在文档启动之前立即执行。
  • \newlabel命令现在另外将标签添加到列表中,我将其称为\orderedlabels
  • 在您的文档中(或序言中也可以),您可以使用\providelabelitem您想要在列表中看到的所有标签。
  • 接下来,调用\placelabelitems,它将遍历刚刚创建的标签列表,对于每个项目,如果您为相应的标签提供了一些内容,那么将放置这些提供的内容。

因此请注意,如果您指定的标签最终未被使用,它也不会出现在列表中,并且如果您没有在列表中包含所有图形,您也不会收到任何警告或错误。

您可以\placelabelitems多次使用,并且我已设置使用后删除的内容。因此,使用后\placelabelitems,只有您使用的内容\providelabelitems才会包含在下一个中\placelabelitems;不会泄漏。

这能达到你的要求吗?:)


更多自动化

  1. 如果你想要的只是简单的,\item就像你的例子一样,那么你可以在序言中添加

    \newcommand\providelabelname[2]{
        \providelabelitem{#1}{
            \item[\ref{#1}.] #2
        }
    }
    

    只需使用

    \begin{itemize}
        \providelabelname{fig:gimel}{gimel}
        \providelabelname{fig:alef}{alef}
        \providelabelname{fig:bet}{bet}
        \placelabelitems
    \end{itemize}
    

    在您的文档中。

  2. 更加自动化:如果您希望文本只是图形标签,就像在 MWE 中一样,请添加\usepackage{xstring}此命令

    \newcommand\provideallfigures{%
        \def\do##1{%
            \IfBeginWith{##1}{fig:}{%
                \providelabelname{##1}{\StrGobbleLeft{##1}{4}\relax}%
            }{}%
        }%
        \orderedlabels
    }
    

    然后你可以做

    \begin{itemize}
        \provideallfigures
        \placelabelitems
    \end{itemize}
    

相关内容