% \iffalse meta-comment % !TEX program = pdfLaTeX %<*internal> \iffalse % %<*readme> ----------------------------------------------------------------- ##### erw-l3 --- Utilities based on LaTeX3, such as 'merge sort' - Source repository: https://github.com/rogard/erw-l3 - Released under the LaTeX Project Public License v1.3c or later - See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- % %<*internal> \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi % %<*install> \input l3docstrip.tex \keepsilent \askforoverwritefalse \preamble ----------------------------------------------------------------------------- erw-l3 --- Utilities based on LaTeX3, such as 'merge sort' Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt ---------------------------------------------------------------------------- \endpreamble \postamble Copyright (C) 2020-2022 by Erwann Rogard This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this license or (at your option) any later version. The latest version of this license is in the file: http://www.latex-project.org/lppl.txt This work is "maintained" (as per LPPL maintenance status) by Erwann Rogard. This work consists of the file erw-l3.dtx and the derived files: erw-l3.sty, and erw-l3.pdf. \endpostamble \generate{ \file{\jobname.sty}{\from{\jobname.dtx}{package}} } % % \endbatchfile %<*internal> \generate{ \file{\jobname.ins}{\from{\jobname.dtx}{install}} } \nopreamble\nopostamble \generate{ \file{README.md}{\from{\jobname.dtx}{readme}} } \ifx\fmtname\nameofplainTeX \expandafter\endbatchfile \else \expandafter\endgroup \fi % % \NeedsTeXFormat{LaTeX2e}[2021-06-01] % \RequirePackage{xparse, l3keys2e, xtemplate}[2021-06-01] % \ProvidesExplPackage % {erw-l3} % Package name % {2022-01-28} % Release date % {4.2} % Release version % {erw-l3 --- Utilities based on LaTeX3, such as 'merge sort' } % Description %<*driver> \documentclass%^^A[show-notes] % ^^A[draft] {l3doc} \EnableCrossrefs \CodelineIndex \RecordChanges % ^^A \listfiles \usepackage{amsmath, bookmark, enumitem, mathtools, microtype, tcolorbox, xparse} \usepackage[french, german, english]{babel} \usepackage[T1]{fontenc} \usepackage[bibencoding=auto, backend=biber, sorting=ynt]{biblatex} \begin{filecontents*}{\jobname.bib} @manual{interface3, title = {The \LaTeX3 interfaces}, author = {The \LaTeX3 Project Team}, year = {2019}, note = {\url{https://ctan.math.washington.edu/tex-archive/macros/latex/contrib/l3kernel/expl3.pdf}}, annote = {} } \end{filecontents*} \addbibresource{\jobname.bib} \ExplSyntaxOn % ^^A *** Sectioning \tl_gset:Nn \partname {Part}%^^A allows to test w/o babel % ^^A *** Msg \msg_new:nnn{__erw-l3_doc}{unknown}{~#1:#2~unknown} % ^^A *** Expressions \ProvideDocumentCommand{\docrule}{}{\texttt{$\rightarrow$}} \ProvideDocumentCommand{\docpipe}{}{\textbar} % ^^A *** L3 package \ProvideDocumentCommand{\docparam}{m}{\texttt{\#}\meta{#1}} % ^^A *** Lists \newlist{arab-inl}{enumerate*}{1} \setlist[arab-inl]{label=\arabic*)} \newlist{colon-inl}{itemize*}{1} \setlist[colon-inl] { %^^Abefore=\noindent, label={}, itemjoin={{; }}, after={{.}}} \newlist{descr}{description}{2} \setlist[descr]{nosep, align=right, itemindent=0pt, font=\sffamily\tiny} % ^^A Sort---> \ProvideDocumentCommand{\docdescrf}{m}{{\sffamily\bfseries\tiny{}#1}} \ProvideDocumentCommand{\docfillblank}{}{\begin{minipage}[t]{\linewidth}\end{minipage}} % ^^A Sort<--- \ExplSyntaxOff % ^^A *** listing \tcbuselibrary{listings, breakable} \newtcblisting[auto counter] {listing}[2][]{ noparskip, breakable, colback=white, colframe=black, opacitybacktitle=.8,% fonttitle=\bfseries, title={Listing~\thetcbcounter. #1}, arc=0pt, outer arc=0pt, boxrule=1pt, listing and text, #2} \usepackage{erw-l3} \usepackage{hyperref} %^^A comes last \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \GetFileInfo{\jobname.sty} % \title{The \pkg{erw-l3} package\thanks{^^A % This file describes version \fileversion, last revised \filedate.^^A % }^^A % } % \begin{documentation} % \maketitle % \begin{abstract} % Utilities based on \LaTeX3\cite{interface3}, such as \cs{erw_merge_sort:nNn}. % \end{abstract} % \tableofcontents % \part{Usage} % \section{\textsf{boilerplate}} % \begin{function}{\erw_keys_set:n,\erw_keys_set:nn} % \cs{erw_keys_set:n}\Arg{keyval list} % \end{function} % \begin{function}[EXP] % {\erw_identity:n, % \erw_int_incr:n, % \erw_swap:nn, % \erw_swap:ne, % \erw_name_signature_cs:N} % \end{function} % \section{\textsf{quark}} % \begin{function} % {\erw_all_q:w, % \erw_remove_first_q:w, % \erw_first_q:w, % \erw_remove_last_q:w, % \erw_last_q:w} % \begin{syntax} % \cs{erw_remove_last_q:w}\meta{tokenlist} \cs[no-index]{q_recursion_tail}\cs[no-index]{q_recursion_stop} % \end{syntax} % \end{function} % \section{\textsf{predicate}} % \begin{function}{new_compare_p} % \cs{erw_keys_set:n}|{ new_compare_p = |\Arg{name}\Arg{signature}\Arg{predicate}| }| % \begin{descr} % \item[Instance]\docfillblank % \begin{descr} % \item[erw_compare_p:nNnNn] % \item[erw_int_incr_p:nn] % \end{descr} % \end{descr} % \end{function} % \section{\textsf{op's on lists}} % \begin{function} % {\erw_remove_first:n, % \erw_remove_last:n, % \erw_first:n, % \erw_last:n, % \erw_adjacent_insert:nn, % \erw_adjacent_insert:en} % \end{function} % \section{\textsf{algo}} % \begin{function} % {\erw_split_even:n, % \erw_split_even:e, % \erw_merge_sort:nNn, % \thread_sort:nnNn, % \erw_filter_uniq:nn, % \erw_filter_uniq:n % } % \begin{syntax} % \cs{erw_thread_sort:nnNn}\Arg{first sorted list}\Arg{second sorted list}\Arg{compare predicate name}|<|\docpipe|>| % \cs{erw_merge_sort:nNn}\Arg{compare predicate name}|<|\docpipe|>|\Arg{unsorted list} % \cs{erw_filter_uniq:nn}\Arg{compare predicate}\Arg{tokenlist} % \cs{erw_filter_uniq:n}\Arg{ascending intergers} % \end{syntax} % \end{function} % \section{\textsf{code}} % \begin{function}{\erw_parameter:n, % \erw_parameter:nn,\argument:nn,} % \begin{syntax} % \cs{erw_parameter:n}\Arg{arity} % \cs{erw_parameter:nn}\Arg{start pos}\Arg{arity} % \cs{erw_argument:nn}\Arg{start pos}\Arg{signature} % \end{syntax} % \end{function} % % \part{Other} % \section{Bibliograhy} % \printbibliography[heading=none] % \section{Support}\label{other:support} % % This package is available from \url{https://github.com/rogard/erw-l3}. % \changes{v4.0}{2022/01/27} %{Replacing 3.2 altogether (not used by any packages but mine that have been updated accordingly} % \changes{v4.1}{2022/01/27} % {Removed commented portion labeled trash (thread), code_analyze, erw_compare_recurse_p:nnN[N], and keyval, as not used.} % \changes{v4.2}{2022/01.28} % {Removed \cs[no-index]{__erw_keyval_dispatch_build:nn}} % \StopEventually{ % \clearpage % \PrintChanges % \PrintIndex %^^A https://tex.stackexchange.com/q/610349/112708 % } %^^A% % \end{documentation} % \begin{implementation} % \part{Implementation}\label{part:impl} % \begin{macrocode} %<*package> %<@@=erw> % \ExplSyntaxOn % \end{macrocode} % \section{\textsf{kernel}} % \begin{macrocode} \cs_generate_variant:Nn\int_compare_p:nNn{eNe} \cs_generate_variant:Nn\int_eval:n{e} \cs_generate_variant:Nn\prg_new_conditional:Nnn{c} \cs_generate_variant:Nn\prg_replicate:nn{e} \cs_generate_variant:Nn\regex_gset:Nn{c} \cs_generate_variant:Nn\regex_log:N{c} \cs_generate_variant:Nn\regex_match:NnTF{c} \cs_generate_variant:Nn\tl_to_str:n{e} \cs_generate_variant:Nn\prop_put:Nnn{Nne} % \end{macrocode} % \section{\textsf{boilerplate}} % \begin{macrocode} \msg_new:nnnn{@@}{text}{text~is~not~loaded}{load~amsmath} \cs_new:Npn \@@_text:n #1 {\cs_if_exist:NTF\text{\text{#1}}{\msg_error:nn{@@}{text}}} \cs_new:Npn\@@_empty:w #1 \q_recursion_stop {\c_empty_tl} \cs_new_protected:Nn\erw_keys_set:n{ \keys_set:nn{@@}{#1} } \cs_new_protected:Nn\erw_keys_set:nn{ \keys_set:nn{@@ / #1}{#2} } \cs_generate_variant:Nn\erw_apply:Nw{c} \cs_new:Npn \erw_identity:n#1{#1} \cs_new:Npn \erw_int_incr:n#1{\int_eval:n{#1+1}} \cs_new:Npn \erw_swap:nn#1#2{#2#1} \cs_generate_variant:Nn \erw_swap:nn{e} \cs_new:Npn \erw_name_signature_cs:N #1 { \exp_last_unbraced:Ne \@@_name_signature_cs:nnn{\cs_split_function:N#1}} \cs_new:Nn \@@_name_signature_cs:nnn{{#1}{#2}} % \end{macrocode} % \section{\textsf{quark}} % \begin{macrocode} \msg_new:nnn{erw}{quark-only-tail} {requires~tail;~got~'#1';~\msg_line_context:} \cs_new:Npn \erw_all_q:w #1 \q_recursion_stop {% \erw_remove_last_q:w#1\q_recursion_stop \erw_last_q:w#1\q_recursion_stop } \cs_new:Npn \erw_remove_first_q:w #1 % \q_recursion_stop {\quark_if_recursion_tail_stop:n{#1} \@@_remove_first_q:nw#1\q_recursion_stop} \cs_new:Npn \@@_remove_first_q:nw #1 % #2 % \q_recursion_stop {\erw_remove_last_q:w#2\q_recursion_stop \erw_last_q:w#2\q_recursion_stop} \cs_new:Npn \erw_first_q:w #1 \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#1} \@@_first_q:enw{ \tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop } \cs_new:Npn \@@_first_q:nnw #1 % #2 % #3 % \q_recursion_stop {% \bool_if:nTF{#1}{{#2}}{#2} } \cs_generate_variant:Nn\@@_first_q:nnw{e} \cs_new:Npn \erw_remove_last_q:w #1 \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#1} \@@_remove_last_q:ew{\tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop } \cs_new:Npn \@@_remove_last_q:nw #1 % #2 % \q_recursion_stop { \@@_remove_last_q:nnw{#1}#2\q_recursion_stop } \cs_generate_variant:Nn\@@_remove_last_q:nw{e} \cs_new:Npn \@@_remove_last_q:nnw #1 % #2 % #3 % \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#3} \bool_if:nTF{#1}{{#2}}{#2} \@@_remove_last_q:ew {\tl_if_head_is_group_p:n{#3}} #3 \q_recursion_stop } \cs_generate_variant:Nn\@@_remove_last_q:nnw{e} \cs_new:Npn \erw_last_q:w #1 \q_recursion_stop {\quark_if_recursion_tail_stop:n{#1} \@@_last_q:ew{\tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop} \cs_new:Npn \@@_last_q:nw #1 % #2 % \q_recursion_stop { \@@_last_q:nnw{#1}#2\q_recursion_stop } \cs_generate_variant:Nn\@@_last_q:nw{e} \cs_new:Npn \@@_last_q:nnw #1 % #2 % #3 % \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#3}{ \bool_if:nTF{#1}{{#2}}{#2} } \@@_last_q:ew {\tl_if_head_is_group_p:n{#3}} #3 \q_recursion_stop } \cs_generate_variant:Nn\@@_last_q:nnw{e} % \end{macrocode} % \section{\textsf{predicate}} % \begin{macrocode} \msg_new:nnn{@@}{predicate-empty} {empty~expression~in~predicate} \prg_new_conditional:Npnn \erw_and_tl:nn #1 % #2 % {p} {%^^A \@@_and_tl:nw {#1}#2 \q_recursion_tail\q_recursion_stop } \cs_new:Npn \@@_and_tl:nw #1 % #2 % \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#2} { \prg_return_true: } \@@_and_tl:nnw {#1} % #2 % \q_recursion_stop } \cs_new:Npn \@@_and_tl:nnw #1 % #2 % #3 % \q_recursion_stop {% \bool_if:nTF {#1{#2}} {\@@_and_tl:nw{#1}#3\q_recursion_stop} { \prg_return_false: } } \cs_new:Npn \@@_new_compare_p:nnn #1 % #2 % #3 % {% \prg_new_conditional:cnn{#1:#2} {p} {% \bool_if:nTF {#3} {\prg_return_true:} {\prg_return_false:} } } \keys_define:nn{ @@ } { new_compare_p.code:n = {\@@_new_compare_p:nnn#1} } \erw_keys_set:n {% new_compare_p = {erw_compare} % {nNnNn} { \@@_compare:eecN{ #2{#3} }{ #2{#5} }{ #1:nNn }#4 } } \cs_new:Npn \@@_compare:nnNN #1 % #2 % #3 % #4 % { #3{ #1 }#4{ #2 } } \cs_generate_variant:Nn\@@_compare:nnNN{eec} \erw_keys_set:n {% new_compare_p = {erw_int_incr} {nn} {\exp_args:Ne \int_compare_p:nNn{ \int_eval:n{#1+1} } = {#2} } } % \end{macrocode} % \section{\textsf{keyval}} % \begin{macrocode} \cs_new:Npn\@@_keyval_key:w #1 = #2 \q_recursion_stop{#1} \cs_new:Npn\@@_keyval_value:w #1 = #2 \q_recursion_stop{#2} \cs_new:Npn \erw_keyval_key:n#1{\@@_keyval_key:w #1 \q_recursion_stop} \cs_new:Npn \erw_keyval_value:n#1{\@@_keyval_value:w #1 \q_recursion_stop} \cs_new:Npn \erw_keyval:nn#1#2{ #1 = #2 } \erw_keys_set:n { new_compare_p = {erw_key_compare} {nNn}{ \erw_compare_p:nNnNn {int_compare_p}\erw_keyval_key:n{#1}#2{#3} }, new_compare_p = {erw_key_compare} {n}{ \erw_compare_recurse_p:nnNN{#1} {int_compare_p}\erw_keyval_key:n< } } % \end{macrocode} % \section{\textsf{op's on list}} % \begin{macrocode} \cs_new:Npn \erw_remove_first:n #1 % {\erw_remove_first_q:w#1\q_recursion_tail\q_recursion_stop} \cs_generate_variant:Nn\erw_remove_first:n{e} \cs_new:Npn \erw_remove_last:n #1 % {\erw_remove_last_q:w#1\q_recursion_tail\q_recursion_stop} \cs_generate_variant:Nn\erw_remove_last:n{e} \cs_new:Npn \erw_first:n #1 {\erw_first_q:w#1\q_recursion_tail\q_recursion_stop} \cs_generate_variant:Nn\erw_first:n{e} \cs_new:Npn \erw_last:n #1 % {\erw_last_q:w#1\q_recursion_tail\q_recursion_stop} \cs_generate_variant:Nn\erw_last:n{e} \cs_new:Npn \erw_adjacent_insert:nn #1 % #2 % {% \erw_first:n{#1} \erw_swap:en { \erw_remove_first:n{#1} } {% \@@_adjacent_insert:nw {#2} % } \q_recursion_tail \q_recursion_stop } \cs_generate_variant:Nn\erw_adjacent_insert:nn{e} \cs_new:Npn \@@_adjacent_insert:nw #1 % #2 % \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#2} \@@_adjacent_insert:new {#1}{\tl_if_head_is_group_p:n{#2}}#2 \q_recursion_stop } \cs_new:Npn \@@_adjacent_insert:nnw #1 % #2 % #3 % #4 % \q_recursion_stop {% #1\bool_if:nTF{#2}{{#3}}{#3} \@@_adjacent_insert:nw{#1}#4\q_recursion_stop } \cs_generate_variant:Nn\@@_adjacent_insert:nnw{ne} % \end{macrocode} % \begin{macrocode} \cs_new:Npn \erw_clist_tl:nn #1 % #2 % { \erw_clist_tl:nnw {#1} #2 \q_recursion_tail\q_recursion_stop } \cs_new:Npn \erw_clist_tl:nnw #1 #2\q_recursion_stop {\quark_if_recursion_tail_stop:n{#2} \erw_clist_tl:nenw {#1} {\tl_if_head_is_group_p:n{#2}} #2 \q_recursion_stop} \cs_generate_variant:Nn\erw_clist_tl:nnw{ne} \cs_new:Npn \erw_clist_tl:nnnw #1 % #2 % #3 % #4 % \q_recursion_stop { \quark_if_recursion_tail_stop_do:nn{#4} {% \bool_if:nTF {\bool_lazy_and_p:nn{#1}{#2}} {{#3}}{#3} } \bool_if:nTF{\bool_lazy_and_p:nn{#1}{#2}} {{#3}}{#3}, \erw_clist_tl:nnw {#1} #4 \q_recursion_stop } \cs_generate_variant:Nn\erw_clist_tl:nnnw{ne} \prg_new_conditional:Npnn \erw_if_in_clist:nn #1 % #2 % {p} { \@@_clist_if_in:nw {#1} #2, \q_recursion_tail \q_recursion_stop } \cs_new:Npn \@@_clist_if_in:nw #1 #2 \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#2} \@@_clist_if_in:nnw {#1} #2 \q_recursion_stop } \cs_new:Nn \@@_clist_if_in:nn {\@@_clist_if_in:nw{#1} #2 \q_recursion_stop} \cs_new:Npn \@@_clist_if_in:nnw #1 #2, #3 \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#3} {% \str_if_eq:nnTF{#1}{#2} {\prg_return_true:}{\prg_return_false:} } \str_if_eq:nnTF{#1}{#2} {\prg_return_true:} {\@@_clist_if_in:nw {#1} #3 \q_recursion_stop} \@@_empty:w\q_recursion_stop } % \end{macrocode} % \section{\textsf{algo}} % \subsection{\textsf{split}} % \begin{macrocode} \cs_new:Npn \erw_split_even:n #1 % {% \tl_if_empty:nF{#1} {% \exp_last_unbraced:Ne \@@_split_even:nnnw {% {\@@_split_even_threshold:n{#1}} % {\tl_if_head_is_group_p:n{#1}} % } #1 % \q_recursion_tail \q_recursion_stop } } \cs_generate_variant:Nn\erw_split_even:n{e} \cs_new:Npn \@@_split_even_threshold:n #1 % {\exp_args:Ne \int_div_round:nn{\tl_count:n{#1}}{2}} \cs_new:Npn \@@_split_even:nnnw #1 % #2 % #3 % #4 % \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#4} { { \bool_if:nTF{#2}{{#3}}{#3} }{} } \exp_last_unbraced:Ne \@@_split_even:nnnnw {% {1} % { \tl_if_head_is_group_p:n{#4} } {#1} % { \bool_if:nTF{#2}{{#3}}{#3} } % } #4 % \q_recursion_stop } \cs_new:Npn \@@_split_even:nnnnw #1 % #2 % #3 % #4 % #5 % #6 % \q_recursion_stop {% \bool_if:nTF { \int_compare_p:nNn {#1}<{#3} } {% \exp_last_unbraced:Ne \@@_split_even:nnnnw { { \int_eval:n{#1+1} } % { \tl_if_head_is_group_p:n{#6} } % {#3} % {#4\bool_if:nTF{#2}{{#5}}{#5}} % } #6 \q_recursion_stop } {% {#4} {% \bool_if:nTF{#2}{{#5}}{#5} \erw_remove_last_q:w#6\q_recursion_stop\erw_last_q:w#6\q_recursion_stop} } } % \end{macrocode} % \subsection{\textsf{thread sort}} % \begin{macrocode} \cs_new:Npn \erw_thread_sort:nnNn #1 % #2 % #3 % #4 % {% \@@_thread_sort:nNnnn {#3} % #4 % {\c_empty_tl} % {#1} {#2} } \cs_generate_variant:Nn\erw_thread_sort:nnNn{ee} \cs_new:Npn \@@_thread_sort:nNnnn #1 % #2 % #3 % #4 % #5 % {% \@@_thread_sort:nNnww {#1} % {#2} % {#3} % #4 \q_recursion_tail% \q_stop #5 \q_recursion_tail% \q_recursion_stop } \cs_generate_variant:Nn\@@_thread_sort:nNnnn{nNeee} \cs_new:Npn \@@_thread_sort:nNnww #1 % #2 % #3 % #4 % \q_stop #5 % \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#4} { #3 \erw_all_q:w #5 \q_recursion_stop } \quark_if_recursion_tail_stop_do:nn{#5} { #3 \erw_all_q:w #4 \q_recursion_stop } \@@_thread_sort:nNneeww {#1}#2{#3} { \tl_if_head_is_group_p:n{#4} } { \tl_if_head_is_group_p:n{#5} } #4\q_stop #5\q_recursion_stop } \cs_new:Npn \@@_thread_sort:nNnnnww #1 % #2 % #3 % #4 % #5 % #6 % #7 % \q_stop #8 % #9 % \q_recursion_stop {% \bool_if:nTF { \use:c{#1:nNn}{#6}#2{#8} } {% \@@_thread_sort:nNeee {#1} #2 {#3\bool_if:nTF{#4}{{#6}}{#6}} {\erw_all_q:w#7\q_recursion_stop} {\bool_if:nTF{#5}{{#8}}{#8}\erw_all_q:w#9\q_recursion_stop} } {% \@@_thread_sort:nNeee {#1} #2 {#3\bool_if:nTF{#5}{{#8}}{#8}} {\bool_if:nTF{#4}{{#6}}{#6}\erw_all_q:w#7\q_recursion_stop} {\erw_all_q:w#9\q_recursion_stop} } } \cs_generate_variant:Nn\@@_thread_sort:nNnnnww{nNnee} % \end{macrocode} % \subsection{\textsf{merge sort}} % \begin{macrocode} \cs_new:Npn \erw_merge_sort:nNn #1 % #2 % #3 % {% \tl_if_empty:nF{#3} {% \@@_sort_merge:enNw {\tl_if_head_is_group_p:n{#3}} % {#1} % #2 % #3 % \q_recursion_tail \q_recursion_stop } } \cs_generate_variant:Nn\erw_merge_sort:nNn{nNe} \cs_new:Npn \@@_sort_merge:nnNw #1 % #2 % #3 % #4 % #5 % \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#5} { \bool_if:nTF{#1}{{#4}}{#4} } \exp_last_unbraced:Ne \@@_sort_merge:nnnN {% \erw_split_even:e {% \bool_if:nTF{#1}{{#4}}{#4} \erw_all_q:w#5\q_recursion_stop } } % {}{} {#2} % #3 % \@@_empty:w \q_recursion_stop } \cs_generate_variant:Nn\@@_sort_merge:nnNw{e} \cs_new:Npn \@@_sort_merge:nnnN #1 % #2 % #3 % #4 % {% \erw_thread_sort:eeNn {% \@@_sort_merge:enNw {\tl_if_head_is_group_p:n{#1}} {#3} % #4 % #1 % \q_recursion_tail \q_recursion_stop } % {% \@@_sort_merge:enNw {\tl_if_head_is_group_p:n{#2}} {#3} % #4 % #2 % \q_recursion_tail \q_recursion_stop } % {#3} % #4 % } % \end{macrocode} % \subsection{\textsf{filter}} % \begin{macrocode} \msg_new:nnn{@@}{tokenlist-incr} {expecting~an~ascending~tokenlist~got~#1~followed~by~#2} \cs_new:Npn \@@_filter_uniq:nnw #1 % #2 % #3 % \q_recursion_stop { % \quark_if_recursion_tail_stop:n{#3} \@@_filter_uniq_aux:nnw{#1}{#2}#3\q_recursion_stop} \cs_new:Npn \@@_filter_uniq_aux:nw #1 % #2 % #3 % \q_recursion_stop {% {#2} \@@_filter_uniq:nnw {#1} % {#2} #3 % \q_recursion_stop } \cs_new:Npn \@@_filter_uniq_aux:nnw #1 % #2 % #3 % #4 % \q_recursion_stop { % \bool_if:nTF{\use:c{#1:nNn}{#3}<{#2}} {\msg_error:nnnn{@@}{tokenlist-incr}{#2}{#3}} {% \bool_if:nF {\use:c{#1:nNn}{#3}={#2}} % ^^A {{#3}} {\tl_if_single_token:nTF{#3}{#3}{{#3}}} } \quark_if_recursion_tail_stop:n{#4} % ^^A \@@_filter_uniq:nnw{#1}{#3}#4\q_recursion_stop } \@@_filter_uniq:nnw{#1}{#3}#4\q_recursion_stop } \cs_new:Npn \@@_filter_uniq:nw #1 % #2 % {% \quark_if_recursion_tail_stop_do:nn{#2}{\c_empty_tl} \@@_filter_uniq_aux:nw {#1}#2 \q_recursion_stop} \cs_new:Npn \erw_filter_uniq:nn #1 % #2 % {% \@@_filter_uniq_aux:nw {#1} % #2 \q_recursion_tail % \q_recursion_stop} \cs_new:Npn \erw_filter_uniq:n #1 % { \erw_filter_uniq:nn{int_compare_p}{#1} } \cs_generate_variant:Nn\erw_filter_uniq:nn{ne} % \end{macrocode} % \section{\textsf{code}} % \begin{macrocode} \keys_define:nn{@@} { clist_map_inline.code:n = \@@_map_inline_clist:nnn#1 } \cs_new_protected:Npn \@@_map_inline_clist:nnn #1 % #2 % #3 % { \cs_new_protected:cn {@@_do:#2}{#3} \clist_map_inline:nn {#1} {\use:c{@@_do:#2}##1} } \cs_new:Npn \erw_parameter:n #1 %^^A {## #1} \cs_new:Npn \@@_parameter_aux:nn #1 % #2 % { \int_step_function:nnN {#2}{#1}\erw_parameter:n} \cs_new:Npn \erw_parameter:nn #1 % #2 % {% \exp_args:Ne \@@_parameter_aux:nn {\int_eval:n{#1+#2-1}}{#1}} \cs_new:Npn \erw_argument:nn #1 % #2 % {\@@_argument:nw{#1}#2\q_recursion_tail\q_recursion_stop} \cs_new:Npn \@@_argument_unit:nn #1 % #2 % {\use:c{@@_argument_#2:w} #1 \q_recursion_stop} \cs_new:Npn\@@_argument_n:w #1 \q_recursion_stop{{## #1}} \cs_new:Npn\@@_argument_N:w #1 \q_recursion_stop{## #1} \cs_new:Npn \@@_argument:nw #1 % #2 % \q_recursion_stop { \quark_if_recursion_tail_stop:n{#2} \@@_argument:nnw{#1}#2\q_recursion_stop } \cs_new:Npn \@@_argument:nnw #1 % #2 % #3 % \q_recursion_stop {% \@@_argument_unit:nn{#1}{#2} \exp_args:Ne \@@_argument:nw {\erw_int_incr:n{#1}}#3\q_recursion_stop } % \end{macrocode} % ^^A --- % \begin{macrocode} \ProcessKeysOptions{@@} \ExplSyntaxOff % % \end{macrocode} % \end{implementation} % \Finale \endinput