diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3str/l3str-expl.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3experimental/l3str/l3str-expl.dtx | 984 |
1 files changed, 0 insertions, 984 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-expl.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-expl.dtx deleted file mode 100644 index 95ef2a826ed..00000000000 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-expl.dtx +++ /dev/null @@ -1,984 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3str.dtx Copyright (C) 2011-2015 The 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 "l3experimental 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 LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- -% -%<*driver|package> -% The version of expl3 required is tested as early as possible, as -% some really old versions do not define \ProvidesExplPackage. -\RequirePackage{expl3}[2015/09/11] -%<package>\@ifpackagelater{expl3}{2015/09/11} -%<package> {} -%<package> {% -%<package> \PackageError{l3str}{Support package l3kernel too old} -%<package> {% -%<package> Please install an up to date version of l3kernel\MessageBreak -%<package> using your TeX package manager or from CTAN.\MessageBreak -%<package> \MessageBreak -%<package> Loading l3str will abort!% -%<package> }% -%<package> \endinput -%<package> } -\GetIdInfo$Id: l3str-expl.dtx 6001 2015-09-11 21:50:23Z joseph $ - {L3 Experimental strings} -\def\ExplFileName{l3str} -%</driver|package> -%<*driver> -\documentclass[full]{l3doc} -\usepackage{amsmath} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% -% \title{^^A -% The \textsf{l3str} package: manipulating strings of characters^^A -% \thanks{This file describes v\ExplFileVersion, -% last revised \ExplFileDate.}^^A -% } -% -% \author{^^A -% The \LaTeX3 Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released \ExplFileDate} -% -% \maketitle -% -% \tableofcontents -% -% \begin{documentation} -% -% \LaTeX3 provides a set of functions to manipulate token lists -% as strings of characters, ignoring the category codes of those -% characters. -% -% String variables are simply specialised token lists, but by convention -% should be named with the suffix \texttt{\ldots{}str}. Such variables -% should contain characters with category code $12$ (other), except -% spaces, which have category code $10$ (blank space). All the -% functions in this module which accept a token list argument first -% convert it to a string using \cs{tl_to_str:n} for internal processing, -% and will not treat a token list or the corresponding string -% representation differently. -% -% Most expandable functions in this module come in three flavours: -% \begin{itemize} -% \item \cs{str_...:N}, which expect a token list or string -% variable as their argument; -% \item \cs{str_...:n}, taking any token list (or string) as an -% argument; -% \item \cs{str_..._ignore_spaces:n}, which ignores any space -% encountered during the operation: these functions are typically -% faster than those which take care of escaping spaces -% appropriately. -% \end{itemize} -% -% \section{Building strings} -% -% \begin{variable} -% { -% \c_backslash_str, -% \c_left_brace_str, -% \c_right_brace_str, -% \c_hash_str, -% \c_tilde_str, -% \c_percent_str -% } -% Constant strings, containing a single character token, with category -% code $12$. Any character can be accessed as \cs{iow_char:N} -% |\|\meta{character}. -% \end{variable} -% -% \begin{function}{\str_new:N, \str_new:c} -% \begin{syntax} -% \cs{str_new:N} \meta{str~var} -% \end{syntax} -% Creates a new \meta{str~var} or raises an error if the name is -% already taken. The declaration is global. The \meta{str~var} will -% initially be empty. -% \end{function} -% -% \begin{function}{\str_const:Nn, \str_const:Nx, \str_const:cn, \str_const:cx} -% \begin{syntax} -% \cs{str_const:Nn} \meta{str~var} \Arg{token list} -% \end{syntax} -% Creates a new constant \meta{str~var} or raises an error if the name -% is already taken. The value of the \meta{str~var} will be set -% globally to the \meta{token list}, converted to a string. -% \end{function} -% -% \begin{function} -% { -% \str_set:Nn, \str_set:Nx, \str_set:cn, \str_set:cx, -% \str_gset:Nn, \str_gset:Nx, \str_gset:cn, \str_gset:cx -% } -% \begin{syntax} -% \cs{str_set:Nn} \meta{str var} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, and stores the -% result in \meta{str var}. -% \end{function} -% -% \begin{function} -% { -% \str_put_left:Nn, \str_put_left:Nx, -% \str_put_left:cn, \str_put_left:cx, -% \str_gput_left:Nn, \str_gput_left:Nx, -% \str_gput_left:cn, \str_gput_left:cx -% } -% \begin{syntax} -% \cs{str_put_left:Nn} \meta{str var} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, and prepends the -% result to \meta{str var}. The current contents of the \meta{str -% var} are not automatically converted to a string. -% \end{function} -% -% \begin{function} -% { -% \str_put_right:Nn, \str_put_right:Nx, -% \str_put_right:cn, \str_put_right:cx, -% \str_gput_right:Nn, \str_gput_right:Nx, -% \str_gput_right:cn, \str_gput_right:cx -% } -% \begin{syntax} -% \cs{str_put_right:Nn} \meta{str var} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, and appends the -% result to \meta{str var}. The current contents of the \meta{str -% var} are not automatically converted to a string. -% \end{function} -% -% \section{Accessing the contents of a string} -% -% \begin{function}[EXP] -% {\str_count:N, \str_count:n, \str_count_ignore_spaces:n} -% \begin{syntax} -% \cs{str_count:n} \Arg{token list} -% \end{syntax} -% Leaves in the input stream the number of characters in the string -% representation of \meta{token list}, as an integer denotation. The -% functions differ in their treatment of spaces. In the case of -% \cs{str_count:N} and \cs{str_count:n}, all characters including -% spaces are counted. The \cs{str_count_ignore_spaces:n} function -% leaves the number of non-space characters in the input stream. -% \end{function} -% -% \begin{function}[EXP]{\str_count_spaces:N, \str_count_spaces:n} -% \begin{syntax} -% \cs{str_count_spaces:n} \Arg{token list} -% \end{syntax} -% Leaves in the input stream the number of space characters in the -% string representation of \meta{token list}, as an integer -% denotation. Of course, this function has no \texttt{_ignore_spaces} -% variant. -% \end{function} -% -% \begin{function}[EXP]{\str_head:N, \str_head:n, \str_head_ignore_spaces:n} -% \begin{syntax} -% \cs{str_head:n} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} into a \meta{string}. The first -% character in the \meta{string} is then left in the input stream, -% with category code \enquote{other}. The functions differ if the -% first character is a space: \cs{str_head:N} and \cs{str_head:n} -% return a space token with category code~$10$ (blank space), while -% the \cs{str_head_ignore_spaces:n} function ignores this space -% character and leaves the first non-space character in the input -% stream. If the \meta{string} is empty (or only contains spaces in -% the case of the \texttt{_ignore_spaces} function), then nothing is -% left on the input stream. -% \end{function} -% -% \begin{function}[EXP]{\str_tail:N, \str_tail:n, \str_tail_ignore_spaces:n} -% \begin{syntax} -% \cs{str_tail:n} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, removes the first -% character, and leaves the remaining characters (if any) in the input -% stream, with category codes $12$ and $10$ (for spaces). The -% functions differ in the case where the first character is a space: -% \cs{str_tail:N} and \cs{str_tail:n} will trim only that space, while -% \cs{str_tail_ignore_spaces:n} removes the first non-space character -% and any space before it. If the \meta{token list} is empty (or -% blank in the case of the \texttt{_ignore_spaces} variant), then -% nothing is left on the input stream. -% \end{function} -% -% \begin{function}[EXP]{\str_item:Nn, \str_item:nn, \str_item_ignore_spaces:nn} -% \begin{syntax} -% \cs{str_item:nn} \Arg{token list} \Arg{integer expression} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, and leaves in the -% input stream the character in position \meta{integer expression} of -% the \meta{string}, starting at $1$ for the first (left-most) -% character. In the case of \cs{str_item:Nn} and \cs{str_item:nn}, -% all characters including spaces are taken into account. The -% \cs{str_item_ignore_spaces:nn} function skips spaces when counting -% characters. If the \meta{integer expression} is negative, -% characters are counted from the end of the \meta{string}. Hence, -% $-1$ is the right-most character, \emph{etc.} -% \end{function} -% -% \begin{function}[EXP] -% {\str_range:Nnn, \str_range:nnn, \str_range_ignore_spaces:nnn} -% \begin{syntax} -% \cs{str_range:nnn} \Arg{token list} \Arg{start index} \Arg{end index} -% \end{syntax} -% Converts the \meta{token list} to a \meta{string}, and leaves in the -% input stream the characters from the \meta{start index} to the -% \meta{end index} inclusive. Positive \meta{indices} are counted -% from the start of the string, $1$~being the first character, and -% negative \meta{indices} are counted from the end of the string, -% $-1$~being the last character. If either of \meta{start index} or -% \meta{end index} is~$0$, the result is empty. For instance, -% \begin{verbatim} -% \iow_term:x { \str_range:nnn { abcdef } { 2 } { 5 } } -% \iow_term:x { \str_range:nnn { abcdef } { -4 } { -1 } } -% \iow_term:x { \str_range:nnn { abcdef } { -2 } { -1 } } -% \iow_term:x { \str_range:nnn { abcdef } { 0 } { -1 } } -% \end{verbatim} -% will print \texttt{bcd}, \texttt{cdef}, \texttt{ef}, and an empty -% line to the terminal. -% \end{function} -% -% \section{Viewing strings} -% -% \begin{function}{\str_show:N, \str_show:c, \str_show:n} -% \begin{syntax} -% \cs{str_show:N} \meta{tl~var} -% \end{syntax} -% Displays the content of the \meta{str~var} on the terminal. -% \end{function} -% -% \section{Scratch strings} -% -% \begin{variable}{\l_tmpa_str, \l_tmpb_str} -% Scratch strings for local assignment. These are never used by -% the kernel code, and so are safe for use with any \LaTeX3-defined -% function. However, they may be overwritten by other non-kernel -% code and so should only be used for short-term storage. -% \end{variable} -% -% \begin{variable}{\g_tmpa_str, \g_tmpb_str} -% Scratch strings for global assignment. These are never used by -% the kernel code, and so are safe for use with any \LaTeX3-defined -% function. However, they may be overwritten by other non-kernel -% code and so should only be used for short-term storage. -% \end{variable} -% -% \section{Internal \pkg{l3str} functions} -% -% \begin{function}[EXP]{\__str_to_other:n} -% \begin{syntax} -% \cs{__str_to_other:n} \Arg{token list} -% \end{syntax} -% Converts the \meta{token list} to a \meta{other string}, where -% spaces have category code \enquote{other}. This function can be -% \texttt{f}-expanded without fear of losing a leading space, since -% spaces do not have category code $10$ in its result. It takes a -% time quadratic in the character count of the string, but there exist -% non-expandable ways to reach linear time. -% \end{function} -% -% \begin{function}[EXP]{\__str_count_unsafe:n} -% \begin{syntax} -% \cs{__str_count_unsafe:n} \Arg{other string} -% \end{syntax} -% This function expects an argument that is entirely made of -% characters with category \enquote{other}, as produced by -% \cs{__str_to_other:n}. It leaves in the input stream the number of -% character tokens in the \meta{other string}, faster than the -% analogous \cs{str_count:n} function. -% \end{function} -% -% \begin{function}[EXP]{\__str_range_unsafe:nnn} -% \begin{syntax} -% \cs{__str_range_unsafe:nnn} \Arg{other string} \Arg{start index} \Arg{end index} -% \end{syntax} -% Identical to \cs{str_range:nnn} except that the first argument is -% expected to be entirely made of characters with category -% \enquote{other}, as produced by \cs{__str_to_other:n}, and the -% result is also an \meta{other string}. -% \end{function} -% -% \section{Possible additions to \pkg{l3str}} -% -% Semantically correct copies of some \texttt{tl} functions. -% \begin{itemize} -% \item \cs{c_space_str} -% \item \cs{str_clear:N}, \cs{str_gclear:N}, \cs{str_clear_new:N}, -% \cs{str_gclear_new:N}. -% \item \cs{str_concat:NNN}, \cs{str_gconcat:NNN} -% \item \cs{str_set_eq:NN}, \cs{str_gset_eq:NN} -% \item \cs{str_if_empty:NTF}, \cs{str_if_empty_p:N} -% \item \cs{str_if_exist:NTF}, \cs{str_if_exist_p:N} -% \item \cs{str_use:N} -% \end{itemize} -% -% Some functions that are not copies of \texttt{tl} functions. -% \begin{itemize} -% \item \cs{str_if_blank:NTF}, \cs{str_if_blank_p:N}. -% \item \cs{str_map_inline:Nn}, \cs{str_map_function:NN}, -% \cs{str_map_variable:NNn}, and \texttt{:n} analogs. -% \item Expandable \cs{str_if_in:nnTF}? -% \item \cs{str_if_head_eq:nNTF}, \cs{str_if_head_eq_p:nN} -% \item \cs{str_if_numeric/decimal/integer:n}, perhaps in \pkg{l3fp}? -% \end{itemize} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3str} implementation} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=str> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplPackage - {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -% \end{macrocode} -% -% The following string-related functions are currently defined in -% \pkg{l3kernel}. -% \begin{itemize} -% \item \cs{str_if_eq:nn}[pTF] and variants, -% \item \cs{str_if_eq_x_return:on}, \cs{str_if_eq_x_return:nn} -% \item \cs{tl_to_str:n}, \cs{tl_to_str:N}, \cs{tl_to_str:c}, -% \item \cs{token_to_str:N}, \cs{cs_to_str:N} -% \item \cs{str_head:n}, \cs{__str_head:w}, (copied here) -% \item \cs{str_tail:n}, \cs{__str_tail:w}, (copied here) -% \item \cs{__str_count_ignore_spaces} (unchanged) -% \item \cs{__str_count_loop:NNNNNNNNN} (unchanged) -% \end{itemize} -% -% \subsection{String assignments} -% -% \begin{macro}{\str_new:N, \str_new:c} -% A string is simply a token list. -% \begin{macrocode} -\cs_new_eq:NN \str_new:N \tl_new:N -\cs_generate_variant:Nn \str_new:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \str_set:Nn, \str_set:Nx, -% \str_set:cn, \str_set:cx, -% \str_gset:Nn, \str_gset:Nx, -% \str_gset:cn, \str_gset:cx, -% \str_const:Nn, \str_const:Nx, -% \str_const:cn, \str_const:cx, -% \str_put_left:Nn, \str_put_left:Nx, -% \str_put_left:cn, \str_put_left:cx, -% \str_gput_left:Nn, \str_gput_left:Nx, -% \str_gput_left:cn, \str_gput_left:cx, -% \str_put_right:Nn, \str_put_right:Nx, -% \str_put_right:cn, \str_put_right:cx, -% \str_gput_right:Nn, \str_gput_right:Nx, -% \str_gput_right:cn, \str_gput_right:cx, -% } -% Simply convert the token list inputs to \meta{strings}. -% \begin{macrocode} -\tl_map_inline:nn - { - { set } - { gset } - { const } - { put_left } - { gput_left } - { put_right } - { gput_right } - } - { - \cs_new_protected:cpx { str_ #1 :Nn } ##1##2 - { \exp_not:c { tl_ #1 :Nx } ##1 { \exp_not:N \tl_to_str:n {##2} } } - \exp_args:Nc \cs_generate_variant:Nn { str_ #1 :Nn } { Nx , cn , cx } - } -% \end{macrocode} -% \end{macro} -% -% \subsection{String variables and constants} -% -% \begin{variable} -% { -% \c_backslash_str, -% \c_left_brace_str, -% \c_right_brace_str, -% \c_hash_str, -% \c_tilde_str, -% \c_percent_str -% } -% For all of those strings, use \cs{cs_to_str:N} to get characters with -% the correct category code. The conditional for \cs{c_backslash_str} -% is needed as while this code is experimental others may also -% define the name (see \pkg{xpatch} for example). -% \begin{macrocode} -%<*package> -\cs_if_exist:NF \c_backslash_str - { \str_const:Nx \c_backslash_str { \cs_to_str:N \\ } } -%</package> -%<*initex> -\str_const:Nx \c_backslash_str { \cs_to_str:N \\ } -%</initex> -\str_const:Nx \c_left_brace_str { \cs_to_str:N \{ } -\str_const:Nx \c_right_brace_str { \cs_to_str:N \} } -\str_const:Nx \c_hash_str { \cs_to_str:N \# } -\str_const:Nx \c_tilde_str { \cs_to_str:N \~ } -\str_const:Nx \c_percent_str { \cs_to_str:N \% } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_tmpa_str, \l_tmpb_str, \g_tmpa_str, \g_tmpb_str} -% Scratch strings. -% \begin{macrocode} -\str_new:N \l_tmpa_str -\str_new:N \l_tmpb_str -\str_new:N \g_tmpa_str -\str_new:N \g_tmpb_str -% \end{macrocode} -% \end{variable} -% -% \subsection{Counting characters} -% -% \begin{macro}[EXP]{\str_count_spaces:N, \str_count_spaces:n} -% \begin{macro}[EXP, aux]{\@@_count_spaces_loop:wwwwwwwww} -% To speed up this function, we grab and discard $9$ space-delimited -% arguments in each iteration of the loop. The loop stops when the -% last argument is one of the trailing |X|\meta{number}, and that -% \meta{number} is added to the sum of $9$ that precedes, to adjust -% the result. -% \begin{macrocode} -\cs_new_nopar:Npn \str_count_spaces:N - { \exp_args:No \str_count_spaces:n } -\cs_new:Npn \str_count_spaces:n #1 - { - \int_eval:n - { - \exp_after:wN \@@_count_spaces_loop:wwwwwwwww - \tl_to_str:n {#1} ~ - X 7 ~ X 6 ~ X 5 ~ X 4 ~ X 3 ~ X 2 ~ X 1 ~ X 0 ~ X -1 ~ - \q_stop - } - } -\cs_new:Npn \@@_count_spaces_loop:wwwwwwwww #1~#2~#3~#4~#5~#6~#7~#8~#9~ - { - \if_meaning:w X #9 - \use_i_delimit_by_q_stop:nw - \fi: - \c_nine + \@@_count_spaces_loop:wwwwwwwww - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\str_count:N, \str_count:n, \str_count_ignore_spaces:n} -% \begin{macro}[EXP, int]{\@@_count_unsafe:n} -% \begin{macro}[EXP, aux]{\@@_count:n, \@@_count_loop:NNNNNNNNN} -% To count characters in a string we could first escape all spaces -% using \cs{@@_to_other:n}, then pass the result to \cs{tl_count:n}. -% However, the escaping step would be quadratic in the number of -% characters in the string, and we can do better. Namely, sum the -% number of spaces (\cs{str_count_spaces:n}) and the result of -% \cs{tl_count:n}, which ignores spaces. Since strings tend to be -% longer than token lists, we use specialized functions to count -% characters ignoring spaces. Namely, loop, grabbing $9$ non-space -% characters at each step, and end as soon as we reach one of the $9$ -% trailing items. The \texttt{_unsafe} variant expects a token list -% already converted to category code $12$ characters, and is used by -% \cs{str_item:nn} and \cs{str_range:nnn}. -% \begin{macrocode} -\cs_new_nopar:Npn \str_count:N { \exp_args:No \str_count:n } -\cs_new:Npn \str_count:n #1 - { - \@@_count:n - { - \str_count_spaces:n {#1} - + \exp_after:wN \@@_count_loop:NNNNNNNNN \tl_to_str:n {#1} - } - } -\cs_new:Npn \@@_count_unsafe:n #1 - { - \@@_count:n - { \@@_count_loop:NNNNNNNNN #1 } - } -\cs_new:Npn \str_count_ignore_spaces:n #1 - { - \@@_count:n - { \exp_after:wN \@@_count_loop:NNNNNNNNN \tl_to_str:n {#1} } - } -\cs_new:Npn \@@_count:n #1 - { - \int_eval:n - { - #1 - { X \c_eight } { X \c_seven } { X \c_six } - { X \c_five } { X \c_four } { X \c_three } - { X \c_two } { X \c_one } { X \c_zero } - \q_stop - } - } -\cs_set:Npn \@@_count_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9 - { - \if_meaning:w X #9 - \exp_after:wN \use_none_delimit_by_q_stop:w - \fi: - \c_nine + \@@_count_loop:NNNNNNNNN - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Head and tail of a string} -% -% \begin{macro}[EXP]{\str_head:N, \str_head:n, \str_head_ignore_spaces:n} -% \begin{macro}[EXP, aux]{\@@_head:w} -% The \texttt{_ignore_spaces} variant is almost identical to -% \cs{tl_head:n}. As usual, \cs{str_head:N} expands its argument and -% hands it to \cs{str_head:n}. To circumvent the fact that \TeX{} -% skips spaces when grabbing undelimited macro parameters, -% \cs{@@_head:w} takes an argument delimited by a space. If |#1| -% starts with a non-space character, \cs{use_i_delimit_by_q_stop:nw} -% leaves that in the input stream. On the other hand, if |#1| starts -% with a space, the \cs{@@_head:w} takes an empty argument, and the -% single (initially braced) space in the definition of \cs{@@_head:w} -% makes its way to the output. Finally, for an empty argument, the -% (braced) empty brace group in the definition of \cs{str_head:n} -% gives an empty result after passing through -% \cs{use_i_delimit_by_q_stop:nw}. -% \begin{macrocode} -\cs_new_nopar:Npn \str_head:N { \exp_args:No \str_head:n } -\cs_set:Npn \str_head:n #1 - { - \exp_after:wN \@@_head:w - \tl_to_str:n {#1} - { { } } ~ \q_stop - } -\cs_set:Npn \@@_head:w #1 ~ % - { \use_i_delimit_by_q_stop:nw #1 { ~ } } -\cs_new:Npn \str_head_ignore_spaces:n #1 - { - \exp_after:wN \use_i_delimit_by_q_stop:nw - \tl_to_str:n {#1} { } \q_stop - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\str_tail:N, \str_tail:n, \str_tail_ignore_spaces:n} -% \begin{macro}[EXP, aux]{\@@_tail_auxi:w, \@@_tail_auxii:w} -% Getting the tail is a little bit more convoluted than the head of a -% string. We hit the front of the string with \cs{reverse_if:N} -% \cs{if_charcode:w} \cs{scan_stop:}. This removes the first -% character, and necessarily makes the test true, since the character -% cannot match \cs{scan_stop:}. The auxiliary function then inserts -% the required \cs{fi:} to close the conditional, and leaves the tail -% of the string in the input stream. The details are such that an -% empty string has an empty tail (this requires in particular that the -% end-marker |X| be unexpandable and not a control sequence). The -% \texttt{_ignore_spaces} is rather simpler: after converting the -% input to a string, \cs{@@_tail_auxii:w} removes one undelimited -% argument and leaves everything else until an end-marker \cs{q_mark}. -% One can check that an empty (or blank) string yields an empty -% tail. -% \begin{macrocode} -\cs_new_nopar:Npn \str_tail:N { \exp_args:No \str_tail:n } -\cs_set:Npn \str_tail:n #1 - { - \exp_after:wN \@@_tail_auxi:w - \reverse_if:N \if_charcode:w - \scan_stop: \tl_to_str:n {#1} X X \q_stop - } -\cs_set:Npn \@@_tail_auxi:w #1 X #2 \q_stop { \fi: #1 } -\cs_new:Npn \str_tail_ignore_spaces:n #1 - { - \exp_after:wN \@@_tail_auxii:w - \tl_to_str:n {#1} \q_mark \q_mark \q_stop - } -\cs_new:Npn \@@_tail_auxii:w #1 #2 \q_mark #3 \q_stop { #2 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Accessing specific characters in a string} -% -% \begin{macro}[EXP, int]{\@@_to_other:n} -% \begin{macro}[EXP, aux]{\@@_to_other_loop:w, \@@_to_other_end:w} -% First apply \cs{tl_to_str:n}, then replace all spaces by -% \enquote{other} spaces, $8$ at a time, storing the converted part of -% the string between the \cs{q_mark} and \cs{q_stop} markers. The end -% is detected when \cs{@@_to_other_loop:w} finds one of the trailing -% |A|, distinguished from any contents of the initial token list by -% their category. Then \cs{@@_to_other_end:w} is called, and finds -% the result between \cs{q_mark} and the first |A| (well, there is -% also the need to remove a space). -% \begin{macrocode} -\group_begin: -\char_set_lccode:nn { `\* } { `\ } -\char_set_lccode:nn { `\A } { `\A } -\tl_to_lowercase:n - { - \group_end: - \cs_new:Npn \@@_to_other:n #1 - { - \exp_after:wN \@@_to_other_loop:w \tl_to_str:n {#1} ~ % - A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop - } - \cs_new:Npn \@@_to_other_loop:w - #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \q_stop - { - \if_meaning:w A #8 - \@@_to_other_end:w - \fi: - \@@_to_other_loop:w - #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop - } - \cs_new:Npn \@@_to_other_end:w \fi: #1 \q_mark #2 * A #3 \q_stop - { \fi: #2 } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP, aux]{\@@_skip_exp_end:w} -% \begin{macro}[EXP, aux] -% {\@@_skip_loop:wNNNNNNNN, \@@_skip_end:w, \@@_skip_end:NNNNNNNN} -% Removes |max(#1,0)| characters from the input stream, and then -% leaves \cs{exp_end:}. This should be expanded using -% \cs{exp:w}. We remove characters $8$ at a time until -% there are at most $8$ to remove. Then we do a dirty trick: the -% \cs{if_case:w} construction leaves between $0$ and $8$ times the -% \cs{or:} control sequence, and those \cs{or:} become arguments of -% \cs{@@_skip_end:NNNNNNNN}. If the number of characters to remove -% is $6$, say, then there are two \cs{or:} left, and the $8$ arguments -% of \cs{@@_skip_end:NNNNNNNN} are the two \cs{or:}, and $6$ -% characters from the input stream, exactly what we wanted to -% remove. Then close the \cs{if_case:w} conditional with \cs{fi:}, and -% stop the initial expansion with \cs{exp_end:} (see places where -% \cs{@@_skip_exp_end:w} is called). -% \begin{macrocode} -\cs_new:Npn \@@_skip_exp_end:w #1; - { - \if_int_compare:w #1 > \c_eight - \exp_after:wN \@@_skip_loop:wNNNNNNNN - \else: - \exp_after:wN \@@_skip_end:w - \int_use:N \__int_eval:w - \fi: - #1 ; - } -\cs_new:Npn \@@_skip_loop:wNNNNNNNN #1; #2#3#4#5#6#7#8#9 - { \exp_after:wN \@@_skip_exp_end:w \int_use:N \__int_eval:w #1 - \c_eight ; } -\cs_new:Npn \@@_skip_end:w #1 ; - { - \exp_after:wN \@@_skip_end:NNNNNNNN - \if_case:w #1 \exp_stop_f: \or: \or: \or: \or: \or: \or: \or: \or: - } -\cs_new:Npn \@@_skip_end:NNNNNNNN #1#2#3#4#5#6#7#8 { \fi: \exp_end: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP, aux]{\@@_collect_delimit_by_q_stop:w} -% \begin{macro}[EXP, aux] -% { -% \@@_collect_loop:wn, \@@_collect_loop:wnNNNNNNN, -% \@@_collect_end:wn, \@@_collect_end:nnnnnnnnw -% } -% Collects |max(#1,0)| characters, and removes everything else until -% \cs{q_stop}. This is somewhat similar to \cs{@@_skip_exp_end:w}, but -% accepts integer expression arguments. This time we can only grab -% $7$ characters at a time. At the end, we use an \cs{if_case:w} -% trick again, so that the $8$ first arguments of -% \cs{@@_collect_end:nnnnnnnnw} are some \cs{or:}, followed by an -% \cs{fi:}, followed by |#1| characters from the input stream. Simply -% leaving this in the input stream will close the conditional properly -% and the \cs{or:} disappear. -% \begin{macrocode} -\cs_new:Npn \@@_collect_delimit_by_q_stop:w #1; - { \@@_collect_loop:wn #1 ; { } } -\cs_new:Npn \@@_collect_loop:wn #1 ; - { - \if_int_compare:w #1 > \c_seven - \exp_after:wN \@@_collect_loop:wnNNNNNNN - \else: - \exp_after:wN \@@_collect_end:wn - \fi: - #1 ; - } -\cs_new:Npn \@@_collect_loop:wnNNNNNNN #1; #2 #3#4#5#6#7#8#9 - { - \exp_after:wN \@@_collect_loop:wn - \int_use:N \__int_eval:w #1 - \c_seven ; - { #2 #3#4#5#6#7#8#9 } - } -\cs_new:Npn \@@_collect_end:wn #1 ; - { - \exp_after:wN \@@_collect_end:nnnnnnnnw - \if_case:w \if_int_compare:w #1 > \c_zero #1 \else: 0 \fi: \exp_stop_f: - \or: \or: \or: \or: \or: \or: \fi: - } -\cs_new:Npn \@@_collect_end:nnnnnnnnw #1#2#3#4#5#6#7#8 #9 \q_stop - { #1#2#3#4#5#6#7#8 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\str_item:Nn, \str_item:nn, \str_item_ignore_spaces:nn} -% \begin{macro}[EXP, aux]{\@@_item_unsafe:nn, \@@_item:ww} -% The \cs{str_item:nn} hands its argument with spaces escaped to -% \cs{@@_item_unsafe:nn}, and makes sure to turn the result back into -% a proper string (with category code~$10$ spaces) eventually. The -% \cs{str_item_ignore_spaces:nn} function cheats a little bit in that -% it doesn't hand to \cs{@@_item_unsafe:nn} an \enquote{other string}. -% This is safe, as everything else is done with undelimited arguments. -% Then evaluate the \meta{index} argument~|#2| and count characters in -% the string, passing those two numbers to \cs{@@_item:ww} for further -% analysis. If the \meta{index} is negative, shift by |#2|, and -% remove that number of characters before returning the next item in -% the input stream (and if |#1| is smaller than $-|#2|$, nothing is -% returned). If the \meta{index} is positive, ignore that number -% (minus one) of characters before returning the next one. The shift -% by one is obtained by inserting an empty brace group before the -% string in that case: that brace group also covers the case where the -% \meta{index} is zero. -% \begin{macrocode} -\cs_new_nopar:Npn \str_item:Nn { \exp_args:No \str_item:nn } -\cs_new:Npn \str_item:nn #1#2 - { - \exp_args:Nf \tl_to_str:n - { - \exp_args:Nf \@@_item_unsafe:nn - { \@@_to_other:n {#1} } {#2} - } - } -\cs_new:Npn \str_item_ignore_spaces:nn #1 - { \exp_args:No \@@_item_unsafe:nn { \tl_to_str:n {#1} } } -\cs_new:Npn \@@_item_unsafe:nn #1#2 - { - \exp_after:wN \@@_item:ww - \int_use:N \__int_eval:w #2 \exp_after:wN ; - \__int_value:w \@@_count_unsafe:n {#1} ; - #1 \q_stop - } -\cs_new:Npn \@@_item:ww #1; #2; - { - \int_compare:nNnTF {#1} < \c_zero - { - \int_compare:nNnTF {#1} < {-#2} - { \use_none_delimit_by_q_stop:w } - { - \exp_after:wN \use_i_delimit_by_q_stop:nw - \exp:w \exp_after:wN \@@_skip_exp_end:w - \int_use:N \__int_eval:w #1 + #2 ; - } - } - { - \int_compare:nNnTF {#1} > {#2} - { \use_none_delimit_by_q_stop:w } - { - \exp_after:wN \use_i_delimit_by_q_stop:nw - \exp:w \@@_skip_exp_end:w #1 ; { } - } - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP, aux]{\@@_range_normalize:nn} -% This function converts an \meta{index} argument into an explicit -% position in the string (a result of $0$ denoting \enquote{out of -% bounds}). Expects two explicit integer arguments: the -% \meta{index} |#1| and the string count~|#2|. If |#1| is negative, -% replace it by $|#1| + |#2| + 1$, then limit to the range $[0, -% |#2|]$. -% \begin{macrocode} -\cs_new:Npn \@@_range_normalize:nn #1#2 - { - \int_eval:n - { - \if_int_compare:w #1 < \c_zero - \if_int_compare:w #1 < -#2 \exp_stop_f: - \c_zero - \else: - #1 + #2 + \c_one - \fi: - \else: - \if_int_compare:w #1 < #2 \exp_stop_f: - #1 - \else: - #2 - \fi: - \fi: - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP] -% {\str_range:Nnn, \str_range:nnn, \str_range_ignore_spaces:nnn} -% \begin{macro}[EXP, int]{\@@_range_unsafe:nnn} -% \begin{macro}[EXP, aux]{\@@_range:www, \@@_range:nnw} -% Sanitize the string. Then evaluate the arguments. At this stage we -% also decrement the \meta{start index}, since our goal is to know how -% many characters should be removed. Then limit the range to be -% non-negative and at most the length of the string (this avoids -% needing to check for the end of the string when grabbing -% characters), shifting negative numbers by the appropriate amount. -% Afterwards, skip characters, then keep some more, and finally drop -% the end of the string. -% \begin{macrocode} -\cs_new_nopar:Npn \str_range:Nnn { \exp_args:No \str_range:nnn } -\cs_new:Npn \str_range:nnn #1#2#3 - { - \exp_args:Nf \tl_to_str:n - { - \exp_args:Nf \@@_range_unsafe:nnn - { \@@_to_other:n {#1} } {#2} {#3} - } - } -\cs_new:Npn \str_range_ignore_spaces:nnn #1 - { \exp_args:No \@@_range_unsafe:nnn { \tl_to_str:n {#1} } } -\cs_new:Npn \@@_range_unsafe:nnn #1#2#3 - { - \exp_after:wN \@@_range:www - \__int_value:w \@@_count_unsafe:n {#1} \exp_after:wN ; - \int_use:N \__int_eval:w #2 - \c_one \exp_after:wN ; - \int_use:N \__int_eval:w #3 ; - #1 \q_stop - } -\cs_new:Npn \@@_range:www #1; #2; #3; - { - \exp_args:Nf \@@_range:nnw - { \@@_range_normalize:nn {#2} {#1} } - { \@@_range_normalize:nn {#3} {#1} } - } -\cs_new:Npn \@@_range:nnw #1#2 - { - \exp_after:wN \@@_collect_delimit_by_q_stop:w - \int_use:N \__int_eval:w #2 - #1 \exp_after:wN ; - \exp:w \@@_skip_exp_end:w #1 ; - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{String conditionals} -% -% \begin{macro}[EXP, pTF]{\str_if_eq:NN} -% \begin{macro}[EXP, pTF]{\str_if_eq:nn, \str_if_eq_x:nn} -% Note that \cs{str_if_eq:NN} is different from -% \cs{tl_if_eq:NN} because it needs to ignore category codes. -% \begin{macrocode} -\prg_new_conditional:Npnn \str_if_eq:NN #1#2 { p , TF , T , F } - { - \if_int_compare:w \__str_if_eq_x:nn { \tl_to_str:N #1 } { \tl_to_str:N #2 } - = \c_zero \prg_return_true: \else: \prg_return_false: \fi: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP, TF]{\str_case:nn, \str_case:on, \str_case_x:nn} -% Defined in \pkg{l3basics} at present. -% \end{macro} -% -% \subsection{Viewing strings} -% -% \begin{macro}{\str_show:n, \str_show:N, \str_show:c} -% Displays a string on the terminal. -% \begin{macrocode} -\cs_new_eq:NN \str_show:n \tl_show:n -\cs_new_eq:NN \str_show:N \tl_show:N -\cs_generate_variant:Nn \str_show:N { c } -% \end{macrocode} -% \end{macro} -% -% \subsection{Deprecated string functions} -% -% Deprecated 2013-01-20 for removal by 2013-04-30 -% \begin{macro}[EXP] -% {\str_substr:Nnn, \str_substr:nnn, \str_substr_ignore_spaces:nnn} -% \begin{macro}[EXP, aux]{\@@_substr:nnn} -% These functions used to allow for an empty argument to denote the -% start/end of the string. We reimplement them here by first checking -% for an empty argument, then only calling the appropriate version of -% the \cs{str_range:nnn} function. -% \begin{macrocode} -\cs_new:Npn \str_substr:Nnn #1 { \@@_substr:nnn { \str_range:Nnn #1 } } -\cs_new:Npn \str_substr:nnn #1 { \@@_substr:nnn { \str_range:nnn {#1} } } -\cs_new:Npn \str_substr_ignore_spaces:nnn #1 - { \@@_substr:nnn { \str_range_ignore_spaces:nnn {#1} } } -\cs_new:Npn \@@_substr:nnn #1#2#3 - { - \tl_if_empty:nTF {#2} - { \tl_if_empty:nTF {#3} { #1 { 1} { -1 } } { #1 { 1} {#3} } } - { \tl_if_empty:nTF {#3} { #1 {#2} { -1 } } { #1 {#2} {#3} } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% Deprecated 2013-01-20 for removal by 2013-04-30 -% \begin{variable}{\c_lbrace_str, \c_rbrace_str} -% \begin{macrocode} -\cs_new_eq:NN \c_lbrace_str \c_left_brace_str -\cs_new_eq:NN \c_rbrace_str \c_right_brace_str -% \end{macrocode} -% \end{variable} -% -% \begin{macrocode} -%</initex|package> -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex |