I have a document with requirements marked up in text with a custom macro \Req{}, which takes a comma separated list of identifiers of the form [A-F]:[0-9]{4,5}([0-9]{1,2})?, outputs the identifiers and calls \index for each of them. I need the index to be output ordered by the numeric part of the identifier, so am attempting to pad the numeric part of the identifier into a sort key to pass to \index{thing!sort-key@text}. This is performed by \padreq:n:
\documentclass{article}
\usepackage{expl3}
\usepackage{imakeidx}
\usepackage{xparse}
\makeindex[name=a2b, columns=1]
\ExplSyntaxOn
% #1 length
% #2 padee
\cs_new:Nn \padint:nn
{ % From : https://tex.stackexchange.com/a/412238/104401
\prg_replicate:nn { #1 - \tl_count:f { \int_to_arabic:n { #2 } } } { 0 }
\int_to_arabic:n { #2 }
}
\cs_generate_variant:Nn \tl_count:n { f }
% takes x.y, pads to 00000x.0y
\cs_new:Nn \padreq:n
{
% temp variables
\seq_clear_new:N \l_padreq_tmp_seq
\tl_clear_new:N \l_padreq_tmp_tl
% split arg 1
\seq_set_split:Nnn \l_padreq_tmp_seq {.} {#1}
\seq_log:N \l_padreq_tmp_seq
% Take the first item...
\seq_pop_left:NNT \l_padreq_tmp_seq \l_padreq_tmp_tl
{ % ... and pad it
%\padint:nn{5}{\l_padreq_tmp_tl}
\padint:nn{5}{\l_padreq_tmp_tl}
}
% Add the middle '.'
.
% Take next split item, which is optional
\seq_pop_left:NNTF \l_padreq_tmp_seq {\l_padreq_tmp_tl}
{ % and pad it
\padint:nn{2}{\l_padreq_tmp_tl}
}
{ % or set a default of 00 if missing
00
}
}
\cs_generate_variant:Nn \padreq:n { x }
\DeclareDocumentCommand{\Req}{m}
{
% Split the csv input
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
% output back to the document, with formatting
[ \seq_use:Nn \l_tmpa_seq {,~} ]
% Index each value, creating a sort key for \index
\seq_map_inline:Nn \l_tmpa_seq {
% Split by colon
% colons with expl3 https://tex.stackexchange.com/a/501346/104401
\use:x {\exp_not:N\seq_set_split:Nnn \exp_not:N\l_tmpb_seq {\c_colon_str} {##1}}
% Pad the 2nd item in the split sequence
\tl_set:Nn \l_tmpa_tl {\padreq:x{\seq_item:Nn \l_tmpb_seq 2}}
\newline ##1~--~\l_tmpa_tl % debug, typesets correctly
\index[a2b]{MWE!\l_tmpa_tl@##1}
}
}
\ExplSyntaxOff
\begin{document}
Hello. \Req{C:230, A:10}
\par
World. \Req{B:101.1}
\printindex[a2b]
\end{document}
This produces an a2b.idx of:
\indexentry{MWE!\padreq:x {230}@C:230}{1}
\indexentry{MWE!\padreq:x {10}@A:10}{1}
\indexentry{MWE!\padreq:x {101.1}@B:101.1}{1}
whereas, I think, makeindex will treat it literally and it needs to be evaluated for the idx file.
Printed index should be in order A B C, but ends up B A C.
The symptoms are the same as this unanswered question, but I'm using expl3 Expanding macro in \index argument.
There are now enough copy 'n paste fixes in my solution (padding, colons, general expl3 bodging) that I get the feeling I'm missing something obvious, as everything I've tried has either made no difference or broken it completely. What am I doing wrong?


