% !TeX TXS-program:compile = txs:///arara % arara: pdflatex: {shell: no, synctex: no, interaction: batchmode} % arara: pdflatex: {shell: no, synctex: no, interaction: batchmode} \documentclass[11pt,a4paper]{ltxdoc} \usepackage{bera} \usepackage{inconsolata} \usepackage[T1]{fontenc} \usepackage[scale=0.875]{cabin} \usepackage{commalists-tools} \usepackage{fancyvrb} \usepackage{fancyhdr} \usepackage{tabularray} \usepackage{fontawesome5} \fancyhf{} \renewcommand{\headrulewidth}{0pt} \lfoot{\sffamily\small [commalists-tools]} \cfoot{\sffamily\small - \thepage{} -} \rfoot{\hyperlink{matoc}{\small\faArrowAltCircleUp[regular]}} \usepackage{hologo} \providecommand\tikzlogo{Ti\textit{k}Z} \providecommand\TeXLive{\TeX{}Live\xspace} \let\TikZ\tikzlogo \usepackage{hyperref} \urlstyle{same} \hypersetup{pdfborder=0 0 0} \usepackage[margin=2cm]{geometry} \setlength{\parindent}{0pt} \def\TPversion{0.1.4} \def\TPdate{24/10/2024} \usepackage{tcolorbox} \usepackage{pgffor} \tcbuselibrary{breakable,skins,hooks,listingsutf8} %\usepackage{soul} %\sethlcolor{lightgray!25} \lstset{ language=[LaTeX]TeX,% basicstyle=\ttfamily,% keywordstyle={\color{blue}},% classoffset=0,% keywords={},% alsoletter={-},% keywordstyle={\color{blue}},% classoffset=1,% alsoletter={-},% morekeywords={commalists-tools},% keywordstyle={\color{violet}},% classoffset=2,% alsoletter={-},% morekeywords={\sortasclist,\sortdeslist,\addvalinlist,\removevalinlist,\boolvalinlist,\testifvalinlist,\countvalinlist,\minoflist,\maxoflist,\meanoflist,\sumoflist,\prodoflist,\reverselist,\getvaluefromlist,\lenoflist,\getvaluefromlist,\definemylist,\countvalindeflist,\lenofdeflist,\meanofdeflist,\sumofdeflist,\prodofdeflist,\getvaluefromdeflist},% keywordstyle={\color{green!50!black}},% classoffset=3,% morekeywords={},% keywordstyle={\color{orange}} } \newtcblisting{DemoCode}[1]{% enhanced,width=\linewidth,% bicolor,size=title,% colback=cyan!10!white,% colbacklower=cyan!5!white,% colframe=cyan!75!black,% listing options={% breaklines=true,% breakatwhitespace=true,% style=tcblatex,basicstyle=\small\ttfamily,% tabsize=4,% commentstyle={\itshape\color{gray}}, keywordstyle={\color{blue}},% classoffset=0,% keywords={\usepackage,\includegraphics,xstring,listofitems,\readlist,\showitems,\xintFor,\xintSeq},% alsoletter={-},% keywordstyle={\color{blue}},% classoffset=1,% alsoletter={-},% morekeywords={euromoney},% keywordstyle={\color{violet}},% classoffset=2,% alsoletter={-},% morekeywords={\sortasclist,\sortdeslist,\addvalinlist,\removevalinlist,\boolvalinlist,\testifvalinlist,\countvalinlist,\minoflist,\maxoflist,\meanoflist,\sumoflist,\prodoflist,\reverselist,\getvaluefromlist,\lenoflist,\getvaluefromlist,\definemylist,\countvalindeflist,\lenofdeflist,\meanofdeflist,\sumofdeflist,\prodofdeflist,\getvaluefromdeflist},% keywordstyle={\color{green!50!black}},% classoffset=3,% morekeywords={},% keywordstyle={\color{orange}} },% #1 } \newtcbinputlisting\DemoCodeFile[1]{% enhanced,width=\linewidth,% bicolor,size=title,% colback=lightgray!10!white,% colbacklower=lightgray!5!white,% colframe=lightgray!75!black,% listing options={% breaklines=true,% breakatwhitespace=true,% style=tcblatex, basicstyle=\scriptsize\ttfamily,% tabsize=4,% commentstyle={\itshape\color{gray}},% %lastline=148 },% breakable, listing only,% listing file={#1} } \NewDocumentCommand\ShowCode{ m }{% \lstinline{#1}% } \begin{document} \thispagestyle{empty} \begin{center} \begin{minipage}{0.88\linewidth} \begin{tcolorbox}[colframe=yellow,colback=yellow!15] \begin{center} \renewcommand{\arraystretch}{1.25}% \begin{tabular}{c} {\Huge \texttt{commalists-tools}}\\ \\ {\LARGE Macros for manipulating numeral} \\ {\LARGE comma separated lists:} \\ {\LARGE sorting, adding, removing, etc} \\ \\ {\small \texttt{Version \TPversion{} -- \TPdate}} \end{tabular} \end{center} \end{tcolorbox} \end{minipage} \end{center} \begin{center} \begin{tabular}{c} \texttt{Cédric Pierquet}\\ {\ttfamily c pierquet -- at -- outlook . fr}\\ \texttt{\url{https://github.com/cpierquet/commalists-tools}} \\ \end{tabular} \end{center} \hrule \vfill \begin{tcblisting}{colframe=lightgray,colback=lightgray!5,listing only} \def\mytestlist{14,10,15,11,9,10} \lenoflist*{\mytestlist} \minoflist*{\mytestlist} \maxoflist*{14,10,15,11,9,10} \sortasclist*{\mytestlist} \meanoflist*{\mytestlist} \removevalinlist*{10}{\mytestlist} \testifvalinlist{15}{\mytestlist}{true}{false} \getvaluefromlist*{\mytestlist}{3} \end{tcblisting} \begin{tcolorbox}[colframe=lightgray,colback=lightgray!5] \def\mytestlist{14,10,15,11,9,10} We consider the list: \mytestlist\par\smallskip There's \lenoflist*{\mytestlist} values in the list\par\smallskip The minimum value is \minoflist*{\mytestlist} and the maximum is \maxoflist*{14,10,15,11,9,10}\par\smallskip Ascending sorted list is \sortasclist*{\mytestlist}\par\smallskip Meaning value of the list is \meanoflist*{\mytestlist}\par\smallskip If we remove the value 10, then the list is \removevalinlist*{10}{\mytestlist}\par\smallskip We test if 15 is in the list: \testifvalinlist{15}{\mytestlist}{true}{false}\par\smallskip The third value of the list is \getvaluefromlist*{\mytestlist}{3} \end{tcolorbox} \vfill~ %\hrule % %\medskip %\emph{% % The \textsf{luarandom} package do the same things, but with the obligation to compile with \hologo{LuaLaTeX}. %} % %\medskip \hrule \vspace*{5mm} \pagebreak \phantomsection \hypertarget{matoc}{} \tableofcontents \vspace*{5mm} %\hrule \pagebreak \section{Loading, useful packages} In order to load \texttt{randintlist}, simply use: \begin{DemoCode}{listing only} \usepackage{commalists-tools} \end{DemoCode} Loaded packages are \texttt{listofitems}, \texttt{xintexpr} and \texttt{xstring}. \smallskip The idea is to propose "reusage" of lists with \texttt{listofitems} or other commands, for example. \section{The individual macros} \subsection{Global usage} Package \texttt{commalists-tools} supports (basic) manipulations on numeral comma separated lists: \begin{itemize} \item sorting; \item adding values; \item removing values; \item counting values; \item mean, sum, product; \item get value, get length; \item etc. \end{itemize} Starred versions only print the result, whereas non starred versions store the result into a macro. \medskip \hfill\textbf{All engines \TeX\ are compatible with this package.}\hfill~ \subsection{The macros for calculating} \begin{DemoCode}{listing only} %getting length of list, only printing \lenoflist*{list} %storing length of list into macro (\resmylen by default) \lenoflist{list} %getting min of list, only printing \minoflist*{list} %storing min of list into \macro (\resmin by default) \minoflist{list}[\macro] %getting max of list, only printing \maxoflist*{list} %storing max of list into \macro (\resmax by default) \maxoflist{list}[\macro] \end{DemoCode} \begin{DemoCode}{} %only printing \lenoflist*{14,10,15,11,9,10}\\ %only printing \minoflist*{14,10,15,11,9,10} and \maxoflist*{14,10,15,11,9,10} \end{DemoCode} \begin{DemoCode}{} %storing len/min/max of list \def\mytestlist{10,14.5,20,12,8.5} \lenoflist{\mytestlist}[\mylen]Length of list is \mylen\ \& \minoflist{\mytestlist}[\mymin]Min of list is \mymin\ \& \maxoflist{\mytestlist}[\mymax]Max of list is \mymax \end{DemoCode} \begin{DemoCode}{listing only} %getting mean of list, only printing \meanoflist*{list} %storing mean of list into \macro (\resmean by default) \meanoflist{list}[\macro] %getting sum of list, only printing \sumoflist*{list} %storing max of list into \macro (\ressum by default) \sumoflist{list}[\macro] %getting prod of list, only printing \prodoflist*{list} %storing max of list into \macro (\resprod by default) \prodoflist{list}[\macro] \end{DemoCode} \begin{DemoCode}{} %only printing \meanoflist*{14,10,15,11,9,10} \\ %storing \meanoflist{14,10,15,11,9,10}[\mymean]\mymean \\ %only printing \sumoflist*{14,10,15,11,9,10} and \prodoflist*{14,10,15,11,9,10} \\ %storing \sumoflist{14,10,15,11,9,10}[\mysum]\prodoflist{14,10,15,11,9,10}[\myprod] The sum is \mysum\ and the prod is \myprod \end{DemoCode} \subsection{Macros for manipulating} \begin{DemoCode}{listing only} %sorting (asc), only printing \sortasclist*{list} %sorting (asc) and storing (overwrite) \sortasclist{list} %sorting (des), only printing \sortdeslist*{list} %sorting (des) and storing (overwrite) \sortdeslist{list} \end{DemoCode} \begin{DemoCode}{} %sorting (asc), only printing \sortasclist*{14,10,15,11.5,9,10}\\ %sorting (asc) and storing (overwrite) \def\tmpsortlist{14,10,15,11.5,9,10} \sortasclist{\tmpsortlist}\tmpsortlist\\ %analysing \readlist*\tmpSORTlist{\tmpsortlist} \showitems{\tmpSORTlist} \end{DemoCode} \begin{DemoCode}{listing only} %extract value, only printing \getvaluefromlist*{list}{index} %extract value and storing into macro (\myelt by default) \getvaluefromlist{list}{index}[\macro] \end{DemoCode} \begin{DemoCode}{} %extract value, only printing \def\listtmp{1,2,3,6,3,1,5,7,3}% \getvaluefromlist*{\listtmp}{4}\par\smallskip %storing \getvaluefromlist{\listtmp}{-1}[\mylastelt]The last element is \mylastelt \end{DemoCode} \begin{DemoCode}{} %sorting (des), only printing \sortdeslist*{14,10,15,11.5,9,10}\\ %sorting (asc) and storing (overwrite) \def\tmpsortlist{14,10,15,11.5,9,10} \sortdeslist{\tmpsortlist}\tmpsortlist\\ %analysing \readlist*\tmpSORTlist{\tmpsortlist} \showitems{\tmpSORTlist} \end{DemoCode} \begin{DemoCode}{listing only} %adding, only printing \addvalinlist*{values}{list} %adding and storing (overwrite) \addvalinlist{values}{list} %removing, only printing \removevalinlist*{value}{list} %removing and storing (overwrite) \removevalinlist{value}{list} \end{DemoCode} \begin{DemoCode}{} %only printing \addvalinlist*{3}{1,2,5,6}\\ %defining and adding \def\tmpaddlist{1,2,4,5,6} \addvalinlist{3}{\tmpaddlist}\tmpaddlist\\ %analysing \readlist*\tmpADDlist{\tmpaddlist} \showitems{\tmpADDlist} \end{DemoCode} \begin{DemoCode}{} %only printing \removevalinlist*{3}{1,2,3,6,3,1,5,7,3}\\ %defining and removing \def\tmpremlist{1,2,3,6,3,1,5,7,3} \removevalinlist{3}{\tmpremlist}\tmpremlist\\ %analysing \readlist*\tmpREMlist{\tmpremlist} \showitems{\tmpREMlist} \end{DemoCode} \begin{DemoCode}{listing only} %reversing, only printing \reverselist*{list} %reversing and storing (overwrite) \reverselist{list} \end{DemoCode} \begin{DemoCode}{} %only printing \reverselist*{14,10,15,11,9,10}\\ %reversing and storing %storing \reverselist{14,10,15,11,9,10}[\myreverse]\myreverse\\ %analysing \readlist*\tmpREVERSElist{\myreverse} \showitems{\tmpREVERSElist} \end{DemoCode} \subsection{Macros with testing} \begin{DemoCode}{listing only} %testing if value is in list, with boolean result in \macro (\resisinlist by default) \boolvalinlist{value}{list}[\macro] %conditionnal test if value is in list, according to xint syntax \testifvalinlist{3}{0,1,2,3}{true}{false} \end{DemoCode} \begin{DemoCode}{} %test with xint syntax \testifvalinlist{-1}{0,1,2,3}{true}{false}\\ %test with xint syntax \testifvalinlist{3}{0,1,2,3}{true}{false}\\ %boolean macro \def\myteslist{0,5,10,5,6,9,7,8} \boolvalinlist{5}{\myteslist}[\resisinlist]\resisinlist \end{DemoCode} \begin{DemoCode}{listing only} %counting value, only printing \countvalinlist*{value}{list} %counting value, with result in \macro (\rescount by default) \countvalinlist{value}{list}[\macro] \end{DemoCode} \begin{DemoCode}{} %only printing \countvalinlist*{8}{1,2,3,4,5,6,6,7,8,8,8,9}\\ %storing \def\tmpcountlist{1,2,3,4,5,6,6,7,8,8,8,9} \countvalinlist{6}{\tmpcountlist}[\rescountsix]\rescountsix\\ \countvalinlist{10}{\tmpcountlist}[\rescountten]\rescountten \end{DemoCode} \pagebreak \section{Macros for already processed lists} In order to speed up the process, it's possible to "define" a list (processed with \texttt{listofitems}) and the to call specific macros. \begin{DemoCode}{listing only} %define a list, to be processed by listofitems \definemylist{rawlist}{processed list} %Specific macros (same specs as above) \lenofdeflist(*){processed list, without \ !}[\macro] \countvalindeflist(*){val}{processed list, without \ !}[\macro] \meanofdeflist(*){processed list, without \ !}[\macro] \sumofdeflist(*){processed list, without \ !}[\macro] \prodofdeflist(*){processed list, without \ !}[\macro] \getvaluefromdeflist(*){processed list, without \ !}{index}[\macro] \end{DemoCode} \begin{DemoCode}{} %define a list, to be processed by listofitems \definemylist{1,4,5,6,7,8,9,19,9,9,10}{\mydeflist}\showitems{\mydeflist} %Specific macros \lenofdeflist*{mydeflist}\\ \getvaluefromdeflist*{mydeflist}{5}\\ \countvalindeflist*{9}{mydeflist}\\ \meanofdeflist*{mydeflist}\\ \sumofdeflist*{mydeflist}\\ \prodofdeflist*{mydeflist} \end{DemoCode} If the list needs to be "modified" (add, remove, reverse) the best is to use individual macros, and after use \textit{define} and specific macros :-) \pagebreak \section{History} \texttt{0.1.3: Changing name of macro} \texttt{0.1.3: Duplicate macro with ProfMaquette (so new name)} \texttt{0.1.2: Alternative macros for already treated lists} \texttt{0.1.1: Compatibility with decimals, len of list, get value} \texttt{0.1.0: Initial version} \section{The code} \DemoCodeFile{commalists-tools.sty} \end{document}