summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/withargs/withargs.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/withargs/withargs.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/withargs/withargs.sty')
-rw-r--r--macros/latex/contrib/withargs/withargs.sty330
1 files changed, 330 insertions, 0 deletions
diff --git a/macros/latex/contrib/withargs/withargs.sty b/macros/latex/contrib/withargs/withargs.sty
new file mode 100644
index 0000000000..c7d715687a
--- /dev/null
+++ b/macros/latex/contrib/withargs/withargs.sty
@@ -0,0 +1,330 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \iffalse %%%%
+% %
+% Copyright (c) 2016 - Michiel Helvensteijn (www.mhelvens.net) %
+% %
+% This work may be distributed and/or modified under the conditions %
+% of the LaTeX Project Public License, either version 1.3 of this %
+% license or (at your option) any later version. The latest version %
+% of this license is 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. %
+% %
+% This work has the LPPL maintenance status `maintained'. %
+% %
+% The Current Maintainer of this work is Michiel Helvensteijn. %
+% %
+% This work consists of the files withargs.tex and withargs.sty. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \fi %%%%
+
+% \CheckSum{117}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Package Info} %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{expl3}
+\ProvidesExplPackage{withargs}{2016/12/19}{0.2.0}
+ {an inline construct for passing token lists as TeX parameters}
+% \end{macrocode}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Required Packages} %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% We just need some expl3-ish packages.
+%
+% \begin{macrocode}
+\RequirePackage{xparse}
+\RequirePackage{l3regex}
+% \end{macrocode}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{\LaTeX3 Functions} %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % \begin{macro}{\withargs:nn,\withargs:nnn,\withargs:nnnn,\withargs:nnnnn,\withargs:nnnnnn,
+ % \withargs:nnnnnnn,\withargs:nnnnnnnn,\withargs:nnnnnnnnn}
+ % \(\overbrace{\hbox{\marg1 \marg2 \marg3 \marg4 \marg5 \marg6 \marg7 \marg8}}^{1-8}\)
+ % \marg{body}
+%%% \\[-.5\belowdisplayskip]\nopagebreak
+%
+% \noindent These are the |expl3| API versions of the |\withargs| command.
+% The implementation is quite straight-forward. This technique has to
+% be used by any library command that accepts \TeX-style parameters.
+%
+% \begin{macrocode}
+\cs_new_protected:Nn \withargs:nn {
+ \cs_set:Npn \__withargs:n ##1 {#2}
+ \__withargs:n {#1} }
+\cs_new_protected:Nn \withargs:nnn {
+ \cs_set:Npn \__withargs:nn ##1##2 {#3}
+ \__withargs:nn {#1}{#2} }
+\cs_new_protected:Nn \withargs:nnnn {
+ \cs_set:Npn \__withargs:nnn ##1##2##3 {#4}
+ \__withargs:nnn {#1}{#2}{#3} }
+\cs_new_protected:Nn \withargs:nnnnn {
+ \cs_set:Npn \__withargs:nnnn ##1##2##3##4 {#5}
+ \__withargs:nnnn {#1}{#2}{#3}{#4} }
+\cs_new_protected:Nn \withargs:nnnnnn {
+ \cs_set:Npn \__withargs:nnnnn ##1##2##3##4##5 {#6}
+ \__withargs:nnnnn {#1}{#2}{#3}{#4}{#5} }
+\cs_new_protected:Nn \withargs:nnnnnnn {
+ \cs_set:Npn \__withargs:nnnnnn ##1##2##3##4##5##6 {#7}
+ \__withargs:nnnnnn {#1}{#2}{#3}{#4}{#5}{#6} }
+\cs_new_protected:Nn \withargs:nnnnnnnn {
+ \cs_set:Npn \__withargs:nnnnnnn ##1##2##3##4##5##6##7 {#8}
+ \__withargs:nnnnnnn {#1}{#2}{#3}{#4}{#5}{#6}{#7} }
+\cs_new_protected:Nn \withargs:nnnnnnnnn {
+ \cs_set:Npn \__withargs:nnnnnnnn ##1##2##3##4##5##6##7##8 {#9}
+ \__withargs:nnnnnnnn {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8} }
+% \end{macrocode}
+%
+%%% \end{macro}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Document Level Command} %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % \begin{macro}{\__withargs_var:x} \marg{argument specifier}
+%%% \\[-.5\belowdisplayskip]\nopagebreak
+%
+% \noindent This is a convenience command for generating
+% and using a |\withargs:| variant in one go. I only use it
+% for the document-level command, since those users can't
+% roll their own.
+%
+% |#1| should be the number of optional |\withargs| arguments
+% and |#2| should be a \LaTeX3 argument specification not
+% longer than |#1| --- a prefix.
+%
+% \begin{macrocode}
+\cs_new:Nn \__withargs_var:nn {
+ \cs_generate_variant:cx
+ { withargs : \prg_replicate:nn{#1}{n} n }
+ { #2 n }
+ \use:c {
+ withargs :
+ #2
+ \prg_replicate:nn{#1-\tl_count:n{#2}}{n}
+ n
+ }
+}
+% \end{macrocode}
+% \uninteresting\begin{macrocode}
+\cs_generate_variant:Nn \__withargs_var:nn {nx}
+\cs_generate_variant:Nn \cs_generate_variant:Nn {cx}
+% \end{macrocode}
+%
+%%% \end{macro} \vspace{-2mm}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % \begin{macro}{\__withargs_process_uniquecsname:n}
+ % \marg{argument}
+%%% \\[-.5\belowdisplayskip]\nopagebreak
+%
+% \noindent An |xparse| processor function to pass a unique
+% control sequence name if the argument given was '|\uniquecsname|'.
+%
+% \begin{macrocode}
+\cs_new_protected:Nn\__withargs_process_uniquecsname:n{
+ \tl_if_eq:nnTF {#1} {\uniquecsname} {
+ \int_gincr:N \g__with_unique_int
+ \tl_set:Nx \ProcessedArgument
+ { Unique-CS-Name-( \int_use:N\g__with_unique_int ) }
+ }{
+ \tl_set:Nn \ProcessedArgument {#1}
+ }
+}
+\int_new:N \g__with_unique_int
+% \end{macrocode}
+%
+%%% \end{macro} \vspace{-2mm}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % \begin{macro}{\__withargs_remove_spaces:n}
+ % \marg{argument}
+%%% \\[-.5\belowdisplayskip]\nopagebreak
+%
+% \noindent An |xparse| processor function to remove all
+% spaces from the argument.
+%
+% \begin{macrocode}
+\cs_new_protected:Nn\__withargs_remove_spaces:n{
+ \tl_set:Nn \ProcessedArgument {#1}
+ \tl_remove_all:Nn\ProcessedArgument {~}
+}
+% \end{macrocode}
+%
+%%% \end{macro} \vspace{-2mm}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+% \pagebreak
+
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % \begin{macro}{\withargs}
+ % \texttt{\bfseries(}\meta{argument specification}\texttt{\bfseries)}
+ % \oarg{1} \oarg{2} \oarg{3} \oarg{4} \oarg{5} \oarg{6} \oarg{7}
+ % \marg{body}
+%%% \\[-.5\belowdisplayskip]\nopagebreak
+%
+% \noindent This is the document version of the |\withargs| command.
+%
+% \changes{0.0.2}{2013/10/11}
+% {made the first argument optional and delimited by parentheses}
+%
+% \begin{macrocode}
+\NewDocumentCommand {\withargs}
+ { >{\__withargs_remove_spaces:n} D(){} % argument spec
+ >{\__withargs_process_uniquecsname:n} +o % up to 7 optional args
+ >{\__withargs_process_uniquecsname:n} +o
+ >{\__withargs_process_uniquecsname:n} +o
+ >{\__withargs_process_uniquecsname:n} +o
+ >{\__withargs_process_uniquecsname:n} +o
+ >{\__withargs_process_uniquecsname:n} +o
+ >{\__withargs_process_uniquecsname:n} +o
+ +m } { % the body to execute
+% \end{macrocode}
+%
+% We first check if the argument specification is valid.
+% It has to be between 0 and 7 characters long and each
+% symbol has to be one of `|noxfcv|'. Otherwise: error!
+% The variants `|N|' and `|V|' are not supported (yet) because
+% they collect arguments differently than the others, and frankly,
+% I didn't want to bother.
+%
+% \begin{macrocode}
+ \regex_match:nnF {^[nofxcv]{0,7}$} {#1}
+ { \msg_critical:nnn{withargs}{invalid-parameter-specs}{#1} }
+% \end{macrocode}
+%
+% The next bit counts the number of optional arguments provided
+% using binary search.
+% If |#1| specifies \emph{more} arguments than were provided: error!
+%
+% \begin{macrocode}
+ \int_set:Nn \l__with_arg_int {
+ \IfNoValueTF {#5}
+ { \IfNoValueTF {#3} { \IfNoValueTF{#2} 0 1 }
+ { \IfNoValueTF{#4} 2 3 } }
+ { \IfNoValueTF {#7} { \IfNoValueTF{#6} 4 5 }
+ { \IfNoValueTF{#8} 6 7 } }
+ }
+
+ \int_compare:nNnT {\tl_count:n{#1}} > {\l__with_arg_int} {
+ \msg_error:nnxxx{withargs}{invalid-parameter-number}
+ { \tl_count:n{#1} }
+ { \int_use:N \l__with_arg_int }
+ { #1 }
+ }
+% \end{macrocode}
+%
+% We can then call the right variant of |\withargs:|.
+%
+% \begin{macrocode}
+ \int_case:nnF {\l__with_arg_int} {
+ {1} { \__withargs_var:nx1{#1} {#2} {#9} }
+ {2} { \__withargs_var:nx2{#1} {#2}{#3} {#9} }
+ {3} { \__withargs_var:nx3{#1} {#2}{#3}{#4} {#9} }
+ {4} { \__withargs_var:nx4{#1} {#2}{#3}{#4}{#5} {#9} }
+ {5} { \__withargs_var:nx5{#1} {#2}{#3}{#4}{#5}{#6} {#9} }
+ {6} { \__withargs_var:nx6{#1} {#2}{#3}{#4}{#5}{#6}{#7} {#9} }
+ {7} { \__withargs_var:nx7{#1} {#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9} }
+ }{}
+% \end{macrocode}
+% \uninteresting\begin{macrocode}
+}
+\int_new:N \l__with_arg_int
+% \end{macrocode}
+%
+%%% \end{macro}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \noindent The following is the error message displayed
+% if the argument specification is ill-formed:
+%
+% \begin{macrocode}
+\msg_new:nnnn{withargs}{invalid-parameter-specs}{
+ The~argument~specification~'#1'~is~not~valid.
+}{
+ The~argument~specification~should~consist~of~between~one~
+ and~seven~of~the~letters~'n',~'o',~'f',~'x',~'c',~'v'.
+}
+% \end{macrocode}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \noindent This is the error message displayed if the
+% number of provided optional arguments is inconsistent
+% with the provided argument specification.
+%
+% \begin{macrocode}
+\msg_new:nnnn{withargs}{invalid-parameter-number}{
+ You~specified~#1~arguments~but~provided~#2.
+}{
+ Your~argument~specification~is~'#3',~which~means~you~should~
+ provide~#1~optional~arguments.~However,~you~provided~#2.~
+ You~should~fix~that.
+}
+% \end{macrocode}
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%