diff options
author | Karl Berry <karl@freefriends.org> | 2012-01-19 22:49:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-01-19 22:49:25 +0000 |
commit | 8764984f07460a77b8200111ddb513c8af6c23f3 (patch) | |
tree | 61782419c00b217fc7f14919b9e24bbae260274f /Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx | |
parent | 17d590a6bcf898806aeec2d7aa57d641a440ca10 (diff) |
l3experimental 3209 (19jan12)
git-svn-id: svn://tug.org/texlive/trunk@25158 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx | 298 |
1 files changed, 162 insertions, 136 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx index a33d4909a1a..cddd7349adc 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3str.dtx Copyright (C) 2011 The LaTeX3 Project +%% File: l3str.dtx Copyright (C) 2011-2012 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 @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{expl3} -\GetIdInfo$Id: l3str.dtx 3088 2011-12-23 02:00:14Z bruno $ +\GetIdInfo$Id: l3str.dtx 3159 2012-01-09 00:51:58Z bruno $ {L3 Experimental Strings} %</driver|package> %<*driver> @@ -67,6 +67,7 @@ % % \maketitle % +% \newcommand{\hexnum}[1]{\text{\texttt{\char`\"}#1}} % \begin{documentation} % % \LaTeX3 provides a set of functions to manipulate token lists @@ -106,7 +107,7 @@ % \c_percent_str % } % Constant strings, containing a single character, with category code $12$. -% Other characters can be accessed as \cs{iow_char:N} |\|\meta{character}. +% Any character can be accessed as \cs{iow_char:N} |\|\meta{character}. % \end{variable} % % \begin{function}[EXP]{\tl_to_str:N, \tl_to_str:n} @@ -116,6 +117,16 @@ % \end{syntax} % Converts the \meta{token list} to a \meta{string}, leaving the resulting % tokens in the input stream. +% \begin{texnote} +% The string representation of a token list may depend +% on the category codes in effect when it is measured, +% and the value of the \tn{escapechar}: for instance +% |\tl_to_str:n {\a}| may produce $1$, $2$ or $3$ +% characters depending on the escape character, and +% the category code of \texttt{a}. This impacts almost +% all functions in the module, which use \cs{tl_to_str:n} +% internally. +% \end{texnote} % \end{function} % % \begin{function}{\str_const:Nn, \str_const:Nx, \str_const:cn, \str_const:cx} @@ -191,16 +202,16 @@ % (an arbitrary number of hexadecimal digits are read): % this is mostly useful for Unicode-aware engines. % \item |\a|, |\e|, |\f|, |\n|, |\r|, |\t| stand for specific characters: -% \begin{center} -% \begin{tabular}{cccc} -% |\a| & |\^^G| & alarm & hex \texttt{07} \\ -% |\e| & |\^^[| & escape & hex \texttt{1B} \\ -% |\f| & |\^^L| & form feed & hex \texttt{0C} \\ -% |\n| & |\^^J| & new line & hex \texttt{0A} \\ -% |\r| & |\^^M| & carriage return & hex \texttt{0D} \\ -% |\t| & |\^^I| & horizontal tab & hex \texttt{09} \\ -% \end{tabular} -% \end{center} +% \begin{center} +% \begin{tabular}{cccc} +% |\a| & |\^^G| & alarm & hex \texttt{07} \\ +% |\e| & |\^^[| & escape & hex \texttt{1B} \\ +% |\f| & |\^^L| & form feed & hex \texttt{0C} \\ +% |\n| & |\^^J| & new line & hex \texttt{0A} \\ +% |\r| & |\^^M| & carriage return & hex \texttt{0D} \\ +% |\t| & |\^^I| & horizontal tab & hex \texttt{09} \\ +% \end{tabular} +% \end{center} % \end{itemize} % For instance, % \begin{quote} @@ -226,13 +237,6 @@ % all characters including spaces are counted. % 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, -% and the value of the \tn{escapechar}: for instance -% |\str_length:n {\a}| may return $1$, $2$ or $3$ depending -% on the escape character, and the category code of \texttt{a}. -% \end{texnote} % \end{function} % % \begin{function}[EXP]{\str_head:N, \str_head:n, \str_head_ignore_spaces:n} @@ -262,8 +266,11 @@ % 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} trims +% 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} @@ -432,14 +439,14 @@ % by converting each character in the string \texttt{Hello!} % to the \textsc{utf-16} encoding, and expressing each byte % as a pair of hexadecimal digits. Note the presence of a -% (big-endian) byte order mark \texttt{FEFF}, which can be +% (big-endian) byte order mark \hexnum{FEFF}, which can be % avoided by specifying the encoding \texttt{utf16be/hex}. % % Parts of the \meta{string} which cannot be converted to bytes % using the \meta{escaping 1} are silently ignored (including non-byte % characters which could be present in the string). % Sequences of bytes which are not valid in the \meta{encoding 1} -% are converted to the replacement character |"FFFD|, and raise +% are converted to the replacement character \hexnum{FFFD}, and raise % an error. % Characters which cannot be encoded in the \meta{encoding 2} % are silently ignored. @@ -478,7 +485,7 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % If the \meta{token} is a hexdecimal digit (upper case or lower case), -% its upper-case version is left in the input strem, \emph{followed} +% its upper-case version is left in the input stream, \emph{followed} % by the \meta{true code}. Otherwise, the \meta{false code} is left % in the input stream. % \begin{texnote} @@ -552,6 +559,7 @@ % \begin{macrocode} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\RequirePackage{l3tl-analysis} % \end{macrocode} % % Those string-related functions are defined in \pkg{l3kernel}. @@ -669,7 +677,7 @@ % % \begin{variable}{\c_str_replacement_char_int} % When converting, invalid bytes are replaced by the Unicode -% replacement character \textsc{u-fffd}. +% replacement character \hexnum{FFFD}. % \begin{macrocode} \int_const:Nn \c_str_replacement_char_int { "FFFD } % \end{macrocode} @@ -1431,11 +1439,11 @@ { \exp_after:wN \str_aux_gmap_internal_result_loop:Nww \exp_after:wN #1 - \g_str_result_tl \q_mark \q_stop \prg_map_break: , + \g_str_result_tl \s_tl \q_stop \prg_map_break: \s_tl \prg_break_point:n { } } } -\cs_new_nopar:Npn \str_aux_gmap_internal_result_loop:Nww #1#2\q_mark #3, +\cs_new_nopar:Npn \str_aux_gmap_internal_result_loop:Nww #1 #2 \s_tl #3 \s_tl { \use_none_delimit_by_q_stop:w #3 \q_stop #1 {#3} @@ -1982,19 +1990,20 @@ \use_none_delimit_by_q_stop:w #1 \q_stop \tex_dimen:D "#1 = \l_str_tmpa_int sp \scan_stop: \tex_skip:D \l_str_tmpa_int = "#1 sp \scan_stop: - \tex_toks:D \l_str_tmpa_int \exp_after:wN { \int_value:w "FFFD } + \tex_toks:D \l_str_tmpa_int \exp_after:wN + { \int_use:N \c_str_replacement_char_int } \tex_advance:D \l_str_tmpa_int \c_one \str_convert_from_eight_bit_load_missing:n } \cs_new:Npn \str_convert_from_eight_bit_aux:N #1 { - #1 \exp_not:N \q_mark + #1 \s_tl \if_num:w \tex_dimen:D `#1 < \l_str_tmpa_int \if_num:w \tex_skip:D \tex_dimen:D `#1 = `#1 \exp_stop_f: \tex_the:D \tex_toks:D \tex_dimen:D \fi: \fi: - \int_value:w `#1 , + \int_value:w `#1 \s_tl } % \end{macrocode} % \end{macro} @@ -2031,7 +2040,10 @@ } \cs_new:Npn \str_convert_to_eight_bit_aux:n #1 { - \if_num:w #1 < "8000 \exp_stop_f: + \if_num:w #1 > \c_max_register_int + \msg_expandable_kernel_error:nnn + { str } { eight-bit-to-byte-overflow } {#1} + \else: \if_num:w \tex_dimen:D #1 < \l_str_tmpa_int \if_num:w \tex_skip:D \tex_dimen:D #1 = #1 \exp_stop_f: \tex_the:D \tex_toks:D \tex_dimen:D #1 \exp_stop_f: @@ -2039,9 +2051,6 @@ \fi: \fi: \str_convert_to_eight_bit_aux_ii:n {#1} - \else: - \msg_expandable_kernel_error:nnn - { str } { eight-bit-to-byte-overflow } {#1} \fi: } \cs_new:Npn \str_convert_to_eight_bit_aux_ii:n #1 @@ -2145,7 +2154,7 @@ \cs_new_protected_nopar:Npn \str_convert_from_native: { \str_aux_gmap_result:N \str_convert_from_native_aux:N } \cs_new:Npn \str_convert_from_native_aux:N #1 - { #1 \exp_not:N \q_mark \int_value:w `#1 , } + { #1 \s_tl \int_value:w `#1 \s_tl } % \end{macrocode} % \end{macro} % \end{macro} @@ -2169,10 +2178,10 @@ \str_aux_convert_to_native:n { \exp_after:wN \str_convert_to_native_aux:w - \l_str_tmpa_tl \q_mark { \q_stop \prg_map_break: } , + \l_str_tmpa_tl \s_tl { \q_stop \prg_map_break: } \s_tl } } -\cs_new_protected_nopar:Npn \str_convert_to_native_aux:w #1\q_mark #2, +\cs_new_protected_nopar:Npn \str_convert_to_native_aux:w #1 \s_tl #2 \s_tl { \use_none_delimit_by_q_stop:w #2 \q_stop \str_aux_convert_to_native_step:n {#2} @@ -2294,6 +2303,8 @@ { Overlong~UTF-8~byte~sequence~for~code~point~#1. } \msg_kernel_new:nnn { str } { utf8-premature-end } { Incomplete~last~UTF-8~character. } +\msg_kernel_new:nnn { str } { utf8-overflow } + { Code~point~#1~too~large~(UTF-8). } \msg_kernel_new:nnn { str } { utf32-overflow } { Code~point~too~large~(UTF-32~`#1'). } \msg_kernel_new:nnn { str } { utf32-truncated } @@ -2584,7 +2595,7 @@ % \begin{variable}{\c_str_convert_output_name_not_str} % For each byte, test whether it should % be output as is, or be \enquote{hash-encoded}. -% Roughly, bytes outside the range from |"2A| to |"7E| +% Roughly, bytes outside the range $[\hexnum{2A},\hexnum{7E}]$ % are hash-encoded. We keep two lists of exceptions: % characters in \cs{c_str_convert_output_name_not_str} % are not hash-encoded, and characters in the @@ -2767,22 +2778,21 @@ % \begin{macro}[aux, rEXP] % { % \str_aux_from_utf_viii:N, -% \str_aux_from_utf_viii:wwNN, -% \str_aux_from_utf_viii:wNNww +% \str_aux_from_utf_viii:wwN, +% \str_aux_from_utf_viii:wNnnwN % } % \begin{macro}[aux, rEXP] % { -% \str_aux_from_utf_viii_error:w, -% \str_aux_from_utf_viii_error:NwNN, +% \str_aux_from_utf_viii_overflow:w , % \str_aux_from_utf_viii_error: % } -% In the \textsc{utf-8} encoding, bytes in the range $[0,127]$ stand -% for themselves, bytes in the range $[128,191]$ are continuation bytes, +% In the \textsc{utf-8} encoding, bytes in the range +% $[0,\hexnum{7F}]$ stand for themselves, bytes in the range +% $[\hexnum{80},\hexnum{BF}]$ are continuation bytes, % and larger bytes must be followed by a number of continuation bytes. % Documentation to come. % ^^A todo: refuse "D800 -- "DFFF? % ^^A todo: document -% ^^A todo: what error recovery for code points > "10FFFF? % \begin{macrocode} \cs_new_protected_nopar:cpn { str_convert_from_utf8: } { @@ -2797,7 +2807,7 @@ { #1 \if_num:w `#1 < "C0 \exp_stop_f: - \exp_not:N \q_mark + \s_tl \if_num:w `#1 < "80 \exp_stop_f: \int_value:w `#1 \else: @@ -2807,71 +2817,73 @@ \fi: \else: \if_num:w `#1 < "F5 \exp_stop_f: - \exp_after:wN \str_aux_from_utf_viii:wwNN - \int_use:N \int_eval:w `#1 - "C0 + \exp_after:wN \str_aux_from_utf_viii:wwN + \int_value:w \int_eval:n { `#1 - "C0 } \else: - \exp_not:N \q_mark + \s_tl \msg_expandable_kernel_error:nnn { str } { utf8-invalid-byte } {#1} \int_use:N \c_str_replacement_char_int \fi: \fi: - , - \use_none_delimit_by_q_stop:w - "80 , "800 , "10000 , "10FFFF , - \q_stop + \s_tl + \use_none_delimit_by_q_stop:w {"80} {"800} {"10000} {"110000} \q_stop \str_aux_from_utf_viii:N } -\cs_new_nopar:Npn \str_aux_from_utf_viii:wwNN #1 , #2 \q_stop #3#4 +\cs_new_nopar:Npn \str_aux_from_utf_viii:wwN + #1 \s_tl #2 \str_aux_from_utf_viii:N #3 { - \use_none:n #4 - \exp_after:wN \str_aux_from_utf_viii:wNNww - \int_use:N \int_eval:w #1 * "40 + `#4 - "80 , - #4 - #2 - \q_stop #3 + \use_none:n #3 + \if_num:w \int_eval:w ( `#3 + "20 ) / "40 = \c_three + #3 + \exp_after:wN \str_aux_from_utf_viii:wNnnwN + \int_value:w \int_eval:n { #1 * "40 + `#3 - "80 } + \else: + \s_tl + \msg_expandable_kernel_error:nnn + { str } { utf8-missing-conti } {#3} + \int_use:N \c_str_replacement_char_int + \fi: + \s_tl + #2 + \str_aux_from_utf_viii:N #3 } -\cs_new_nopar:Npn \str_aux_from_utf_viii:wNNww #1, #2 #3#4, #5, +\cs_new_nopar:Npn \str_aux_from_utf_viii:wNnnwN + #1 \s_tl #2#3#4 #5 \str_aux_from_utf_viii:N #6 { - \if_num:w \int_eval:w ( `#2 + \c_thirty_two ) / "40 = \c_three - \if_num:w #1 < #4 \exp_stop_f: - \str_aux_from_utf_viii_error:w #1 , + \if_num:w #1 < #4 + \s_tl + \if_num:w #1 < #3 \exp_stop_f: + \msg_expandable_kernel_error:nnn + { str } { utf8-overlong } {#1} + \int_use:N \c_str_replacement_char_int \else: - #2 - \if_num:w #1 < #5 \exp_stop_f: - \exp_not:N \q_mark #1 - \else: - \exp_after:wN \str_aux_from_utf_viii:wwNN - \int_use:N \int_eval:w #1 - #5 - \fi: + #1 \fi: \else: - \exp_after:wN \str_aux_from_utf_viii_error:NwN - \exp_after:wN #2 + \if_meaning:w \q_stop #5 + \str_aux_from_utf_viii_overflow:w #1 + \fi: + \exp_after:wN \str_aux_from_utf_viii:wwN + \int_value:w \int_eval:n { #1 - #4 } \fi: - , #3#5, - } -\cs_new_nopar:Npn \str_aux_from_utf_viii_error:w #1 , - { - \exp_not:N \q_mark - \msg_expandable_kernel_error:nnn - { str } { utf8-overlong } {#1} - \c_str_replacement_char_int + \s_tl + #2 {#4} #5 + \str_aux_from_utf_viii:N } -\cs_new_nopar:Npn \str_aux_from_utf_viii_error:NwN #1 #2 \q_stop #3 +\cs_new_nopar:Npn \str_aux_from_utf_viii_overflow:w #1 \fi: #2 \fi: { - \exp_not:N \q_mark + \fi: \fi: \msg_expandable_kernel_error:nnn - { str } { utf8-missing-conti } {#1} - \c_str_replacement_char_int , - #3#1 + { str } { utf8-overflow } {#1} + \int_use:N \c_str_replacement_char_int } \cs_new_nopar:Npn \str_aux_from_utf_viii_error: { - \exp_not:N \q_mark + \s_tl \msg_expandable_kernel_error:nn { str } { utf8-premature-end } - \c_str_replacement_char_int , + \int_use:N \c_str_replacement_char_int \s_tl \prg_map_break: } % \end{macrocode} @@ -3018,19 +3030,32 @@ % \end{macro} % % \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi:NN} -% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi:wNNN} -% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi_error:wNNw} +% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi:NNwNNN} % \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi_end:Nw} -% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi_end:wNNww} +% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi_error:NNw} +% \begin{macro}[aux, rEXP]{\str_aux_from_utf_xvi_error:NNN} % When \cs{str_aux_from_utf_xvi:NN} is called, \cs{str_tmp:w} % is such that |\str_tmp:w #1#2| expands to |`#1| if the string % is big-endian, and |`#2| if the string is little-endian. -% If the most significant byte is between |"D8| and |"DB| -% inclusive, then the pair of bytes is a high surrogate, -% and we fetch the following pair, which must be a low surrogate, -% \emph{i.e.}, between |"DC| and |"DF| inclusive. -% Unpaired surrogates are errors, handled with -% \cs{str_aux_from_utf_xvi_error:wNNw}. +% If the code unit (a pair of characters) does not represent +% a surrogate, the \cs{if_case:w} construction expands to nothing, +% and we leave in the input stream \meta{characters} \cs{s_tl} +% \meta{char code} \cs{s_tl}, and move on to the next code unit. +% When the end is found, we check for the case of an odd-length +% string (an error) and end the mapping. +% +% Surrogates are characterized by a most significant byte in the +% ranges $[\hexnum{D8},\hexnum{DB}]$ and $[\hexnum{DC},\hexnum{DF}]$, +% detected by dividing the character code by $4$ (\eTeX{} rounds to +% nearest, ties away from zero). Here, a trail surrogate is invalid, +% replaced by the replacement character. Lead surrogates are treated by +% \cs{str_aux_from_utf_xvi:NNwNNN}, which grabs the next two +% characters, checks for a premature end, and checks whether +% the code unit is a trailing surrogate. If it is, leave +% \meta{characters} \cs{s_tl} \meta{char code} \cs{s_tl} in the +% input stream and move on to the next code unit. Otherwise, raise +% an error, and continue parsing, replacing only the first code unit +% (the leading surrogate) by the replacement character. % \begin{macrocode} \cs_new:Npn \str_aux_from_utf_xvi:NN #1#2 { @@ -3039,60 +3064,63 @@ \fi: \if_case:w \int_eval:w ( \str_tmp:w #1#2 - "D6 ) / \c_four \int_eval_end: - \or: #1#2 \exp_after:wN \str_aux_from_utf_xvi:wNNN - \or: \exp_after:wN \str_aux_from_utf_xvi_error:wNNw - \else: #1#2 \exp_not:N \q_mark \int_use:N \int_eval:w + \or: \exp_after:wN \str_aux_from_utf_xvi:NNwNNN + \or: \exp_after:wN \str_aux_from_utf_xvi_error:NNw \fi: - "100 * \str_tmp:w #1#2 + \str_tmp:w #2#1 , + #1#2 \s_tl + \int_eval:n { "100 * \str_tmp:w #1#2 + \str_tmp:w #2#1 } \s_tl \str_aux_from_utf_xvi:NN } - \cs_new:Npn \str_aux_from_utf_xvi:wNNN #1, #2#3#4 + \cs_new:Npn \str_aux_from_utf_xvi:NNwNNN #1#2 \s_tl #3 \s_tl #4#5#6 { - \if_meaning:w \scan_stop: #4 - \str_aux_from_utf_xvi_end:wNNww #1 , #3 + \if_meaning:w \scan_stop: #6 + \str_aux_from_utf_xvi_error:NNN #1#2#5 \fi: - \if_num:w \int_eval:w ( \str_tmp:w #3#4 - "DA ) / \c_four = \c_one - #3 #4 - \int_use:N \int_eval:w - ( #1 - "D800 ) * "400 - + \str_tmp:w #3#4 * "100 + \str_tmp:w #4#3 - "DC00 , + \if_num:w \int_eval:w ( \str_tmp:w #5#6 - "DA ) / \c_four = \c_one + #1 #2 #5 #6 \s_tl + \int_eval:n + { + ( "100 * \str_tmp:w #1#2 + \str_tmp:w #2#1 - "D800 ) * "400 + + "100 * \str_tmp:w #4#5 + \str_tmp:w #5#4 - "DC00 + } + \s_tl \exp_after:wN \use_i:nnn \else: - \str_aux_from_utf_xvi_error:wNNw #1 , + \str_aux_from_utf_xvi_error:NNw #1#2 \s_tl \s_tl \fi: - #2#3#4 - } - \cs_new:Npn \str_aux_from_utf_xvi_error:wNNw #1 \str_tmp:w #2#3 #4, - { - \exp_not:N \q_mark - \msg_expandable_kernel_error:nnn - { str } { utf16-surrogate } { #2#3 } - \c_str_replacement_char_int , + #4#5#6 } \cs_new:Npn \str_aux_from_utf_xvi_end:Nw #1 \fi: { \fi: \if_meaning:w \scan_stop: #1 \else: - #1 \exp_not:N \q_mark + #1 \s_tl \msg_expandable_kernel_error:nnn { str } { utf16-odd } {#1} - \int_use:N \c_str_replacement_char_int , + \int_use:N \c_str_replacement_char_int \s_tl \fi: \prg_map_break: } - \cs_new:Npn \str_aux_from_utf_xvi_end:wNNww #1 `#2#3 #4, #5 \fi: + \cs_new:Npn \str_aux_from_utf_xvi_error:NNw #1#2 \s_tl #3 \s_tl { - \fi: - \exp_not:N \q_mark - \if_meaning:w \scan_stop: #5 + #1 #2 \s_tl + \msg_expandable_kernel_error:nnn + { str } { utf16-surrogate } { #1#2 } + \int_use:N \c_str_replacement_char_int \s_tl + } + \cs_new:Npn \str_aux_from_utf_xvi_error:NNN #1#2#3 + { + \if_meaning:w \scan_stop: #3 + #1#2 \s_tl \msg_expandable_kernel_error:nnn - { str } { utf16-surrogate } { #2#3 } + { str } { utf16-surrogate } { #1#2 } \else: + #1#2#3 \s_tl \msg_expandable_kernel_error:nnn - { str } { utf16-odd } { #2#3#5 } + { str } { utf16-odd } { #1#2#3 } \fi: - \int_use:N \c_str_replacement_char_int , + \int_use:N \c_str_replacement_char_int \s_tl \prg_map_break: } % \end{macrocode} @@ -3180,7 +3208,7 @@ % \begin{macro}[aux, rEXP] % { % \str_aux_from_utf_xxxii:NNNN, -% \str_aux_from_utf_xxxii_end:ww +% \str_aux_from_utf_xxxii_end:w % } % See the conversion functions from \textsc{utf-16} encodings. % The \cs{str_aux_from_utf_xxxii:No} auxiliary defines @@ -3226,7 +3254,7 @@ \if_meaning:w \scan_stop: #4 \exp_after:wN \str_aux_from_utf_xxxii_end:w \fi: - #1#2#3#4 \exp_not:N \q_mark + #1#2#3#4 \s_tl \if_num:w \int_eval:w \str_tmp:w #1#4 * \c_two_hundred_fifty_six + \str_tmp:w #2#3 @@ -3235,12 +3263,10 @@ { str } { utf32-overflow } { #1#2#3#4 } \int_use:N \c_str_replacement_char_int \else: - \int_use:N \int_eval:w - \str_tmp:w #2#3*"10000 - + \str_tmp:w #3#2 * \c_two_hundred_fifty_six - + \str_tmp:w #4#1 + \int_eval:n + { \str_tmp:w #2#3*"10000 + \str_tmp:w #3#2*"100 + \str_tmp:w #4#1 } \fi: - , + \s_tl \str_aux_from_utf_xxxii:NNNN } \cs_new:Npn \str_aux_from_utf_xxxii_end:w #1 \scan_stop: @@ -3249,8 +3275,8 @@ { \msg_expandable_kernel_error:nnn { str } { utf32-truncated } { #1 } - #1 \exp_not:N \q_mark - \int_use:N \c_str_replacement_char_int , + #1 \s_tl + \int_use:N \c_str_replacement_char_int \s_tl } \prg_map_break: } |