2

I would like to sort the list of figures by caption alphabetically (instead of the order of appearance).

Something like

List of figures

4 Aaaa      3
1 Bbbbb     1
8 Ddd dd    10

Is there a way?

  • 3
    The makeindex package might help. Normally LOF entries are stored as a file, as opposed to labels which are stored as global macros \csname r@labelname\endcsname. The aux file shows what information is available to be used. – John Kormylo May 13 at 21:38
4
+100

A latex3 implementation, using \tex_strcmp:D to compare strings.

  • Here \tex_strcmp:D is the latex3 alias taken from primitive \pdfstrcmp in pdftex or \strcmp in xetex. It takes two arguments, and expands to 1 if arg1 > arg2, to 0 if arg1 == arg2, and to -1 if otherwise.
  • 18 May 2020 update: It is now compatible with both tocbibind (which redefines \listoffigures) and hyperref (which redefines \contentsline)
\documentclass{article}
\usepackage{tocbibind}
\usepackage{hyperref}
\usepackage{xpatch}

\ExplSyntaxOn
\makeatletter

% a seq of clist "<sort key>,<orig contents line>"
\seq_new:N \g_lof_seq

% backup
\cs_set_eq:NN \contentsline_orig \contentsline
\cs_set_eq:NN \numberline_orig   \numberline


% patch \@starttoc to insert two hooks
\xpatchcmd \@starttoc
  { \begingroup }
  {
    \begingroup
    \tl_if_eq:nnT {#1} {lof}
      { \hook_before_starttoc: }
  }
  {}{\fail}
\xpatchcmd \@starttoc
  { \endgroup }
  {
    \tl_if_eq:nnT {#1} {lof}
      { \hook_after_starttoc: }
    \endgroup
  }
  {}{\fail}


% hook inserted at the beginning of \@starttoc
\cs_new:Nn \hook_before_starttoc:
  {
    \seq_clear:N \g_lof_seq

    \cs_set_eq:NN \contentsline \contentsline_new
    \cs_set_eq:NN \numberline   \numberline_new
  }


% hook inserted at the end of \@starttoc
\cs_new:Nn \hook_after_starttoc:
  {
    % for i in seq, sort by the top element of i
    \seq_sort:Nn \g_lof_seq
      {
        \clist_set:Nn \l_tmpa_clist {##1}
        \clist_set:Nn \l_tmpb_clist {##2}
        \clist_get:NN \l_tmpa_clist \l_tmpa_tl
        \clist_get:NN \l_tmpb_clist \l_tmpb_tl

        \int_compare:nNnTF
          % \tex_strcmp:D is the primitive \pdfstrcmp in pdftex 
          % or \strcmp in xetex
          { \exp_args:NVV \tex_strcmp:D \l_tmpa_tl \l_tmpb_tl } = 1
          { \sort_return_swapped: }
          { \sort_return_same: }
      }

    % restore
    \cs_set_eq:NN \contentsline \contentsline_orig
    \cs_set_eq:NN \numberline   \numberline_orig

    % output
    \seq_map_inline:Nn \g_lof_seq
      {
        \clist_set:Nn \l_tmpa_clist {##1}
        \clist_item:Nn \l_tmpa_clist {2}
      }
  }


% variant definition of \contentsline
% for every <contents line>, store clist of "<title>,<orig contents line>" in \g_lof_seq
\@ifpackageloaded{hyperref}
  {
    % eg, \contentsline{figure}{\numberline{3}{\ignorespaces Aaa}}{2}{figure.3}%
    \cs_new:Npn \contentsline_new #1#2#3#4
      {
        % eg, #2 == \numberline{3}{\ignorespaces Aaa}
        #2

        \clist_clear:N \l_tmpa_clist
        \clist_put_right:NV \l_tmpa_clist \l_tmpa_tl
        \clist_put_right:Nn \l_tmpa_clist 
          { \contentsline{#1}{#2}{#3}{#4} } % different here

        \seq_gput_right:NV \g_lof_seq \l_tmpa_clist
      }
  }
  {
    % eg, \contentsline{figure}{\numberline{3}{\ignorespaces Aaa}}{2}%
    \cs_new:Npn \contentsline_new #1#2#3
      {
        % eg, #2 == \numberline{3}{\ignorespaces Aaa}
        #2

        \clist_clear:N \l_tmpa_clist
        \clist_put_right:NV \l_tmpa_clist \l_tmpa_tl
        \clist_put_right:Nn \l_tmpa_clist 
          { \contentsline{#1}{#2}{#3} } % different here

        \seq_gput_right:NV \g_lof_seq \l_tmpa_clist
      }
  }

% variant definition of \numberline, store title part in \l_tmpa_tl
\cs_new:Npn \numberline_new #1#2
  {
    \tl_set:Nn \l_tmpa_tl {#2}
  }

\makeatother
\ExplSyntaxOff


\begin{document}
\renewcommand{\listfigurename}{List of Figures (sorted by title)}
\listoffigures
\newpage

\begin{figure} content \caption{Ddd} \end{figure}
\begin{figure} content \caption{Bbb} \end{figure}
\begin{figure} content \caption{Aaa} \end{figure}
\begin{figure} content \caption{Ccc} \end{figure}
\end{document}

enter image description here

| improve this answer | |
  • Thanks. It's not working with the package tocbibind but I'll try to figure out why – Matteo May 17 at 16:56
  • With tobibind I get no errors but the content is not ordered anymore. With hyperref I get some additional text (figure.0, figure.1) before the list of figures – Matteo May 17 at 17:38
  • @Matteo Answer is updated, now it is compatible with both tocbibind and hyperref. – muzimuzhi Z May 17 at 23:31
  • Thanks again. Works perfectly – Matteo May 18 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.