diff options
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3str.dtx')
-rw-r--r-- | macros/latex/contrib/l3kernel/l3str.dtx | 148 |
1 files changed, 118 insertions, 30 deletions
diff --git a/macros/latex/contrib/l3kernel/l3str.dtx b/macros/latex/contrib/l3kernel/l3str.dtx index 897f4b962b..ddfdd10279 100644 --- a/macros/latex/contrib/l3kernel/l3str.dtx +++ b/macros/latex/contrib/l3kernel/l3str.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2022-02-24} +% \date{Released 2022-04-10} % % \maketitle % @@ -222,8 +222,8 @@ % % \section{String conditionals} % -% \begin{function}[EXP,pTF, added = 2015-09-18] -% {\str_if_empty:N, \str_if_empty:c} +% \begin{function}[EXP,pTF, added = 2015-09-18, updated = 2022-03-21] +% {\str_if_empty:N, \str_if_empty:c, \str_if_empty:n} % \begin{syntax} % \cs{str_if_empty_p:N} \meta{str~var} % \cs{str_if_empty:NTF} \meta{str~var} \Arg{true code} \Arg{false code} @@ -282,8 +282,8 @@ % tests whether \meta{string_2} is found inside \meta{string_1}. % \end{function} % -% \begin{function}[added = 2013-07-24, updated = 2015-02-28, EXP, noTF] -% {\str_case:nn, \str_case:Vn, \str_case:on, \str_case:nV, \str_case:nv} +% \begin{function}[added = 2013-07-24, updated = 2022-03-21, EXP, noTF] +% {\str_case:nn, \str_case:Vn, \str_case:Nn, \str_case:on, \str_case:nV, \str_case:nv} % \begin{syntax} % \cs{str_case:nnTF} \Arg{test string} \\ % ~~|{| \\ @@ -747,16 +747,6 @@ % correctly deal with context-dependence and other factors appropriate % to text case changing. % \end{itemize} -% -% \begin{texnote} -% As with all \pkg{expl3} functions, the input supported by -% \cs{str_foldcase:n} is \emph{engine-native} characters which are or -% interoperate with \textsc{utf-8}. As such, when used with \pdfTeX{} -% \emph{only} the Latin alphabet characters A--Z are case-folded -% (\emph{i.e.}~the \textsc{ascii} range which coincides with -% \textsc{utf-8}). Full \textsc{utf-8} support is available with both -% \XeTeX{} and \LuaTeX{}. -% \end{texnote} % \end{function} % % \begin{function}[EXP, added = 2019-11-26] @@ -789,18 +779,6 @@ % a language-insensitive process, there is no special treatment of % Turkic input (\emph{i.e.}~\texttt{I} always folds to \texttt{i} and % not to \texttt{\i}). -% -% \begin{texnote} -% As with all \pkg{expl3} functions, the input supported by -% \cs{str_foldcase:n} is \emph{engine-native} characters which are or -% interoperate with \textsc{utf-8}. As such, when used with \pdfTeX{} -% \emph{only} the Latin alphabet characters A--Z are case-folded -% (\emph{i.e.}~the \textsc{ascii} range which coincides with -% \textsc{utf-8}). Full \textsc{utf-8} support is available with both -% \XeTeX{} and \LuaTeX{}, subject only to the fact that \XeTeX{} in -% particular has issues with characters of code above hexadecimal -% $0\mathrm{xFFFF}$ when interacting with \cs{tl_to_str:n}. -% \end{texnote} % \end{function} % % \section{Viewing strings} @@ -1113,7 +1091,7 @@ % % \begin{macro}[pTF, EXP] % { -% \str_if_empty:N, \str_if_empty:c, +% \str_if_empty:N, \str_if_empty:c, \str_if_empty:n, % \str_if_exist:N, \str_if_exist:c % } % More copy-paste! @@ -1126,6 +1104,8 @@ { p , T , F , TF } \prg_new_eq_conditional:NNn \str_if_empty:c \tl_if_empty:c { p , T , F , TF } +\prg_new_eq_conditional:NNn \str_if_empty:n \tl_if_empty:n + { p , T , F , TF } % \end{macrocode} % \end{macro} % @@ -1224,7 +1204,7 @@ % \end{macro} % % \begin{macro}[EXP, noTF] -% {\str_case:nn, \str_case:Vn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_e:nn} +% {\str_case:nn, \str_case:Vn, \str_case:Nn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_e:nn} % \begin{macro}[EXP]{\@@_case:nnTF, \@@_case_e:nnTF} % \begin{macro}[EXP] % {\@@_case:nw, \@@_case_e:nw, \@@_case_end:nw} @@ -1254,6 +1234,10 @@ \cs_new:Npn \@@_case:nnTF #1#2#3#4 { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop } \cs_generate_variant:Nn \str_case:nn { V , o , nV , nv } +\cs_new_eq:NN \str_case:Nn \str_case:Vn +\cs_new_eq:NN \str_case:NnT \str_case:VnT +\cs_new_eq:NN \str_case:NnF \str_case:VnF +\cs_new_eq:NN \str_case:NnTF \str_case:VnTF \prg_generate_conditional_variant:Nnn \str_case:nn { V , o , nV , nv } { T , F , TF } \cs_new:Npn \@@_case:nw #1#2#3 @@ -1918,10 +1902,21 @@ % \begin{macro}[EXP]{\@@_change_case_loop:nw} % \begin{macro}[EXP]{\@@_change_case_space:n} % \begin{macro}[EXP]{\@@_change_case_char:nN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNN} +% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nNNNN} +% \begin{macro}[EXP] +% { +% \@@_change_case_char_UTFviii:nn , +% \@@_change_case_char_UTFviii_lower:nn , +% \@@_change_case_char_UTFviii_upper:nn , +% \@@_change_case_char_UTFviii_fold:nn +% } % Case changing for programmatic reasons is done by first detokenizing % input then doing a simple loop that only has to worry about spaces % and everything else. The output is detokenized to allow data sharing -% with text-based case changing. +% with text-based case changing. Similarly, for $8$-bit engines the +% multi-byte information is shared. % \begin{macrocode} \cs_new:Npn \str_foldcase:n #1 { \@@_change_case:nn {#1} { fold } } \cs_new:Npn \str_lowercase:n #1 { \@@_change_case:nn {#1} { lower } } @@ -1965,7 +1960,100 @@ { \use:c { char_str_ #1 case:N } #2 } \@@_change_case_loop:nw {#1} } +\if_int_compare:w 0 + \cs_if_exist:NT \tex_XeTeXversion:D { 1 } + \cs_if_exist:NT \tex_luatexversion:D { 1 } + > 0 \exp_stop_f: +\else: + \cs_gset:Npn \@@_change_case_char:nN #1#2 + { + \@@_if_recursion_tail_stop_do:Nn #2 + { \@@_change_case_end:wn } + \int_compare:nNnTF { `#2 } > { "80 } + { + \int_compare:nNnTF { `#2 } < { "E0 } + { \@@_change_case_char_UTFviii:nNN } + { + \int_compare:nNnTF { `#2 } < { "F0 } + { \@@_change_case_char_UTFviii:nNNN } + { \@@_change_case_char_UTFviii:nNNNN } + } + {#1} #2 + } + { + \@@_change_case_output:fw + { \use:c { char_str_ #1 case:N } #2 } + \@@_change_case_loop:nw {#1} + } + } + \cs_new:Npn \@@_change_case_char_UTFviii:nNN #1#2#3 + { \@@_change_case_char_UTFviii:nn {#1} {#2#3} } + \cs_new:Npn \@@_change_case_char_UTFviii:nNNN #1#2#3#4 + { \@@_change_case_char_UTFviii:nn {#1} {#2#3#4} } + \cs_new:Npn \@@_change_case_char_UTFviii:nNNNN #1#2#3#4#5 + { \@@_change_case_char_UTFviii:nn {#1} {#2#3#4#5} } % \end{macrocode} +% Skip high chars for the Japanese engines. +% \begin{macrocode} + \cs_if_exist:NF \tex_pdftexversion:D + { + \cs_gset:Npn \@@_change_case_char_UTFviii:nNNN #1#2#3#4 + { + \@@_change_case_output:nw {#2#3#4} + \@@_change_case_loop:nw {#1} + } + \cs_gset:Npn \@@_change_case_char_UTFviii:nNNNN #1#2#3#4#5 + { + \@@_change_case_output:nw {#2#3#4#5} + \@@_change_case_loop:nw {#1} + } + } + \cs_new:Npn \@@_change_case_char_UTFviii:nn #1#2 + { + \use:c { @@_change_case_char_UTFviii_ #1 :nn } {#1} {#2} + } + \cs_new:Npn \@@_change_case_char_UTFviii_upper:nn #1#2 + { + \@@_change_case_output:fw + { + \cs_if_exist:cTF { c__kernel_ #1 case_ #2 _tl } + { + \__kernel_tl_to_str:w \exp_after:wN \exp_after:wN \exp_after:wN + { \cs:w c__kernel_ #1 case_ #2 _tl \cs_end: } + } + {#2} + } + \@@_change_case_loop:nw {#1} + } + \cs_new_eq:NN \@@_change_case_char_UTFviii_lower:nn + \@@_change_case_char_UTFviii_upper:nn + \cs_new:Npn \@@_change_case_char_UTFviii_fold:nn #1#2 + { + \@@_change_case_output:fw + { + \cs_if_exist:cTF { c__kernel_ #1 case_ #2 _tl } + { + \__kernel_tl_to_str:w \exp_after:wN \exp_after:wN \exp_after:wN + { \cs:w c__kernel_ #1 case_ #2 _tl \cs_end: } + } + { + \cs_if_exist:cTF { c__kernel_lowercase_ #2 _tl } + { + \__kernel_tl_to_str:w + \exp_after:wN \exp_after:wN \exp_after:wN + { \cs:w c__kernel_lowercase_ #2 _tl \cs_end: } + } + {#2} + } + } + \@@_change_case_loop:nw {#1} + } +\fi: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \end{macro} % \end{macro} % \end{macro} |