% Author : C. Pierquet % licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txt \NeedsTeXFormat{LaTeX2e} \ProvidesExplPackage{commalists-tools-l3}{2025-08-27}{0.1.6}{Basic operations for numeral comma separated lists} %------History % 0.1.6 Initial version (prefixed macros due to legacy package) %------Variables \clist_new:N \l__commalists_clist \fp_new:N \l__commalists_tmpa_fp %-----Macros (LaTeX3...) \NewDocumentCommand\ctshowlist{ O{,} m } { \clist_set:Nx \l__commalists_clist { #2 } \clist_use:Nn \l__commalists_clist { #1 } } \NewDocumentCommand\ctsortasclist{ s m O{\mysortedlist} } { \clist_set:Nx \l_foo_clist {#2} \clist_sort:Nn \l_foo_clist{ \fp_compare:nNnTF { ##1 } > { ##2 } { \sort_return_swapped: } { \sort_return_same: } } \IfBooleanTF{#1}%if star := just printing // if not, storing { {\l_foo_clist} } { \tl_gset:Nx \l_tmpa_tl { \l_foo_clist } \tl_gset:Nx #3 { \tl_use:N \l_tmpa_tl } } } \NewDocumentCommand\ctsortdeslist{ s m O{\mysortedlist} } { \clist_set:Nx \l_foo_clist {#2} \clist_sort:Nn \l_foo_clist{ \fp_compare:nNnTF { ##1 } < { ##2 } { \sort_return_swapped: } { \sort_return_same: } } \IfBooleanTF{#1}%if star := just printing // if not, storing { {\l_foo_clist}% } { \tl_gset:Nx \l_tmpa_tl { \l_foo_clist } \tl_gset:Nx #3 { \tl_use:N \l_tmpa_tl } } } \NewDocumentCommand\ctreverselist{ s m O{\reverselist} } { \clist_set:Nx \l__commalists_clist {#2} \IfBooleanTF{#1}%if star := just printing // if not, storing { \clist_reverse:N \l__commalists_clist \clist_use:Nn \l__commalists_clist { , } } { \clist_set_eq:NN #3 \l__commalists_clist \clist_greverse:N #3 } } \NewDocumentCommand{\ctaddvalinlist}{ s m m } { \IfBooleanTF{#1} { #3, #2 } { \tl_gset:Nx #3 { \tl_use:N #3 , #2 } } } \NewDocumentCommand{\ctboolvalinlist}{ m m O{\resisinlist} } { \clist_set:Nx \l__commalists_clist {#2} \tl_set:Nn #3 { 0 } \clist_map_inline:Nn { \l__commalists_clist } { \tl_if_eq:nxT {##1} {#1} { \tl_gset:Nn #3 { 1 } \clist_map_break: } } } \NewDocumentCommand{\cttestifvalinlist}{ m m m m } { \clist_set:Nx \l__commalists_clist {#2} \bool_set_false:N \l_tmpa_bool \clist_map_inline:Nn { \l__commalists_clist } { \tl_if_eq:nxT {##1} {#1} { \bool_set_true:N \l_tmpa_bool \clist_map_break: } } \bool_if:NTF \l_tmpa_bool { #3 } { #4 } } \NewDocumentCommand{\ctremovevalinlist}{ s m m O{\mytmplist} } { \clist_set:Nx \l__commalists_clist {#3} \clist_clear_new:N \l_tmpb_clist \clist_map_inline:Nn { \l__commalists_clist } { \tl_if_eq:nxF {##1} {#2} { \clist_put_right:Nn \l_tmpb_clist { ##1 } } } \IfBooleanTF{#1} { \clist_use:Nn \l_tmpb_clist { , } } { \tl_set:Nx \l_tmpa_tl { \clist_use:Nn \l_tmpb_clist { , } } \tl_gset:Nx #4 { \tl_use:N \l_tmpa_tl } } } \NewDocumentCommand\ctcountvalinlist{ s m m O{\rescount} }{% \clist_set:Nx \l__commalists_clist {#3} \int_zero:N \l_tmpa_int \clist_map_inline:Nn { \l__commalists_clist } { \tl_if_eq:nxT {##1} {#2} { \int_incr:N \l_tmpa_int } } \IfBooleanTF{#1} { \int_use:N \l_tmpa_int } { \tl_gset:Nx #4 { \int_use:N \l_tmpa_int } } } \NewDocumentCommand\ctminoflist{ s m O{\resmin} }{% \IfBooleanTF{#1}% { \fp_eval:n { min(#2) } } { \tl_gset:Nx #3 { \fp_eval:n { min(#2) } } } } \NewDocumentCommand\ctmaxoflist{ s m O{\resmax} }{% \IfBooleanTF{#1}% { \fp_eval:n { max(#2) } } { \tl_gset:Nx #3 { \fp_eval:n { max(#2) } } } } \NewDocumentCommand\ctsumoflist{ s m O{\ressum} }{% \clist_set:Nx \l__commalists_clist {#2} \fp_set:Nn \l__commalists_tmpa_fp { 0 } \clist_map_inline:Nn { \l__commalists_clist } { \fp_set:Nn \l__commalists_tmpa_fp { \fp_eval:n {\l__commalists_tmpa_fp + (##1) } } } \IfBooleanTF{#1}% { \fp_use:N \l__commalists_tmpa_fp } { \tl_gset:Nx #3 { \fp_use:N \l__commalists_tmpa_fp } } } \NewDocumentCommand\ctprodoflist{ s m O{\resprod} }{% \clist_set:Nx \l__commalists_clist {#2} \fp_set:Nn \l__commalists_tmpa_fp { 1 } \clist_map_inline:Nn { \l__commalists_clist } { \fp_set:Nn \l__commalists_tmpa_fp { \fp_eval:n {\l__commalists_tmpa_fp * (##1) } } } \IfBooleanTF{#1} { \fp_use:N \l__commalists_tmpa_fp } { \tl_gset:Nx #3 { \fp_use:N \l__commalists_tmpa_fp } } } \NewDocumentCommand\ctmeanoflist{ s m O{\resmean} }{% \clist_set:Nx \l__commalists_clist {#2} \fp_set:Nn \l__commalists_tmpa_fp { 0 } \clist_map_inline:Nn { \l__commalists_clist } { \fp_set:Nn \l__commalists_tmpa_fp { \fp_eval:n {\l__commalists_tmpa_fp + (##1) } } } \fp_set:Nn \l__commalists_tmpa_fp { \fp_eval:n { (\l__commalists_tmpa_fp) / ( \clist_count:N { \l__commalists_clist } ) } } \IfBooleanTF{#1}% { \fp_use:N \l__commalists_tmpa_fp } { \tl_gset:Nx #3 { \fp_use:N \l__commalists_tmpa_fp } } } \NewDocumentCommand\ctlenoflist{ s m O{\resmylen} }{% \clist_set:Nx \l__commalists_clist {#2} \IfBooleanTF{#1} { \clist_count:N { \l__commalists_clist } } { \tl_gset:Nx #3 { \clist_count:N { \l__commalists_clist } } } } \NewDocumentCommand\ctgetvaluefromlist{ s m m O{\resmyelt} }{% \clist_set:Nx \l__commalists_clist {#2} \IfBooleanTF{#1} { \clist_item:Nn \l__commalists_clist { #3 } } { \tl_gset:Nx #4{ \clist_item:Nn \l__commalists_clist { #3 } } } } \endinput