diff options
author | Karl Berry <karl@freefriends.org> | 2021-07-13 20:03:54 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-07-13 20:03:54 +0000 |
commit | 3879f5443ec624b0f958ce876d5b31234e093755 (patch) | |
tree | 59ad60abc4bdac40d5bed2253c5cd138948e41d0 /Master/texmf-dist/source/latex/macrolist | |
parent | 0bb3c5527b41beba30393f50228233238c56197f (diff) |
macrolist (13jul21)
git-svn-id: svn://tug.org/texlive/trunk@59919 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/macrolist')
-rw-r--r-- | Master/texmf-dist/source/latex/macrolist/macrolist.dtx | 325 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/macrolist/macrolist.ins | 45 |
2 files changed, 370 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/macrolist/macrolist.dtx b/Master/texmf-dist/source/latex/macrolist/macrolist.dtx new file mode 100644 index 00000000000..9c0ee6eb62b --- /dev/null +++ b/Master/texmf-dist/source/latex/macrolist/macrolist.dtx @@ -0,0 +1,325 @@ +% \iffalse meta-comment +% +% Copyright (C) 2021 Dennis Chen <proofprogram@gmail.com> +% +% This file may be distributed and/or modified under +% the conditions the LaTeX Project Public License (LPPL), +% either version 1.3 of this license or (at your option) +% any later version. The latest version of this license +% can be found in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% \fi +% +% \iffalse +%<*package> + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{macrolist}[2021/07/09 v1.0.0 Create lists of macros and perform operations on them] + +\RequirePackage{pgffor} +%</package> + +%<*driver> +\documentclass{ltxdoc} +\usepackage{macrolist} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{macrolist.dtx} + \PrintIndex +\end{document} +%</driver> +% \fi +% \changes{v1.0.0}{2021/07/01}{Initial version} +% +% \GetFileInfo{macrolist.sty} +% +% \title{\textsf{macrolist} -- Create lists of macros and manipulate them} +% \author{Dennis Chen \\ proofprogram@gmail.com} +% \date{\fileversion, v. \filedate\thanks{\url{https://github/com/chennisden/macrolist}}} +% +% \maketitle +% +% \begin{abstract} +% The \textsf{macrolist} package allows you to create lists and manipulate them, with utilities such as |\listforeach| and an implementation of arr.join() from Javascript. Contrary to the name of the package, non-macros and groups of macros can be put into an item of the list. +% \end{abstract} +% +% \section{Usage} +% +% \DescribeMacro{\newlist} +% To create a list, pass in |\newlist{listname}| to create a list with the name \textsf{listname}. +% +% The package checks that \textsf{listname} is not the name of another list, and will throw an error if another list \textsf{listname} has already been defined. +% +% \iffalse +\newcommand{\newlist}[1]{ + \ifcsname c@macrolist@list@#1\endcsname + \PackageError{macrolist}{The list '#1' is already defined}{} + \else + \newcounter{macrolist@list@#1} + \setcounter{macrolist@list@#1}{0} + \fi +} +% \fi +% +% \DescribeMacro{\listelement} +% +% To execute the \textsf{i}th element of \textsf{listname}, write |\listelement{listname}{i}|. Note that \textit{lists are 1-indexed}, meaning the first element is numbered 1, the second element numbered 2, and so on. +% +% An error will be thrown if \textsf{listname} is not a defined list, if \textsf{i} is empty, or if \textsf{i} is greater than the size of the list. +% +% \iffalse +\newcommand{\listelement}[2]{% + \macrolist@inbounds{#1}{#2}% + \csname macrolist@list@#1\the\numexpr #2\relax\endcsname% +} +% \fi +% +% \DescribeMacro{\listadd} +% +% To add something to the list \textsf{listname}, pass in |\listadd{listname}[position]{element}|, where \textsf{position} is an optional argument. If nothing is passed in for \textsf{position}, then by default \textsf{element} will be added to the end of the list. +% +% \iffalse +\newcommand{\listadd}[1]{ + \macrolist@exists{#1} + \def\macrolist@currlist{#1} + \macrolist@listadd +} +%% We write \listadd this way such that the optional argument will be positioned correctly +\newcommand{\macrolist@listadd}[2][]{ + \stepcounter{macrolist@list@\macrolist@currlist} + + \if\relax\detokenize{#1}\relax + \expandafter\def\csname macrolist@list@\macrolist@currlist\listsize{\macrolist@currlist}\endcsname{#2} + \else + \expandafter\ifnum\csname themacrolist@list@\macrolist@currlist\endcsname=#1 + \expandafter\def\csname macrolist@list@\macrolist@currlist\listsize{\macrolist@currlist}\endcsname{#2} + \else + \macrolist@inbounds{\macrolist@currlist}{#1} + \foreach \macrolist@index in {\listsize{\macrolist@currlist}, ...,\the\numexpr #1+1\relax} { + \global\expandafter\let\csname macrolist@list@\macrolist@currlist\macrolist@index\expandafter\endcsname\csname macrolist@list@\macrolist@currlist\the\numexpr\macrolist@index-1\relax\endcsname + } + \expandafter\def\csname macrolist@list@\macrolist@currlist#1\endcsname{#2} + \fi + \fi +} +% \fi +% +% \DescribeMacro{\listremove} +% +% To remove an element in a list, write |\listremove{listname}{index}|. +% +% \iffalse +\newcommand{\listremove}[2]{ + \macrolist@inbounds{#1}{#2} + + \ifnum\numexpr#2\relax=\listsize{#1} + \else + \foreach \macrolist@index in {#2, ..., \the\numexpr\listsize{#1}-1\relax} { + \global\expandafter\let\csname macrolist@list@#1\macrolist@index\expandafter\endcsname\csname macrolist@list@#1\the\numexpr\macrolist@index+1\endcsname + } + \fi + + \expandafter\let\csname macrolist@list@#1\listsize{#1}\endcsname\relax + \addtocounter{macrolist@list@#1}{-1} +} +% \fi +% +% \DescribeMacro{\listremovelast} +% +% To remove the last element in a list, write |\listremovelast{listname}|. This behaves like C++'s |pop_back|. +% +% \iffalse +\newcommand{\listremovelast}[1]{ + \macrolist@exists{#1} + \expandafter\let\csname macrolist@list@#1\listsize{#1}\endcsname\relax + \addtocounter{macrolist@list@#1}{-1} +} +% \fi +% +% \DescribeMacro{\listclear} +% +% To clear a list, write |\listclear{listname}|. +% +% \iffalse +\newcommand{\listclear}[2]{ + \macrolist@inbounds{#1}{#2} + + \foreach \macrolist@index in {1, ..., \listsize{#1}} { + \expandafter\let\csname \macrolist@list@#1\macrolist@index\endcsname\relax + } + + \setcounter{macrolist@list@#1}{0} +} +% \fi +% +% \DescribeMacro{\listsize} +% +% To get the size of a list, write |\listsize{listname}|. +% +% \iffalse +\newcommand*{\listsize}[1]{% + \macrolist@exists{#1}% + \csname themacrolist@list@#1\endcsname +} +% \fi +% +% \DescribeMacro{\listforeach} +% +% To write a for each loop, write +% \begin{verbatim} +%\begin{listforeach}{listname}{\element}[begin][end]{action} +% \end{verbatim} +% +% +% Note that begin and end are optional arguments, and by default, they take the values \textsf{1} and |\listsize{listname}|. If you pass in \textsf{begin}, you must also pass in \textsf{end}. +% +% \iffalse +\newcommand{\listforeach}[2] +{ + \def\macrolist@foreachstart{0} % Reset + % This is used to make optional arguments line up correctly + + \def\macrolist@start{1} + \def\macrolist@end{\listsize{#1}} + \def\macrolist@listname{#1} + \def\macrolist@element{#2} + \macrolist@listforeachi +} + +\newcommand{\macrolist@listforeachi}[1][]{ + \if\relax\detokenize{#1}\relax + \else + \def\macrolist@start{#1} + \def\macrolist@foreachstart{1} + \fi + \macrolist@listforeachii +} + +\newcommand{\macrolist@listforeachii}[1][]{ + \if\relax\detokenize{#1}\relax + \ifnum\macrolist@foreachstart=1 + \PackageError{macrolist}{You must either pass in both a starting and ending position or neither}{} + \fi + \else + \def\macrolist@end{#1} + \fi + \macrolist@listforeachaction +} + +\newcommand{\macrolist@listforeachaction}[1]{ + + \macrolist@exists{\macrolist@listname} + + \ifnum\numexpr\macrolist@start\relax>\listsize{\macrolist@listname}% + \PackageError{macrolist}{The starting index of the loop is out of the bounds of list '\macrolist@listname'}{} + \fi + + \ifnum\numexpr\macrolist@end\relax>\listsize{\macrolist@listname} + \PackageError{macrolist}{The ending index of the loop is out of the bounds of list '\macrolist@listname'}{} + \fi + + \foreach \macrolist@index in {\the\numexpr\macrolist@start\relax, ..., \the\numexpr\macrolist@end\relax} {% + \expandafter\expandafter\expandafter\let\expandafter\expandafter\macrolist@element\csname macrolist@list@\macrolist@listname\macrolist@index\endcsname + #1% + }% +} +% \fi +% +% \DescribeMacro{\listjoin} +% +% Executing |\listjoin{listname}{joiner}| returns all of the elements separated by \textsf{joiner}. This behaves like Javascript's \textsf{arr.join()}. +% +% \iffalse +\newcommand{\listjoin}[2]{% + \ifnum\listsize{#1}>1 + \listforeach{#1}{\macrolist@joinelement}[1][\listsize{#1}-1]{\macrolist@joinelement#2}% + \fi + \ifnum\listsize{#1}>0 + \listelement{#1}{\listsize{#1}}% + \fi +} +% \fi +% +% \section{Example} +% Here is the source code for a small document using \textsf{macrolist}. +% +% \begin{verbatim} +%\documentclass{article} +%\usepackage{macrolist} +% +%\begin{document} +% +%\newlist{mylist} +%\listadd{mylist}{Some text} +%% List: Some text +% +%\newcommand\macro{This is a macro} +% +%\listadd{mylist}{\macro} +%% List: Some text, \macro +% +%\listelement{mylist}{1} +%% Prints out "Some text" +% +%\listadd{mylist}[1]{Element inserted into beginning} +%% List: Element inserted into beginning, Some text, \macro +% +%\listremove{mylist}{1} +%% List: Some text, \macro +% +%\listforeach{mylist}{\element}{We're printing out \textbf{\element}. } +%% We're printing out \textbf{Some text}. We're printing out \textbf{\macro}. +% +%\listjoin{mylist}{, } +%% Some text, \macro +% +%\end{document} +% \end{verbatim} +% +% \section{Implementation details} +% +% All internal macros are namespaced to prevent package conflicts. +% +% \begin{macro}{\macrolist@exists} +% One internal macro we use is |\macrolist@exists{listname}|, which checks that \textsf{listname} exists. It throws an error otherwise. +% +% \begin{macrocode} +\newcommand*{\macrolist@exists}[1]{% + \ifcsname c@macrolist@list@#1\endcsname + \else + \PackageError{macrolist} + {The first argument is not a defined list} + {Make sure you have defined the list before trying to operate on it.} + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\macrolist@inbounds} +% We use |\macrolist@inbounds{listname}{index}| to check that first, \textsf{listname} is a defined list using |\macrolist@exists|, and second, that \textsf{index} is within bounds. It throws an error otherwise. +% \begin{macrocode} +\newcommand*{\macrolist@inbounds}[2]{% + \macrolist@exists{#1}% + % + \if\relax\detokenize{#2} + \PackageError{macrolist} + {No number has been passed into the second argument of your command + }{Pass in a number to the second argument of your command.} + \fi + % + \ifnum\numexpr#2 \relax>\listsize{#1} + \PackageError{macrolist} + {Index out of bounds} + {The number you have passed in to the second argument of your command\MessageBreak + is out of the bounds of list '#1'.} + \fi +} +% \end{macrocode} +% \end{macro} +% +% \Finale +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/macrolist/macrolist.ins b/Master/texmf-dist/source/latex/macrolist/macrolist.ins new file mode 100644 index 00000000000..df2ac1265d4 --- /dev/null +++ b/Master/texmf-dist/source/latex/macrolist/macrolist.ins @@ -0,0 +1,45 @@ +%% Copyright (C) 2021 Dennis Chen <proofprogram@gmail.com> +%% +%% This work may be distributed and/or modified under +%% the conditions the LaTeX Project Public License (LPPL), +%% either version 1.3 of this license or (at your option) +%% any later version. The latest version of this license +%% can be found in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/macrolist} + +\preamble +This work may be distributed and/or modified under +the conditions the LaTeX Project Public License (LPPL), +either version 1.3 of this license or (at your option) +any later version. The latest version of this license +can be found in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. +\endpreamble + +\generate{\file{macrolist.sty}{\from{macrolist.dtx}{package}}} + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* files into a directory searched by TeX: *} +\Msg{* *} +\Msg{* macrolist.sty *} +\Msg{* *} +\Msg{* To produce the documentation, run the file *} +\Msg{* macrolist.dtx through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile
\ No newline at end of file |