From 942371aef371d8b90a56be8c67afcc4cf6a50223 Mon Sep 17 00:00:00 2001 From: Bastien Dumont Date: Tue, 5 Aug 2025 12:48:06 +0200 Subject: [PATCH] The last arg of \crossrefenum can now be a comma-delimited list --- tex/crossrefenum.tex | 77 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/tex/crossrefenum.tex b/tex/crossrefenum.tex index 81d9912..72f1a64 100644 --- a/tex/crossrefenum.tex +++ b/tex/crossrefenum.tex @@ -75,6 +75,13 @@ %%% Initialization: Programming macros %%% +% Trivial macros + +\def\crfnm@appendToToks#1#2{#1=\expandafter{\the#1#2}} +\expandafter\def\expandafter\crfnm@gobspace\space{} +\def\crfnm@lettok#1#2{\let#1= #2} +\crfnm@lettok\crfnm@space{ } + % \crfnm@case is a standard case statement. % #1 is the string or the purely expandable macro to be tested. % #2 is a sequence of tests of the form: @@ -605,7 +612,8 @@ {% % Initializes the environment for this invocation, % then passes the enumeration to the parsing - % and formatting macro \crfnm@formatEnum. + % and formatting macro \crfnm@formatEnum + % through \crfnm@getAndProcessList. \global\advance\crfnm@ienum by 1 % The reference type is capitalized so that it can be used % to refer to macro names typed in camelCase @@ -633,9 +641,10 @@ \edef\crfnm@printedRefsNb@previousPass{% \crfnm@getPrintedRefsNb@previousPass }% - % The following macro will process sequentially - % all references in the enumeration. - \expandafter\crfnm@formatEnum#3{crfnm@enumend}% + \edef\crfnm@thearg{#3}% + \ifx\crfnm@thearg\crfnm@empty\else + \expandafter\crfnm@getAndProcessList\expandafter{\crfnm@thearg}% + \fi }% } @@ -742,13 +751,57 @@ } \crfnm@endCases +% If the last argument of \crossrefenum is a list of groups, +% pass it directly to \crfnm@formatEnum. +% Else, it is a comma-delimited list of strings (with optional leading spaces) +% to be transformed to a list of groups suitable for \crfnm@formatEnum. +\def\crfnm@getAndProcessList#1{% + \crfnm@getListDispatcher #1\crfnm@enumend +} + +\def\crfnm@getListDispatcher{\futurelet\crfnm@nexttok\crfnm@getList@dispatcher} +\def\crfnm@getList@dispatcher{% + \ifx\crfnm@nexttok\bgroup + \expandafter\crfnm@formatEnum + \else + \expandafter\crfnm@commaListToGroups + \fi +} + +\newtoks\crfnm@listAsGroups +\def\crfnm@commaListToGroups#1\crfnm@enumend{% + \crfnm@listAsGroups={}% + \crfnm@commaList@toGroups#1,\crfnm@end,% +} +\def\crfnm@commaList@toGroups#1,{% + \edef\crfnm@thearg{#1}% + \ifx\crfnm@thearg\crfnm@end + \def\crfnm@todo{% + \expandafter\crfnm@formatEnum\the\crfnm@listAsGroups\crfnm@enumend + }% + \else + \crfnm@appendToToks\crfnm@listAsGroups{{#1}}% + \def\crfnm@todo{\futurelet\crfnm@nexttok\crfnm@nextItemToGroup}% + \fi + \crfnm@todo +} +\def\crfnm@nextItemToGroup{% + \ifx\crfnm@nexttok\crfnm@space + \def\crfnm@todo{\expandafter\crfnm@commaList@toGroups\crfnm@gobspace}% + \else + \let\crfnm@todo\crfnm@commaList@toGroups + \fi + \crfnm@todo +} + + %%% \crossrefenum: Processing the individual references in the enumeration %%% \def\crfnm@formatEnum#1{% % #1 is a string consisting of either: % *