summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx753
1 files changed, 433 insertions, 320 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx
index a718f986ce7..b3648c57ede 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{expl3}
-\GetIdInfo$Id: l3str.dtx 2895 2011-10-09 15:58:19Z joseph $
+\GetIdInfo$Id: l3str.dtx 2921 2011-10-17 13:23:36Z bruno $
{L3 Experimental Strings}
%</driver|package>
%<*driver>
@@ -72,25 +72,23 @@
% \LaTeX3 provides a set of functions to manipulate token lists
% as strings of characters, ignoring the category codes of those
% characters.
-%
-% There is no separate string data type: string variables are simply
-% specialized token lists, conventionally made out only of characters
-% with category code $12$ (other), except spaces, which have category
-% code $10$ (blank space). All the \enquote{safe} functions in this
-% module first convert their argument to a string for internal processing,
+%
+% 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 \enquote{safe} functions in
+% this module first convert their argument to a string for internal processing,
% and will not treat a token list or the corresponding string representation
-% differently. However, it is often better to name token list variables
-% meant to contain string data with a name such as \cs{l_\ldots{}_str}.
-% Those are then manipulated mostly with tools from \pkg{l3tl}.
+% differently.
%
% Most functions in this module come in three flavours:
% \begin{itemize}
-% \item \cs{str_...:N...}, which expect a token list
-% 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 slightly faster than those
-% which take care of escaping spaces appropriately;
+% \item \cs{str_...:N...}, which expect a token list
+% 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 slightly faster than those
+% which take care of escaping spaces appropriately;
% \end{itemize}
% When performance is important, the internal \cs{str_..._unsafe:n...}
% functions, which expect a \enquote{safe} string in which spaces
@@ -98,66 +96,119 @@
%
% \subsection{Conversion and input of strings}
%
-% \begin{variable}{\c_backslash_str,
-% \c_lbrace_str,\c_rbrace_str,\c_hash_str,\c_percent_str}
+% \begin{variable}
+% {
+% \c_backslash_str,
+% \c_lbrace_str,
+% \c_rbrace_str,
+% \c_hash_str,
+% \c_percent_str
+% }
% Constant strings, containing a single character, with category code $12$.
% \end{variable}
%
-% \begin{function}[EXP]{\tl_to_str:N,\tl_to_str:n}
+% \begin{function}[EXP]{\tl_to_str:N, \tl_to_str:n}
% \begin{syntax}
% \cs{tl_to_str:N} \meta{tl var}
% \cs{tl_to_str:n} \Arg{token list}
% \end{syntax}
-% Converts the \meta{token list} to a \meta{string}.
+% Converts the \meta{token list} to a \meta{string}, leaving the resulting
+% tokens in the input stream.
+% \end{function}
+%
+% \begin{function}{\str_set:Nn, \str_set:Nx, \str_set:cn, \str_set: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 saves the result in \meta{str var}.
+% \end{function}
+%
+% \begin{function}{\str_gset:Nn, \str_gset:Nx, \str_gset:cn, \str_gset:cx}
+% \begin{syntax}
+% \cs{str_gset:Nn} \meta{str var} \Arg{token list}
+% \end{syntax}
+% Converts the \meta{token list} to a \meta{string},
+% and saves the result in \meta{str var} globally.
% \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,
+% \str_put_left:Nn, \str_put_left:Nx,
+% \str_put_left:cn, \str_put_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_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_gput_left:cn, \str_gput_left:cx
% }
+% \begin{syntax}
+% \cs{str_gput_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}, globally.
+% 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,
+% \str_put_right:cn, \str_put_right:cx
% }
% \begin{syntax}
-% \cs{str_set:Nn} \meta{str var} \Arg{token list}
+% \cs{str_put_right:Nn} \meta{str var} \Arg{token list}
% \end{syntax}
% Converts the \meta{token list} to a \meta{string},
-% and saves the result in \meta{str var}.
-% \end{function}
+% 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}
+%
+% \begin{function}
+% {
+% \str_gput_right:Nn, \str_gput_right:Nx,
+% \str_gput_right:cn, \str_gput_right:cx
+% }
+% \begin{syntax}
+% \cs{str_gput_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}, globally.
+% The current contents of the \meta{str var} are not
+% automatically converted to a string.
% \end{function}
%
-% \begin{function}{\str_input:Nn,\str_ginput:Nn}
+% \begin{function}{\str_input:Nn, \str_ginput:Nn}
% \begin{syntax}
% \cs{str_input:Nn} \meta{str var} \Arg{token list}
% \end{syntax}
% Converts the \meta{token list} into a \meta{string}, and stores
-% it in the \meta{str var}. Special characters can be input by
+% it in the \meta{str var}, within the current \TeX{} group level
+% for the \texttt{input} variant and globally for the \texttt{ginput}
+% version.
+% Special characters can be input by
% escaping them with a backslash.
% \begin{itemize}
-% \item Spaces are ignored unless escaped with a backslash.
-% \item |\xhh| produces the character with code \texttt{hh}
-% in hexadecimal: when |\x| is encountered, up to two hexadecimal digits
-% (\texttt{0}--\texttt{9}, \texttt{a}--\texttt{f}, \texttt{A}--\texttt{F})
-% are read to give a number between $0$ and $255$.
-% \item |\x{hh...}| produces the character with code \texttt{hh...}
-% (an aribtrary number of hexadecimal digits are read):
-% this is mostly useful for Lua\TeX{} and Xe\TeX{}.
-% \item |\a|, |\e|, |\f|, |\n|, |\r|, |\t| stand for specific characters:
+% \item Spaces are ignored unless escaped with a backslash.
+% \item |\xhh| produces the character with code \texttt{hh}
+% in hexadecimal: when |\x| is encountered, up to two hexadecimal digits
+% (\texttt{0}--\texttt{9}, \texttt{a}--\texttt{f},
+% \texttt{A}--\texttt{F})
+% are read to give a number between $0$ and $255$.
+% \item |\x{hh...}| produces the character with code \texttt{hh...}
+% (an arbitrary number of hexadecimal digits are read):
+% this is mostly useful for \LuaTeX{} and \XeTeX{}.
+% \item |\a|, |\e|, |\f|, |\n|, |\r|, |\t| stand for specific characters:
% \begin{center}
% \begin{tabular}{cccc}
% |\a| & |\^^G| & alarm & hex \texttt{07} \\
@@ -172,26 +223,27 @@
% For instance,
% \begin{quote}
% \cs{tl_new:N} \cs{l_my_str} \\
-% \cs{str_input:Nn} \cs{l_my_str} |{\x3C \\ \# abc\ def\^}|
+% \cs{str_input:Nn} \cs{l_my_str} |{\x3C \\ \# abc\ def\^\n}|
% \end{quote}
-% results in \cs{l_my_str} containing the characters |\<#abc def^|,
-% since |<| has ascii code \texttt{3C} (in hexadecimal).
+% results in \cs{l_my_str} containing the characters |<\#abc def^|,
+% followed by a newline character (hex \texttt{0A})
+% since |<| has \textsc{ascii} code \texttt{3C} (in hexadecimal).
% \end{function}
%
% \subsection{Characters given by their position}
%
-% \begin{function}[EXP]{\str_length:N}
-% \begin{function}[EXP]{\str_length:n}
-% \begin{function}[EXP]{\str_length_ignore_spaces:n}
+% \begin{function}[EXP]
+% {\str_length:N, \str_length:n, \str_length_ignore_spaces:n}
% \begin{syntax}
% \cs{str_length:n} \Arg{token list}
% \end{syntax}
% Leaves the length of the string representation of \meta{token list}
-% in the input stream. The functions differ in their treatment of spaces.
+% in the input stream as an integer denotation. The functions differ in
+% their treatment of spaces.
% In the case of \cs{str_length:N} and \cs{str_length:n},
% all characters including spaces are counted.
-% The \cs{str_length_ignore_spaces:n} returns the number of non-space
-% characters.
+% The \cs{str_length_ignore_spaces:n} leaves the number of non-space
+% characters in the input stream.
% \begin{texnote}
% The \cs{str_length:n} of a given token list may depend
% on the category codes in effect when it is measured,
@@ -200,12 +252,8 @@
% on the escape character, and the category code of \texttt{a}.
% \end{texnote}
% \end{function}
-% \end{function}
-% \end{function}
%
-% \begin{function}[EXP]{\str_head:N}
-% \begin{function}[EXP]{\str_head:n}
-% \begin{function}[EXP]{\str_head_ignore_spaces:n}
+% \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}
@@ -215,18 +263,14 @@
% The functions differ in their treatment of spaces.
% In the case of \cs{str_head:N} and \cs{str_head:n},
% a leading space is returned with category code $10$ (blank space).
-% The \cs{str_head_ignore_spaces:n} function returns the first
-% non-space character.
+% The \cs{str_head_ignore_spaces:n} function leaves the first
+% non-space character in the input stream.
% 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}
-% \end{function}
-% \end{function}
%
-% \begin{function}[EXP]{\str_tail:N}
-% \begin{function}[EXP]{\str_tail:n}
-% \begin{function}[EXP]{\str_tail_ignore_spaces:n}
+% \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}
@@ -239,12 +283,8 @@
% only that space, while \cs{str_tail_ignore_spaces:n} trims
% the first non-space character.
% \end{function}
-% \end{function}
-% \end{function}
%
-% \begin{function}[EXP]{\str_item:Nn}
-% \begin{function}[EXP]{\str_item:nn}
-% \begin{function}[EXP]{\str_item_ignore_spaces:nn}
+% \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}
@@ -260,29 +300,25 @@
% the right-most character, \emph{etc.}, while $0$ is the first
% (left-most) character.
% \end{function}
-% \end{function}
-% \end{function}
%
-% \begin{function}[EXP]{\str_from_to:Nnn}
-% \begin{function}[EXP]{\str_from_to:nnn}
-% \begin{function}[EXP]{\str_from_to_ignore_spaces:nnn}
+% \begin{function}[EXP]
+% {\str_substr:Nnn, \str_substr:nnn, \str_substr_ignore_spaces:nnn}
% \begin{syntax}
-% \cs{str_from_to:nnn} \Arg{token list} \Arg{start index} \Arg{end index}
+% \cs{str_substr: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
% between \meta{start index} (inclusive) and \meta{end index} (exclusive).
% If either of \meta{start index} or \meta{end index} is negative,
-% the it is incremented by the length of the list.
-% \end{function}
-% \end{function}
+% the it is incremented by the length of the list. Both \meta{start index}
+% and \meta{end index} count from $0$ for the first (left most) character.
% \end{function}
%
% \subsection{String conditionals}
%
-% \begin{function}[EXP,pTF]{\str_if_eq:NN}
-% \begin{function}[EXP,pTF]
+% \begin{function}[EXP, pTF]
% {
+% \str_if_eq:NN,
% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:no,
% \str_if_eq:nV, \str_if_eq:VV, \str_if_eq:xx
% }
@@ -300,10 +336,9 @@
% expandable (including those involving an \texttt{x}-type
% expansion).
% \end{function}
-% \end{function}
%
-% \begin{function}[EXP,pTF]{\str_if_contains_char:NN}
-% \begin{function}[EXP,pTF]{\str_if_contains_char:nN}
+% \begin{function}[EXP, pTF]
+% {\str_if_contains_char:NN, \str_if_contains_char:nN}
% \begin{syntax}
% \cs{str_if_contains_char:nN} \Arg{token list} \meta{char}
% \end{syntax}
@@ -312,43 +347,43 @@
% The \meta{char} can be given either directly, or as a one
% letter control sequence.
% \end{function}
-% \end{function}
%
-% \subsection{Bytes and encoding}
+% \subsection{Byte conditionals}
%
-% \subsubsection{Conditionals}
-%
-% \begin{function}[EXP,pTF]{\str_if_bytes:N}
+% \begin{function}[EXP, pTF]{\str_if_bytes:N}
% \begin{syntax}
% \cs{str_if_bytes:NTF} \meta{str var} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests whether the \meta{str var} only contains characters
-% in the range $0$--$255$.
-% \end{function}
-%
-% \begin{function}[EXP,pTF]{\str_if_UTF_viii:N}
-% \begin{syntax}
-% \cs{str_if_UTF_viii:N} \meta{str var} \Arg{true code} \Arg{false code}
-% \end{syntax}
-% Tests whether the \meta{str var} only contains characters
-% in the range $0$--$255$, and forms a valid \texttt{UTF8} string.
-% \textbf{Missing!} ^^A Missing.
+% in the range $0$ to $255$.
% \end{function}
%
-% \subsubsection{Conversion}
+% ^^A\begin{function}[EXP, pTF]{\str_if_UTF_viii:N}
+% ^^A \begin{syntax}
+% ^^A \cs{str_if_UTF_viii:N} \meta{str var} \Arg{true code} \Arg{false code}
+% ^^A \end{syntax}
+% ^^A Tests whether the \meta{str var} only contains characters
+% ^^A in the range $0$--$255$, and forms a valid \texttt{UTF8} string.
+% ^^A \textbf{Missing!} ^^A Missing.
+% ^^A\end{function}
+%
+% \subsection{Byte conversion}
+%
+% Byte conversions are necessary where strings are to be used in PDF
+% string objects or within URLs. In both cases, only a restricted subset
+% of characters are permitted.
%
% \begin{function}{\str_native_from_UTF_viii:NN}
% \begin{syntax}
% \cs{str_native_from_UTF_viii:NN} \meta{str~var1} \meta{str~var2}
% \end{syntax}
-% Reads the contents of the \meta{str~var2} as an \texttt{UTF8}-encoded
+% Reads the contents of the \meta{str~var2} as an \textsc{utf8}-encoded
% sequence of bytes, and stores the resulting characters (which can
% now have any character code) into \meta{str~var1}.
% This function raises an error if the \meta{str~var2} is not
-% a valid sequence of bytes in the \texttt{UTF8} encoding.
+% a valid sequence of bytes in the \textsc{utf8} encoding.
% In the \pdfTeX{} engine, this function raises an error if any of the
-% resulting characters is outside the range $0$--$255$ (in other words,
-% don't use this function with \pdfTeX{}).
+% resulting characters is outside the range $0$ to $255$.
% \end{function}
%
% \begin{function}{\str_UTF_viii_from_native:NN}
@@ -356,58 +391,123 @@
% \cs{str_UTF_viii_from_native:NN} \meta{str~var1} \meta{str~var2}
% \end{syntax}
% Converts each character of the \meta{str~var2} into
-% a sequence of bytes, as defined by the \texttt{UTF8}
+% a sequence of bytes, as defined by the \textsc{utf8}
% encoding, and stores the result in \meta{str~var1}.
% In the \pdfTeX{} engine, this function is of course
% of very little use, but can be used without harm:
-% characters in the range $0$--$127$ are left unchanged,
-% and characters in the range $128$--$255$ become two-byte
+% characters in the range $0$ to $127$ are left unchanged,
+% and characters in the range $128$ to $255$ become two-byte
% sequences, as per the definition of \texttt{UTF8}.
% \end{function}
%
-% \begin{function}{\str_bytes_escape_hexadecimal:NN}
-% \begin{function}{\str_bytes_unescape_hexadecimal:NN}
+% \begin{function}
+% {\str_bytes_escape_hexadecimal:NN, \str_bytes_unescape_hexadecimal:NN}
% \begin{syntax}
% \cs{str_bytes_escape_hexadecimal:NN} \meta{str var1} \meta{str var2}
% \cs{str_bytes_unescape_hexadecimal:NN} \meta{str var1} \meta{str var2}
% \end{syntax}
-% See \tn{pdfescapehex}. ^^A missing doc
-% \end{function}
+% The \texttt{escape} variant takes each character in \meta{str var1}
+% and converts it into the hexadecimal representation. The resulting
+% string is stored in \meta{str var2} within the current \TeX{} group
+% level. The \texttt{unescape} variant reverses this process.
+% Thus for example
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { Hello ( ) }
+% \str_bytes_escape_hexadecimal:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |48656C6C6F2829|,
+% while
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { 48656C6C6F2829 }
+% \str_bytes_unescape_hexadecimal:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello()|.
+% See also \tn{pdfescapehex}.
% \end{function}
%
-% \begin{function}{\str_bytes_escape_name:NN}
-% \begin{function}{\str_bytes_unescape_name:NN}
+% \begin{function}
+% {\str_bytes_escape_name:NN, \str_bytes_unescape_name:NN}
% \begin{syntax}
% \cs{str_bytes_escape_name:NN} \meta{str var1} \meta{str var2}
% \cs{str_bytes_unescape_name:NN} \meta{str var1} \meta{str var2}
% \end{syntax}
-% See \tn{pdfescapename}. ^^A missing doc
-% \end{function}
+% The \texttt{escape} variant takes each character in \meta{str var1}
+% and replaces any which cannot be used directly in a PDF string object
+% with the appropriate hexadecimal representation preceded by the |#|
+% character. The resulting
+% string is stored in \meta{str var2} within the current \TeX{} group
+% level. The \texttt{unescape} variant reverses this process. Thus for
+% example
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { Hello ( ) }
+% \str_bytes_escape_name:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello#28#29|,
+% while
+% \begin{verbatim}
+% \char_set_catcode_other:N \#
+% \str_set:Nn \l_mya_str { Hello#28#29 }
+% \str_bytes_unescape_name:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello()|.
+% See also \tn{pdfescapename}.
% \end{function}
%
-% \begin{function}{\str_bytes_escape_string:NN}
-% \begin{function}{\str_bytes_unescape_string:NN}
+% \begin{function}{\str_bytes_escape_string:NN, \str_bytes_unescape_string:NN}
% \begin{syntax}
% \cs{str_bytes_escape_string:NN} \meta{str var1} \meta{str var2}
% \cs{str_bytes_unescape_string:NN} \meta{str var1} \meta{str var2}
% \end{syntax}
-% See \tn{pdfescapestring}. ^^A missing doc
-% \end{function}
+% The \texttt{escape} variant takes each character in \meta{str var1}
+% and prepends a |\| to any which cannot be used directly in a PDF string
+% object. The resulting string is stored in \meta{str var2} within the
+% current \TeX{} group level. The \texttt{unescape} variant reverses this
+% process. Thus for example
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { Hello [ ] }
+% \str_bytes_escape_string:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello\(\)|,
+% while
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { Hello\(\) }
+% \str_bytes_unescape_string:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello()|.
+% Some characters (for example a space) are converted to a three-digit
+% octal representation, so for example a space gives |\040|.
+% See also \tn{pdfescapename}.
% \end{function}
%
-% \begin{function}{\str_bytes_percent_encode:NN}
-% \begin{function}{\str_bytes_percent_decode:NN}
+% \begin{function}{\str_bytes_percent_encode:NN, \str_bytes_percent_decode:NN}
% \begin{syntax}
% \cs{str_bytes_percent_encode:NN} meta{str var1} \meta{str var2}
% \cs{str_bytes_percent_decode:NN} meta{str var1} \meta{str var2}
% \end{syntax}
-% Used for urls. ^^A missing doc
-% \end{function}
+% The \texttt{escape} variant takes each character in \meta{str var1}
+% and replaces any which cannot be used directly in a URL
+% with the appropriate hexadecimal representation preceded by the |%|
+% character. The resulting
+% string is stored in \meta{str var2} within the current \TeX{} group
+% level. The \texttt{unescape} variant reverses this process. Thus for
+% example
+% \begin{verbatim}
+% \str_set:Nn \l_mya_str { Hello ( ) }
+% \str_bytes_precent_encode:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello%28%29|,
+% while
+% \begin{verbatim}
+% \char_set_catcode_other:N \%
+% \str_set:Nn \l_mya_str { Hello%28%29 }
+% \str_bytes_unescape_name:NN \l_mya_str \l_myb_str
+% \end{verbatim}
+% will result in \cs{l_myb_str} containing the string |Hello()|.
% \end{function}
%
% \subsection{Internal string functions}
%
-% \begin{function}[EXP]{\tl_to_other_str:N,\tl_to_other_str:n}
+% \begin{function}[EXP]{\tl_to_other_str:N, \tl_to_other_str:n}
% \begin{syntax}
% \cs{tl_to_other_str:n} \Arg{token list}
% \end{syntax}
@@ -421,7 +521,7 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}[EXP]{\str_sanitize_args:Nn,\str_sanitize_args:Nnn}
+% \begin{function}[EXP]{\str_sanitize_args:Nn, \str_sanitize_args:Nnn}
% \begin{syntax}
% \cs{str_sanitize_args:Nnn} \meta{function}
% ~~\Arg{token list1} \Arg{token list2}
@@ -473,7 +573,6 @@
% Some functionalities of \pkg{stringstrings} and \pkg{xstring} as well.
%
%^^A Should "str_item" be "str_char"?
-%^^A Should "str_from_to" be "str_substr"?
%
% \end{documentation}
%
@@ -482,7 +581,7 @@
% \section{\pkg{l3str} implementation}
%
% \begin{macrocode}
-%<*package>
+%<*initex|package>
% \end{macrocode}
%
% \begin{macrocode}
@@ -492,31 +591,18 @@
%
% Those string-related functions are defined in \pkg{l3kernel}.
% \begin{itemize}
-% \item \cs{str_if_eq:nn}[pTF] and variants,
-% \item \cs{str_if_eq_return:on},
-% \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_aux:w}, (changed behaviour slightly)
-% \item \cs{str_tail:n}, \cs{str_tail_aux:w}, (changed behaviour slightly)
-% \item \cs{str_length_skip_spaces} (deprecated)
-% \item \cs{str_length_loop:NNNNNNNNN} (unchanged)
+% \item \cs{str_if_eq:nn}[pTF] and variants,
+% \item \cs{str_if_eq_return:on},
+% \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_aux:w}, (copied here)
+% \item \cs{str_tail:n}, \cs{str_tail_aux:w}, (copied here)
+% \item \cs{str_length_skip_spaces} (deprecated)
+% \item \cs{str_length_loop:NNNNNNNNN} (unchanged)
% \end{itemize}
%
% \subsection{General functions}
%
-% \begin{macro}[EXP,aux]{\cs_if_exist_use:cF}
-% This function could be moved to a different module in \pkg{l3kernel}.
-% If the control sequence exists, use it,
-% otherwise fall back to a default behaviour.
-% \begin{macrocode}
-\cs_if_exist:NF \cs_if_exist_use:cF
- {
- \cs_new:Npn \cs_if_exist_use:cF #1
- { \cs_if_exist:cTF {#1} { \use:c {#1} } }
- }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}[EXP,aux]{\use_i:nnnnnnnn}
% A function which may already be defined elsewhere.
% \begin{macrocode}
@@ -542,18 +628,20 @@
% }
% Simply convert the token list inputs to \meta{strings}.
% \begin{macrocode}
-\cs_set:Npn \str_tmp:w #1
- {
- \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 }
- }
-\str_tmp:w {set}
-\str_tmp:w {gset}
-\str_tmp:w {put_left}
-\str_tmp:w {gput_left}
-\str_tmp:w {put_right}
-\str_tmp:w {gput_right}
+\group_begin:
+ \cs_set_protected_nopar:Npn \str_tmp:w #1
+ {
+ \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 }
+ }
+ \str_tmp:w { set }
+ \str_tmp:w { gset }
+ \str_tmp:w { put_left }
+ \str_tmp:w { gput_left }
+ \str_tmp:w { put_right }
+ \str_tmp:w { gput_right }
+\group_end:
% \end{macrocode}
% \end{macro}
%
@@ -563,7 +651,7 @@
% \begin{variable}{\g_str_tmpa_tl}
% Internal scratch space for some functions.
% \begin{macrocode}
-\cs_set_protected_nopar:Npn \str_tmp:w { }
+\cs_new_protected_nopar:Npn \str_tmp:w { }
\tl_new:N \g_str_tmpa_tl
% \end{macrocode}
% \end{variable}
@@ -579,11 +667,11 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_str_char_int,\l_str_bytes_int}
+% \begin{variable}{\l_str_char_int, \l_str_bytes_int}
% When converting from various escaped forms to raw characters,
% we often need to read several digits (hexadecimal or octal depending
% on the case) and keep track of the corresponding character code
-% in \cs{l_str_char_int}. For UTF-8 support, the number of bytes
+% in \cs{l_str_char_int}. For \textsc{utf8} support, the number of bytes
% of for the current character is stored in \cs{l_str_bytes_int}.
% \begin{macrocode}
\int_new:N \l_str_char_int
@@ -591,8 +679,14 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\c_backslash_str,
-% \c_lbrace_str,\c_rbrace_str,\c_hash_str,\c_percent_str}
+% \begin{variable}
+% {
+% \c_backslash_str,
+% \c_lbrace_str,
+% \c_rbrace_str,
+% \c_hash_str,
+% \c_percent_str
+% }
% For all of those strings, \cs{cs_to_str:N} produce characters
% with the correct category code.
% \begin{macrocode}
@@ -606,48 +700,45 @@
%
% \subsection{Escaping spaces}
%
-% \begin{macro}[EXP]{\tl_to_other_str:N,\tl_to_other_str:n}
-% \begin{macro}[EXP,aux]{\tl_to_other_str_loop:w,\tl_to_other_str_end:w}
+% \begin{macro}[EXP]{\tl_to_other_str:N, \tl_to_other_str:n}
+% \begin{macro}[EXP,aux]{\tl_to_other_str_loop:w, \tl_to_other_str_end:w}
% Replaces all spaces by \enquote{other} spaces, after converting
% the token list to a string via \cs{tl_to_str:n}.
% \begin{macrocode}
\group_begin:
-\char_set_lccode:nn {`\*}{`\ }
-\char_set_lccode:nn {`\A}{`\A}
-\tl_to_lowercase:n {
- \group_end:
- \cs_new:Npn \tl_to_other_str:n #1
- {
- \exp_after:wN \tl_to_other_str_loop:w \tl_to_str:n {#1} ~ %
- A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop
- }
- \cs_new_nopar:Npn \tl_to_other_str_loop:w
+\char_set_lccode:nn { `\* } { `\ }
+\char_set_lccode:nn { `\A } { `\A }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new:Npn \tl_to_other_str:n #1
+ {
+ \exp_after:wN \tl_to_other_str_loop:w \tl_to_str:n {#1} ~ %
+ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop
+ }
+ \cs_new_nopar:Npn \tl_to_other_str_loop:w
#1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \q_stop
- {
- \if_meaning:w A #8
- \tl_to_other_str_end:w
- \fi:
- \tl_to_other_str_loop:w
- #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop
- }
- \cs_new_nopar:Npn \tl_to_other_str_end:w \fi: #1 \q_mark #2 * A #3 \q_stop
- { \fi: #2 }
-}
-\cs_new_nopar:Npn \tl_to_other_str:N
- { \exp_args:No \tl_to_other_str:n }
+ {
+ \if_meaning:w A #8
+ \tl_to_other_str_end:w
+ \fi:
+ \tl_to_other_str_loop:w
+ #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop
+ }
+ \cs_new_nopar:Npn \tl_to_other_str_end:w \fi: #1 \q_mark #2 * A #3 \q_stop
+ { \fi: #2 }
+ }
+\cs_new_nopar:Npn \tl_to_other_str:N { \exp_args:No \tl_to_other_str:n }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}[EXP]{\str_sanitize_args:Nn,\str_sanitize_args:Nnn}
+% \begin{macro}[EXP]{\str_sanitize_args:Nn, \str_sanitize_args:Nnn}
% Here, \texttt{f}-expansion does not lose leading spaces,
% since they have catcode \enquote{other} after \cs{str_sanitize:n}.
% \begin{macrocode}
-\cs_new:Npn \str_sanitize_args:Nn #1 #2
- {
- \exp_args:Nf #1
- { \tl_to_other_str:n {#2} }
- }
+\cs_new:Npn \str_sanitize_args:Nn #1#2
+ { \exp_args:Nf #1 { \tl_to_other_str:n {#2} } }
\cs_new:Npn \str_sanitize_args:Nnn #1#2#3
{
\exp_args:Nff #1
@@ -726,15 +817,15 @@
% gives an empty result after passing through
% \cs{use_i_delimit_by_q_stop:nw}.
% \begin{macrocode}
-\cs_set_nopar:Npn \str_head:N { \exp_args:No \str_head:n }
+\cs_new_nopar:Npn \str_head:N { \exp_args:No \str_head:n }
\cs_set:Npn \str_head:n #1
{
\exp_after:wN \str_head_aux:w
\tl_to_str:n {#1}
{ { } } ~ \q_stop
}
-\cs_set_nopar:Npx \str_head_aux:w #1 ~ %
- { \exp_not:N \use_i_delimit_by_q_stop:nw #1 { ~ } }
+\cs_set_nopar:Npn \str_head_aux: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 }
\cs_new_nopar:Npn \str_head_unsafe:n #1
@@ -779,7 +870,7 @@
}
\cs_new_nopar:Npn \str_tail_unsafe:n #1
{ \str_tail_aux_ii:w #1 X { } X \q_stop }
-\cs_set_nopar:Npn \str_tail_aux_ii:w #1 #2 X #3 \q_stop { #2 }
+\cs_new_nopar:Npn \str_tail_aux_ii:w #1 #2 X #3 \q_stop { #2 }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -800,12 +891,14 @@
% \begin{macrocode}
\cs_new:Npn \str_skip_do:nn #1
{
- \int_compare:nNnTF {#1} > \c_seven
- { \str_skip_aux:nnnnnnnnn }
- { \str_skip_end:n }
+ \if_num:w \int_eval:w #1 > \c_seven
+ \exp_after:wN \str_skip_aux:nnnnnnnnn
+ \else:
+ \exp_after:wN \str_skip_end:n
+ \fi:
{#1}
}
-\cs_new:Npn \str_skip_aux:nnnnnnnnn #1#2 #3#4#5#6#7#8#9
+\cs_new:Npn \str_skip_aux:nnnnnnnnn #1#2#3#4#5#6#7#8#9
{ \exp_args:Nf \str_skip_do:nn { \int_eval:n { #1 - \c_seven } } {#2} }
\cs_new:Npn \str_skip_end:n #1
{
@@ -821,7 +914,7 @@
\else: \str_skip_end_ii:nwn { XXXXXXX }
\fi:
}
-\cs_new:Npn \str_skip_end_ii:nwn #1 #2 \fi: #3
+\cs_new:Npn \str_skip_end_ii:nwn #1#2 \fi: #3
{ \fi: \use_i:nnnnnnnn {#3} #1 }
% \end{macrocode}
% \end{macro}
@@ -861,18 +954,18 @@
\cs_new:Npn \str_collect_end:n #1
{
\if_case:w \int_eval:w #1 \int_eval_end:
- \str_collect_end_ii:nwn { {}{}{}{}{}{}{} }
- \or: \str_collect_end_ii:nwn { {}{}{}{}{}{} }
- \or: \str_collect_end_ii:nwn { {}{}{}{}{} }
- \or: \str_collect_end_ii:nwn { {}{}{}{} }
- \or: \str_collect_end_ii:nwn { {}{}{} }
- \or: \str_collect_end_ii:nwn { {}{} }
- \or: \str_collect_end_ii:nwn { {} }
+ \str_collect_end_ii:nwn { { } { } { } { } { } { } { } }
+ \or: \str_collect_end_ii:nwn { { } { } { } { } { } { } }
+ \or: \str_collect_end_ii:nwn { { } { } { } { } { } }
+ \or: \str_collect_end_ii:nwn { { } { } { } { } }
+ \or: \str_collect_end_ii:nwn { { } { } { } }
+ \or: \str_collect_end_ii:nwn { { } { } }
+ \or: \str_collect_end_ii:nwn { { } }
\or: \str_collect_end_ii:nwn { }
- \else: \str_collect_end_ii:nwn { {}{}{}{}{}{}{} }
+ \else: \str_collect_end_ii:nwn { { } { } { } { } { } { } { } }
\fi:
}
-\cs_new:Npn \str_collect_end_ii:nwn #1 #2 \fi: #3
+\cs_new:Npn \str_collect_end_ii:nwn #1#2 \fi: #3
{ \fi: #3 \q_stop #1 }
\cs_new:Npn \str_collect_end_iii:nwNNNNNNN #1 #2 \q_stop #3#4#5#6#7#8#9
{ #1 {#2#3#4#5#6#7#8#9} }
@@ -938,12 +1031,12 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}[EXP]{\str_from_to:Nnn}
-% \begin{macro}[EXP]{\str_from_to:nnn}
-% \begin{macro}[EXP]{\str_from_to_ignore_spaces:nnn}
-% \begin{macro}[EXP]{\str_from_to_unsafe:nnn}
-% \begin{macro}[EXP,aux]{\str_from_to_aux:nnnw}
-% \begin{macro}[EXP,aux]{\str_from_to_aux_ii:nnw}
+% \begin{macro}[EXP]{\str_substr:Nnn}
+% \begin{macro}[EXP]{\str_substr:nnn}
+% \begin{macro}[EXP]{\str_substr_ignore_spaces:nnn}
+% \begin{macro}[EXP]{\str_substr_unsafe:nnn}
+% \begin{macro}[EXP,aux]{\str_substr_aux:nnnw}
+% \begin{macro}[EXP,aux]{\str_substr_aux_ii:nnw}
% \begin{macro}[EXP,aux]{\str_aux_eval_args:Nnnn}
% \begin{macro}[EXP,aux]{\str_aux_normalize_range:nn}
% Sanitize the string, then limit the second and third arguments
@@ -952,30 +1045,30 @@
% Afterwards, skip characters, then keep some more, and finally
% drop the end of the string.
% \begin{macrocode}
-\cs_new_nopar:Npn \str_from_to:Nnn { \exp_args:No \str_from_to:nnn }
-\cs_new:Npn \str_from_to:nnn #1#2#3
+\cs_new_nopar:Npn \str_substr:Nnn { \exp_args:No \str_substr:nnn }
+\cs_new:Npn \str_substr:nnn #1#2#3
{
\exp_args:Nf \tl_to_str:n
- { \str_sanitize_args:Nn \str_from_to_unsafe:nnn {#1}{#2}{#3} }
+ { \str_sanitize_args:Nn \str_substr_unsafe:nnn {#1} {#2} {#3} }
}
-\cs_new:Npn \str_from_to_ignore_spaces:nnn #1
- { \exp_args:No \str_from_to_unsafe:nnn { \tl_to_str:n {#1} } }
-\cs_new:Npn \str_from_to_unsafe:nnn #1#2#3 % <string> <from> <to>
+\cs_new:Npn \str_substr_ignore_spaces:nnn #1
+ { \exp_args:No \str_substr_unsafe:nnn { \tl_to_str:n {#1} } }
+\cs_new:Npn \str_substr_unsafe:nnn #1#2#3
{
- \str_aux_eval_args:Nnnn \str_from_to_aux:nnnw
+ \str_aux_eval_args:Nnnn \str_substr_aux:nnnw
{ \str_length_unsafe:n {#1} }
{#2}
{#3}
#1
\q_stop
}
-\cs_new:Npn \str_from_to_aux:nnnw #1#2#3 % <len> <from> <to>
+\cs_new:Npn \str_substr_aux:nnnw #1#2#3
{
- \exp_args:Nf \str_from_to_aux_ii:nnw
+ \exp_args:Nf \str_substr_aux_ii:nnw
{ \str_aux_normalize_range:nn {#2} {#1} }
{ \str_aux_normalize_range:nn {#3} {#1} }
}
-\cs_new:Npn \str_from_to_aux_ii:nnw #1#2
+\cs_new:Npn \str_substr_aux_ii:nnw #1#2
{
\str_skip_do:nn {#1}
{
@@ -1127,7 +1220,7 @@
%
% \subsection{Internal conditionals}
%
-% \begin{macro}[aux]{\str_aux_hexadecimal_test:N}
+% \begin{macro}[aux]{\str_aux_hexadecimal_test:NTF}
% This test is used when reading hexadecimal digits, for the |\x| escape
% sequence, and some conversion functions. It returns \meta{true} if the
% token is a hexadecimal digit, and \meta{false} otherwise. It has the
@@ -1137,7 +1230,7 @@
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \str_aux_hexadecimal_test:N #1 { TF }
{
- \tl_if_in:onTF { \tl_to_str:n {abcdef} } {#1}
+ \tl_if_in:onTF { \tl_to_str:n { abcdef } } {#1}
{
\int_set:Nn \l_str_char_int
{ \c_sixteen * \l_str_char_int + `#1 - 87 }
@@ -1156,7 +1249,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[aux]{\str_aux_octal_test:N}
+% \begin{macro}[aux]{\str_aux_octal_test:NTF}
% This test is used when reading octal digits, for
% some conversion functions. It returns \meta{true} if the
% token is an octal digit, and \meta{false} otherwise.
@@ -1193,7 +1286,8 @@
% and in the regular expression module to go through the regular expression
% once before actually parsing it. The goal in that case is to turn any
% character with a meaning in regular expressions (\texttt{*}, \texttt{?},
-% \texttt{\{}, etc.) into a marker indicating that this was a special character,
+% \texttt{\{}, etc.) into a marker indicating that this was a special
+% character,
% and replace any escaped character by the corresponding unescaped character,
% so that the \pkg{l3regex} code can avoid caring about escaping issues
% (those can become quite complex to handle in combination with ranges
@@ -1201,7 +1295,7 @@
%
% The idea is to feed unescaped characters to one function,
% escaped characters to another, and feed |\a|, |\e|, |\f|,
-% |\n|, |\r|, |\t| and |\x| converted to the approriate
+% |\n|, |\r|, |\t| and |\x| converted to the appropriate
% character to a third function. Spaces are ignored unless
% escaped.
% For the \cs{str_(g)input:Nn} application, all the functions are simply
@@ -1245,7 +1339,7 @@
\cs_set_nopar:Npn \str_aux_escape_unescaped:N { #1 }
\cs_set_nopar:Npn \str_aux_escape_escaped:N { #2 }
\cs_set_nopar:Npn \str_aux_escape_raw:N { #3 }
- \int_set:Nn \tex_escapechar:D {92}
+ \int_set:Nn \tex_escapechar:D { 92 }
\tl_gset:Nx \g_str_result_tl { \tl_to_other_str:n {#4} }
\tl_gset:Nx \g_str_result_tl
{
@@ -1278,9 +1372,11 @@
% \begin{macro}[aux]+\str_aux_escape_\q_recursion_tail:w+
% \begin{macro}[aux]+\str_aux_escape_/\q_recursion_tail:w+
% \begin{macro}[aux]+\str_aux_escape_ :w+
-% \begin{macro}[aux]{
+% \begin{macro}[aux]
+% {
% \str_aux_escape_/a:w, \str_aux_escape_/e:w, \str_aux_escape_/f:w,
-% \str_aux_escape_/n:w, \str_aux_escape_/r:w, \str_aux_escape_/t:w}
+% \str_aux_escape_/n:w, \str_aux_escape_/r:w, \str_aux_escape_/t:w
+% }
% The loop is ended upon seeing \cs{q_recursion_tail}.
% Spaces are ignored, and |\a|, |\e|, |\f|, |\n|, |\r|, |\t| take
% their meaning here.
@@ -1396,12 +1492,6 @@
}
}
\group_end:
-\msg_new:nnn { str } { x-missing-brace }
- {
- You~wrote~something~like~
- `\iow_char:N\\x\{ \int_to_hexadecimal:n { \l_str_char_int }'.~
- The~closing~brace~is~missing.
- }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1411,21 +1501,21 @@
% \end{macro}
% \end{macro}
%
-% \subsubsection{Escape and unescape strings for pdf use}
+% \subsubsection{Escape and unescape strings for PDF use}
%
% \begin{macro}{\str_aux_convert_store:}
% \begin{macro}{\str_aux_convert_store:NNn}
% \begin{macrocode}
\group_begin:
- \char_set_catcode_other:n {`\^^@}
+ \char_set_catcode_other:n { `\^^@ }
\cs_new_protected_nopar:Npn \str_aux_convert_store:
{
- \char_set_lccode:nn {\c_zero} {\l_str_char_int}
+ \char_set_lccode:nn { \c_zero } { \l_str_char_int }
\tl_to_lowercase:n { \tl_gput_right:Nx \g_str_result_tl {^^@} }
}
\cs_new_protected_nopar:Npn \str_aux_convert_store:NNn #1#2#3
{
- \char_set_lccode:nn {\c_zero} {#3}
+ \char_set_lccode:nn { \c_zero } {#3}
\tl_to_lowercase:n { #1 #2 {^^@} }
}
\group_end:
@@ -1438,7 +1528,7 @@
% \begin{macrocode}
\cs_new_nopar:Npn \str_aux_byte_to_hexadecimal:N #1
{
- \int_compare:nNnTF {`#1} < {256}
+ \int_compare:nNnTF {`#1} < { 256 }
{
\int_to_letter:n { \int_div_truncate:nn {`#1} \c_sixteen }
\int_to_letter:n { \int_mod:nn {`#1} \c_sixteen }
@@ -1447,14 +1537,14 @@
}
\cs_new_nopar:Npn \str_aux_byte_to_octal:N #1
{
- \int_compare:nNnTF {`#1} < {64}
+ \int_compare:nNnTF {`#1} < { 64 }
{
0
\int_to_letter:n { \int_div_truncate:nn {`#1} \c_eight }
\int_to_letter:n { \int_mod:nn {`#1} \c_eight }
}
{
- \int_compare:nNnTF {`#1} < {256}
+ \int_compare:nNnTF {`#1} < { 256 }
{ \int_to_octal:n {`#1} }
{ \msg_expandable_error:n { Invalid~byte~`#1'. } }
}
@@ -1476,7 +1566,7 @@
% \begin{macro}{\str_bytes_escape_name:NN}
% \begin{macrocode}
\tl_const:Nx \c_str_bytes_escape_name_str
- { \c_hash_str \c_percent_str \c_lbrace_str \c_rbrace_str () /<>[] }
+ { \c_hash_str \c_percent_str \c_lbrace_str \c_rbrace_str ()/<>[] }
\cs_new_protected_nopar:Npn \str_bytes_escape_name:NN #1#2
{
\str_set:Nx #1
@@ -1484,10 +1574,10 @@
}
\cs_new_nopar:Npn \str_bytes_escape_name_aux:N #1
{
- \int_compare:nNnTF {`#1} < {"21}
+ \int_compare:nNnTF {`#1} < { "21 }
{ \c_hash_str \str_aux_byte_to_hexadecimal:N #1 }
{
- \int_compare:nNnTF {`#1} > {"7E}
+ \int_compare:nNnTF {`#1} > { "7E }
{ \c_hash_str \str_aux_byte_to_hexadecimal:N #1 }
{
\str_if_contains_char:NNTF \c_str_bytes_escape_name_str #1
@@ -1501,7 +1591,7 @@
%
% \begin{macro}{\str_bytes_escape_string:NN}
% Any character below (and including) space, and any character
-% above (anc including) \texttt{del}, are converted to octal.
+% above (and including) \texttt{del}, are converted to octal.
% One backslash is added before each parenthesis and backslash.
% \begin{macrocode}
\tl_const:Nx \c_str_bytes_escape_string_str { \c_backslash_str ( ) }
@@ -1512,10 +1602,10 @@
}
\cs_new_nopar:Npn \str_bytes_escape_string_aux:N #1
{
- \int_compare:nNnTF {`#1} < {"21}
+ \int_compare:nNnTF {`#1} < { "21 }
{ \c_backslash_str \str_aux_byte_to_octal:N #1 }
{
- \int_compare:nNnTF {`#1} > {"7E}
+ \int_compare:nNnTF {`#1} > { "7E }
{ \c_backslash_str \str_aux_byte_to_octal:N #1 }
{
\str_if_contains_char:NNT \c_str_bytes_escape_string_str #1
@@ -1639,7 +1729,7 @@
% If followed by an end-of-line character, the backslash and
% the end-of-line are ignored. If followed by anything else,
% the backslash is ignored.
-% The pdf specification indicates that LF, CR, and CRLF should be
+% The PDF specification indicates that LF, CR, and CRLF should be
% converted to LF: \emph{this is not implemented here}.
% \begin{macrocode}
\group_begin:
@@ -1671,16 +1761,16 @@
{
\prg_case_str:xxn {#2}
{
- {n} {10}
- {r} {13}
- {t} {9}
- {b} {8}
- {f} {12}
- {(} {40}
- {)} {41}
- {\c_backslash_str} {92}
- {^^J} {-1}
- {^^M} {-1}
+ { n } { 10 }
+ { r } { 13 }
+ { t } { 9 }
+ { b } { 8 }
+ { f } { 12 }
+ { ( } { 40 }
+ { ) } { 41 }
+ { \c_backslash_str } { 92 }
+ { ^^J } { -1 }
+ { ^^M } { -1 }
}
{`#2}
}
@@ -1727,14 +1817,14 @@
}
\cs_new_nopar:Npn \str_bytes_percent_encode_aux:N #1
{
- \int_compare:nNnTF {`#1} < {"41}
+ \int_compare:nNnTF {`#1} < { "41 }
{
\str_if_contains_char:NNTF \c_str_bytes_percent_encode_not_str #1
{ #1 }
{ \c_percent_str \str_aux_byte_to_hexadecimal:N #1 }
}
{
- \int_compare:nNnTF {`#1} > {"7E}
+ \int_compare:nNnTF {`#1} > { "7E }
{ \c_percent_str \str_aux_byte_to_hexadecimal:N #1 }
{
\str_if_contains_char:NNTF \c_str_bytes_percent_encode_str #1
@@ -1798,6 +1888,14 @@
% \subsubsection{UTF-8 support}
%
% \begin{macro}{\str_native_from_UTF_viii:NN}
+% \begin{macro}[aux]
+% {
+% \str_native_from_UTF_viii_aux_i:N,
+% \str_native_from_UTF_viii_aux_ii:nN,
+% \str_native_from_UTF_viii_aux_iii:N,
+% \str_native_from_UTF_viii_aux_iv:,
+% \str_native_from_UTF_viii_aux_v:
+% }
% \begin{macrocode}
\cs_new_protected_nopar:Npn \str_native_from_UTF_viii:NN #1#2
{
@@ -1812,19 +1910,18 @@
\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_i:N #1
{
\quark_if_recursion_tail_stop:N #1
- \int_set:Nn \l_str_char_int { `#1 }
- \str_native_from_UTF_viii_aux_ii:nN {128} \c_one
- \str_native_from_UTF_viii_aux_ii:nN {64} \c_zero
- \str_native_from_UTF_viii_aux_ii:nN {32} \c_two
- \str_native_from_UTF_viii_aux_ii:nN {16} \c_three
- \str_native_from_UTF_viii_aux_ii:nN {8} \c_four
+ \int_set:Nn \l_str_char_int {`#1}
+ \str_native_from_UTF_viii_aux_ii:nN { 128 } \c_one
+ \str_native_from_UTF_viii_aux_ii:nN { 64 } \c_zero
+ \str_native_from_UTF_viii_aux_ii:nN { 32 } \c_two
+ \str_native_from_UTF_viii_aux_ii:nN { 16 } \c_three
+ \str_native_from_UTF_viii_aux_ii:nN { 8 } \c_four
\msg_error:nnx { str } { utf8-invalid-byte } {#1}
\use_i:nnn \str_native_from_UTF_viii_aux_i:N
\q_stop
\str_native_from_UTF_viii_aux_iii:N
}
-\cs_new_protected_nopar:Npn
- \str_native_from_UTF_viii_aux_ii:nN #1#2
+\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_ii:nN #1#2
{
\int_compare:nNnTF \l_str_char_int < {#1}
{
@@ -1833,8 +1930,7 @@
}
{ \int_sub:Nn \l_str_char_int {#1} }
}
-\cs_new_protected_nopar:Npn
- \str_native_from_UTF_viii_aux_iii:N #1
+\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_iii:N #1
{
\int_compare:nNnTF \l_str_bytes_int < \c_two
{ \str_native_from_UTF_viii_aux_iv: #1 }
@@ -1844,11 +1940,11 @@
\exp_after:wN \use_none_delimit_by_q_recursion_stop:w
\fi:
\quark_if_recursion_tail_stop:N #1
- \tex_multiply:D \l_str_char_int by 64 \scan_stop: % no interface??
+ \tex_multiply:D \l_str_char_int by 64 \scan_stop:
\int_decr:N \l_str_bytes_int
- \int_compare:nNnTF {`#1} < {128}
+ \int_compare:nNnTF {`#1} < { 128 }
{ \use_ii:nn }
- { \int_compare:nNnTF {`#1} < {192} }
+ { \int_compare:nNnTF {`#1} < { 192 } }
{
\int_add:Nn \l_str_char_int { `#1 - 128 }
\str_native_from_UTF_viii_aux_iii:N
@@ -1859,49 +1955,35 @@
}
}
}
-\cs_new_protected_nopar:Npn
- \str_native_from_UTF_viii_aux_iv:
+\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_iv:
{
\int_compare:nNnTF \l_str_bytes_int = \c_zero
{
\msg_error:nnx { str } { utf8-extra-byte }
{ \int_eval:n { \l_str_char_int + 128 } }
}
+ { \str_native_from_UTF_viii_aux_v: }
+ \str_native_from_UTF_viii_aux_i:N
+ }
+\pdftex_if_engine:TF
+ {
+ \cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_v:
{
- \pdftex_if_engine:TF
+ \int_compare:nNnTF { \l_str_char_int } < { 256 }
+ { \str_aux_convert_store: }
{
- \int_compare:nNnTF { \l_str_char_int } < { 256 }
- { \str_aux_convert_store: }
- {
- \msg_error:nnx { str } { utf8-pdftex-overflow }
- { \int_use:N \l_str_char_int }
- }
+ \msg_error:nnx { str } { utf8-pdftex-overflow }
+ { \int_use:N \l_str_char_int }
}
- { \str_aux_convert_store: }
}
- \str_native_from_UTF_viii_aux_i:N
- }
-\msg_new:nnn { str } { utf8-invalid-byte }
- {
- \int_compare:nNnTF {`#1} < {256}
- { Byte~number~\int_eval:n {`#1}~invalid~in~utf-8~encoding. }
- { The~character~number~\int_eval:n {`#1}~is~not~a~byte. }
}
-\msg_new:nnn { str } { utf8-missing-byte }
- { The~byte~number~\int_eval:n {`#1}~is~not~a~valid~continuation~byte. }
-\msg_new:nnn { str } { utf8-extra-byte }
- { The~byte~number~\int_eval:n {`#1}~is~only~valid~as~a~continuation~byte. }
-\msg_new:nnnn { str } { utf8-premature-end }
- { Incomplete~last~utf8~character. }
{
- The~sequence~of~byte~that~I~need~to~convert~to~utf8 \
- ended~before~the~last~character~was~complete.~Perhaps \
- it~was~mistakenly~truncated?
+ \cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_v:
+ { \str_aux_convert_store: }
}
-\msg_new:nnn { str } { utf8-pdftex-overflow }
- { The~character~number~#1~is~too~big~for~pdfTeX. }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\str_UTF_viii_from_native:NN}
% \begin{macrocode}
@@ -1916,14 +1998,14 @@
\cs_new_protected_nopar:Npn \str_UTF_viii_from_native_aux_i:N #1
{
\int_set:Nn \l_str_char_int {`#1}
- \int_compare:nNnTF \l_str_char_int < {128}
+ \int_compare:nNnTF \l_str_char_int < { 128 }
{ \tl_gput_right:Nx \g_str_result_tl {#1} }
{
\tl_gclear:N \g_str_tmpa_tl
\int_set:Nn \l_str_bytes_int { 64 }
- \str_UTF_viii_from_native_aux_ii:n {32}
- \str_UTF_viii_from_native_aux_ii:n {16}
- \str_UTF_viii_from_native_aux_ii:n {8}
+ \str_UTF_viii_from_native_aux_ii:n { 32 }
+ \str_UTF_viii_from_native_aux_ii:n { 16 }
+ \str_UTF_viii_from_native_aux_ii:n { 8 }
\ERROR % somehow the unicode char was > "1FFFFF > "10FFFF
\tl_gclear:N \g_str_tmpa_tl
\use_none:n \q_stop
@@ -1936,29 +2018,60 @@
{
\str_aux_convert_store:NNn
\tl_gput_left:Nx \g_str_tmpa_tl
- { 128 + \int_mod:nn { \l_str_char_int } {64} }
- \tex_divide:D \l_str_char_int by 64 \scan_stop: % no interface??
+ { 128 + \int_mod:nn { \l_str_char_int } { 64 } }
+ \tex_divide:D \l_str_char_int by 64 \scan_stop:
\int_add:Nn \l_str_bytes_int {#1}
\int_compare:nNnT \l_str_char_int < {#1}
{ \use_none_delimit_by_q_stop:w }
}
% \end{macrocode}
% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macrocode}
+\msg_new:nnnn { str } { x-missing-brace }
+ { Missing~closing~brace~in~ \token_to_str:N \x ~byte~sequence. }
+ {
+ You~wrote~something~like~
+ `\iow_char:N\\x\{ \int_to_hexadecimal:n { \l_str_char_int }'.~
+ The~closing~brace~is~missing.
+ }
+\msg_new:nnn { str } { utf8-invalid-byte }
+ {
+ \int_compare:nNnTF {`#1} < { 256 }
+ { Byte~number~ \int_eval:n {`#1} ~invalid~in~utf-8~encoding. }
+ { The~character~number~ \int_eval:n {`#1} ~is~not~a~byte. }
+ }
+\msg_new:nnn { str } { utf8-missing-byte }
+ { The~byte~number~ \int_eval:n {`#1} ~is~not~a~valid~continuation~byte. }
+\msg_new:nnn { str } { utf8-extra-byte }
+ { The~byte~number~ \int_eval:n {`#1} ~is~only~valid~as~a~continuation~byte. }
+\msg_new:nnnn { str } { utf8-premature-end }
+ { Incomplete~last~UTF8~character. }
+ {
+ The~sequence~of~byte~that~to~be~converted~to~UTF8~
+ ended~before~the~last~character~was~complete.~Perhaps~
+ it~was~mistakenly~truncated?
+ }
+\msg_new:nnn { str } { utf8-pdftex-overflow }
+ { The~character~number~#1~is~too~big~for~pdfTeX. }
+% \end{macrocode}
%
% \subsection{Deprecated string functions}
%
-% \begin{macro}{\str_length_skip_spaces:N,\str_length_skip_spaces:n}
+% \begin{macro}{\str_length_skip_spaces:N, \str_length_skip_spaces:n}
% The naming scheme is a little bit more consistent
% with \enquote{ignore_spaces} instead of \enquote{skip_spaces}.
% \begin{macrocode}
-\cs_gset:Npn \str_length_skip_spaces:N
+\cs_set:Npn \str_length_skip_spaces:N
{ \exp_args:No \str_length_skip_spaces:n }
-\cs_gset_eq:NN \str_length_skip_spaces:n \str_length_ignore_spaces:n
+\cs_set_eq:NN \str_length_skip_spaces:n \str_length_ignore_spaces:n
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
-%</package>
+%</initex|package>
% \end{macrocode}
%
% \end{implementation}