% \iffalse %% File: l3candidates.dtx Copyright (C) 2005-2010 LaTeX3 project %% %% It 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 file is part of the ``expl3 bundle'' (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- % %<*driver|package> \RequirePackage{expl3} % %\fi \errorcontextlines=999 \GetIdInfo$Id: l3candidates.dtx 2063 2010-10-03 08:26:49Z mittelba $ {L3 Experimental 'extras' module} %\iffalse %<*driver> %\fi \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse \documentclass[full]{l3doc} \begin{document} \DocInput{l3candidates.dtx} \end{document} % % \fi % % % \title{The \textsf{l3candidates} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{\Team} % \date{\filedate} % \maketitle % % \begin{documentation} % % \section{Intro} % % This \emph{experimental} package contains additions to the \pkg{expl3} % programming language before they're added to the `official' packages. % The functions defined within will fall into three categories: % \begin{itemize} % \item Will be added directly to a corresponding \pkg{expl3} module at some stage. % \item Will be re-worked and added to a module with slightly different name or behaviour. % \item Will eventually vanish. % \end{itemize} % Beware, then, that loading this package and using its contents may cause your % code to break down the track. % % \section{Functions for characters} % % % \begin{function}{\char_active_set:Npn|\char_active_gset:Npn} % \begin{syntax} % |\char_active_set:Npn|~~~ % \end{syntax} % Makes active and gives it the definition specified as if it were % a function. % \end{function} % % \begin{function}{\char_active_set_eq:NN|\char_active_gset_eq:NN} % \begin{syntax} % |\char_active_set:Npn|~~ % \end{syntax} % Makes active and makes it equal to . % (Or another active char, etc.) % \end{function} % % % % \section{Functions for token lists} % % \begin{function}{\tl_trim_spaces:n|\tl_trim_spaces:N} % \begin{syntax} % |\tl_trim_spaces:n|~|{||}| % |\tl_trim_spaces:n|~|{|\verb*| |\verb*| ||}| % |\tl_trim_spaces:N| % \end{syntax} % After a full expansion, |\tl_trim_space:n| returns stripped % of any preceeding and trailing spaces. % For example, to set a token list variable to a trim-spaced argument, % use something like this: % \begin{verbatim} % \tl_set:Nx \l_tmpa_tl { \tl_trim_spaces:n {#1} } % \end{verbatim} % |\tl_trim_spaces:N| removes preceeding and trailing spaces from the % contents of its token list variable argument. % \end{function} % % % \begin{function}{\tl_transform:nn|\char_transform:NN} % \begin{syntax} % |\tl_transform:nn| \Arg{tranformation rules} \Arg{token list} % "\char_transform:NN" % \end{syntax} % Tokenises and evaluates according to the transformation rules % given in the first argument. % These transformation rules may be function/variable % redefinitions, catcode changes (see "\char_make_other:N" and so on), or % token transformations given by "\char_transform:NN". % % "\char_transform:NN" declares that within the argument, % any occurences of are interpreted as if they were albeit % with the same catcode as . % % Note 1: Everything evaluated by this function occurs within a group; % global definitions will be necessary to make changes outside of it. % % Note 2: Because this function must be invoked before its arguments are % tokenised, it cannot be evaluated within another macro (unless clever use % of "\tl_rescan:nn" is employed). % \begin{texnote} % This is a wrapper around \TeX's "\lowercase" primitive and only the ASCII % uppercase letters are protected from being transformed themselves. % If you are using Xe\TeX\ or Lua\TeX, be careful of unicode letters that will % be affected by this process. % \end{texnote} % \end{function} % % \section{Functions for sequences} % % % \begin{function}{\seq_mapthread_function:NNN} % \begin{syntax} % "\seq_mapthread_function:NNN" % \end{syntax} % Applies to as arguments each pair of % corresponding elements within and (which must have the same % number of elements). % % For example, if "\l_mya_seq" contains "a", "b", "c" and % "\l_myb_seq" contains "x", "y", "z", then % \begin{verbatim} % \seq_mapthread_function:NNN \l_mya_seq \l_myb_seq \my_func:nn % \end{verbatim} % is the same as executing % \begin{verbatim} % \my_func:nn {a} {x} % \my_func:nn {b} {y} % \my_func:nn {c} {z} % \end{verbatim} % \end{function} % % % \begin{function}{\seq_get_length:NN} % \begin{syntax} % |\seq_get_length:NN| % \end{syntax} % Sets to the number of elements in . % \end{function} % % % \begin{function}{\seq_set_from_clist:NN|\seq_set_from_clist:Nn| % \seq_gset_from_clist:NN|\seq_gset_from_clist:Nn} % \begin{syntax} % "\seq_set_from_clist:Nn" \Arg{clist} % "\seq_set_from_clist:NN" % \end{syntax} % Transforms comma-list into sequence . % \end{function} % % % \section{Functions for comma-lists} % % \begin{function}{\clist_set_from_seq:NN|\clist_gset_from_seq:NN} % \begin{syntax} % "\clist_set_from_seq:NN" % \end{syntax} % Transforms sequence into comma-list variable . % \end{function} % % % \begin{function}{\clist_if_in_numrange:nn / (TF)} % \begin{syntax} % "\clist_if_in_numrange:nnTF" \Arg{intexpr} \Arg{numrange} % \Arg{true} \Arg{false} % \end{syntax} % When parsing user input to specify whether numerical elements % should be displayed/operated upon, it is common to use input such as % `|-4,7-11,17-|' to indicate ranged but sometimes discontiguous sets. % (In this particular example, we'd be specifying % $x\le4 \wedge 7\le x\le 11 \wedge x\ge 17$.) % This function can be used to test whether the input number % (actually ) exists within the specified . % % need not be sorted and may contain overlapping ranges. % Numbers inside ranges may consist of integer expressions or anything % considered by \TeX\ to be a number % (such as `|`\A|', which is decimal number 65). % % This function could probably be made expandable with sufficient effort. % \end{function} % % % % \end{documentation} % % \begin{implementation} % % \section{Implementation} % % % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} \package_check_loaded_expl: % %<*initex|package> % \end{macrocode} % % % \begin{macro}{\char_active_set:Npn,\char_active_set:Npx,\char_active_gset:Npn,\char_active_gset:Npx} % \begin{macro}{\char_active_set_eq:NN,\char_active_gset_eq:NN} % \begin{macrocode} \group_begin: \char_make_active:N \^^@ \cs_set:Npn \char_tmp:NN { \cs_gnew:Npn #1 ##1 { \char_make_active:n {`##1} \group_begin: \tex_lccode:D `\^^@ `##1 \tex_lowercase:D{\group_end: #2 ^^@} } } \char_tmp:NN \char_active_set:Npn \cs_set:Npn \char_tmp:NN \char_active_set:Npx \cs_set:Npx \char_tmp:NN \char_active_gset:Npn \cs_gset:Npn \char_tmp:NN \char_active_gset:Npx \cs_gset:Npx \char_tmp:NN \char_active_set_eq:NN \cs_set_eq:NN \char_tmp:NN \char_active_gset_eq:NN \cs_gset_eq:NN \group_end: % \end{macrocode} % \end{macro} % \end{macro} % % % % \begin{macro}{\tl_trim_spaces:n,\tl_trim_spaces:N} % \begin{macrocode} \cs_new:Npn \tl_trim_spaces:n #1 { \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \tl_trim_spaces_exp:n {#1} } } \cs_new:Npn \tl_trim_spaces:N #1 { \tl_set:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } } % \end{macrocode} % % \begin{macrocode} \char_make_math_shift:N \Q \cs_new:Npn \tl_trim_spaces_exp:n #1 { \tex_romannumeral:D -`\q \tl_trim_spaces_aux_i:w \exp_not:N #1 Q~Q } \cs_new:Npn \tl_trim_spaces_aux_i:w #1~Q { \tl_trim_spaces_aux_ii:w #1 Q } \cs_new:Npn \tl_trim_spaces_aux_ii:w #1 Q #2 {#1} \char_make_letter:N \Q % \end{macrocode} % \end{macro} % % % % \begin{macro}{\tl_transform:nn,\char_transform:NN} % \begin{macrocode} \cs_new:Npn \tl_transform:nn #1 { \group_begin: \tl_map_function:nN { \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 } \char_protect_uppercase:N \cs_set_eq:NN \char_transform:NN \char_transform_hidden:NN #1 \tl_transform_aux:n } % \end{macrocode} % Allow for catcode changes: % \begin{macrocode} \cs_new:Npn \tl_transform_aux:n #1 { \tl_to_lowercase:n { \group_end: #1 } } \cs_set:Npn \char_protect_uppercase:N #1 { \char_set_lccode:nn {`#1} {`#1} } % \end{macrocode} % % \begin{macrocode} \cs_new:Npn \char_transform_hidden:NN #1#2 { \char_set_lccode:nn {`#1} {`#2} } \cs_new:Npn \char_transform:NN { \msg_error:nn {l3prg} {naked-char-transform} } \msg_new:nnn {l3prg} {naked-char-transform} { This command can only appear within the first\\ argument of \string\tl_transform:nn. } % \end{macrocode} % \end{macro} % % % \begin{macro}{\seq_mapthread_function:NNN} % \begin{macrocode} \seq_new:N \l_tmpb_seq % \end{macrocode} % % % \begin{macro}{\seq_get_length:NN} % \begin{macrocode} \cs_new:Nn \seq_get_length:NN { \int_zero:N #1 \seq_map_inline:Nn #2 { \int_incr:N #1} } % \end{macrocode} % \end{macro} % % \begin{macrocode} \cs_new:Nn \seq_mapthread_function:NNN { \seq_get_length:NN \l_tmpa_int #1 \seq_get_length:NN \l_tmpb_int #2 \int_compare:nTF { \l_tmpa_int == \l_tmpb_int }{ \seq_set_eq:NN \l_tmpa_seq #1 \seq_set_eq:NN \l_tmpb_seq #2 \prg_stepwise_inline:nnnn{1}{1}{\l_tmpa_int}{ \seq_pop:NN \l_tmpa_seq \l_kernel_tmpa_tl \seq_pop:NN \l_tmpb_seq \l_kernel_tmpb_tl \exp_args:NVV #3 \l_kernel_tmpa_tl \l_kernel_tmpb_tl } }{\ERROR} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\seq_set_from_clist:Nn,\seq_set_from_clist:NN} % \begin{macro}{\seq_gset_from_clist:Nn,\seq_gset_from_clist:NN} % \begin{macrocode} \cs_set:Npn \seq_set_from_clist:Nn #1#2 { \seq_clear:N #1 \clist_map_inline:nn {#2} { \seq_put_right:Nn #1 {##1} } } \cs_set:Npn \seq_set_from_clist:NN #1#2 { \seq_clear:N #1 \clist_map_inline:Nn #2 { \seq_put_right:Nn #1 {##1} } } \cs_set:Npn \seq_gset_from_clist:Nn #1#2 { \seq_gclear:N #1 \clist_map_inline:nn {#2} { \seq_gput_right:Nn #1 {##1} } } \cs_set:Npn \seq_gset_from_clist:NN #1#2 { \seq_gclear:N #1 \clist_map_inline:Nn #2 { \seq_gput_right:Nn #1 {##1} } } % \end{macrocode} % \end{macro} % \end{macro} % % % % \begin{macro}{\clist_set_from_seq:NN,\clist_gset_from_seq:NN} % I assume this technique is more efficient than looping through each element % and using "\clist_put_right:Nn" (Will). % \begin{macrocode} \cs_new:Npn \clist_set_from_seq_aux:NNN #1#2#3 { \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: ##2 { \exp_not:n {##1} \quark_if_nil:NF ##2 { , ##2 } } #1 #2 { #3 \q_nil } } \cs_new:Npn \clist_set_from_seq:NN { \clist_set_from_seq_aux:NNN \tl_set:Nx } \cs_new:Npn \clist_gset_from_seq:NN { \clist_set_from_seq_aux:NNN \tl_gset:Nx } % \end{macrocode} % \end{macro} % % % % \begin{macro}[TF]{\clist_if_in_numrange:nn} % A `numrange' is like |-2,5-8,17-| (can be unsorted). % \begin{macrocode} \prg_new_conditional:Nnn \clist_if_in_numrange:nn {TF,T,F} { \bool_set_false:N \l_clist_numrange_bool \clist_map_inline:nn {#2} { \_clist_numrange_parse:nw {#1} ##1 - \q_nil - \q_stop } \bool_if:NTF \l_clist_numrange_bool \prg_return_true: \prg_return_false: } \cs_set:Npn \_clist_numrange_success: { \bool_set_true:N \l_clist_numrange_bool \clist_map_break: } \cs_set:Npn \_clist_numrange_parse:nw #1 #2 - #3 - #4 \q_stop { \tl_if_empty:nTF {#4}{ \int_compare:nT {#1=#2} {\_clist_numrange_success:} }{ \tl_if_empty:nTF {#3}{ \int_compare:nT {#1>=#2} {\_clist_numrange_success:} }{ \tl_if_empty:nTF {#2}{ \int_compare:nT {#1<=#3} {\_clist_numrange_success:} }{ \int_compare:nT {#1>=#2} { \int_compare:nT {#1<=#3} {\_clist_numrange_success:} } } } } } \bool_new:N \l_clist_numrange_bool % \end{macrocode} % \end{macro} % % % \begin{macrocode} % % \end{macrocode} % % \begin{macrocode} %<*showmemory> \showMemUsage % % \end{macrocode} % % \end{implementation} % % \PrintIndex % % \endinput