summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty')
-rw-r--r--Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty747
1 files changed, 87 insertions, 660 deletions
diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty
index 8fb7f22b337..15d29def3e8 100644
--- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty
+++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty
@@ -13,7 +13,7 @@
%%
%% Do not distribute a modified version of this file.
%%
-%% File: l3str.dtx Copyright (C) 2011-2012 The LaTeX3 Project
+%% File: l3str.dtx Copyright (C) 2011-2013 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
@@ -46,13 +46,10 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{expl3}
-\GetIdInfo$Id: l3str.dtx 4339 2012-11-24 19:16:43Z joseph $
+\GetIdInfo$Id: l3str.dtx 4452 2013-01-20 10:18:32Z joseph $
{L3 Experimental strings}
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
-\RequirePackage{l3tl-analysis,l3tl-build,l3flag}
-\cs_if_exist:NF \use_ii_i:nn
- { \cs_new:Npn \use_ii_i:nn #1#2 { #2 #1 } }
\cs_new_eq:NN \str_new:N \tl_new:N
\cs_generate_variant:Nn \str_new:N { c }
\tl_map_inline:nn
@@ -70,95 +67,17 @@
{ \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 }
}
-\cs_new_protected_nopar:Npn \__str_tmp:w { }
-\tl_new:N \l__str_internal_tl
-\int_new:N \l__str_internal_int
-\tl_new:N \g__str_result_tl
-\int_const:Nn \c_forty_eight { 48 }
-\int_const:Nn \c_fifty_eight { 58 }
-\int_const:Nn \c_sixty_five { 65 }
-\int_const:Nn \c_ninety_one { 91 }
-\int_const:Nn \c_ninety_seven { 97 }
-\int_const:Nn \c_one_hundred_twenty_three { 123 }
-\int_const:Nn \c_one_hundred_twenty_seven { 127 }
-\int_const:Nn \c_max_char_int
- { \pdftex_if_engine:TF { "FF } { "10FFFF } }
-\int_const:Nn \c__str_replacement_char_int { "FFFD }
-\tl_const:Nx \c_backslash_str { \cs_to_str:N \\ }
-\tl_const:Nx \c_lbrace_str { \cs_to_str:N \{ }
-\tl_const:Nx \c_rbrace_str { \cs_to_str:N \} }
-\tl_const:Nx \c_hash_str { \cs_to_str:N \# }
-\tl_const:Nx \c_tilde_str { \cs_to_str:N \~ }
-\tl_const:Nx \c_percent_str { \cs_to_str:N \% }
-\prop_new:N \g__str_alias_prop
-\prop_gput:Nnn \g__str_alias_prop { latin1 } { iso88591 }
-\prop_gput:Nnn \g__str_alias_prop { latin2 } { iso88592 }
-\prop_gput:Nnn \g__str_alias_prop { latin3 } { iso88593 }
-\prop_gput:Nnn \g__str_alias_prop { latin4 } { iso88594 }
-\prop_gput:Nnn \g__str_alias_prop { latin5 } { iso88599 }
-\prop_gput:Nnn \g__str_alias_prop { latin6 } { iso885910 }
-\prop_gput:Nnn \g__str_alias_prop { latin7 } { iso885913 }
-\prop_gput:Nnn \g__str_alias_prop { latin8 } { iso885914 }
-\prop_gput:Nnn \g__str_alias_prop { latin9 } { iso885915 }
-\prop_gput:Nnn \g__str_alias_prop { latin10 } { iso885916 }
-\prop_gput:Nnn \g__str_alias_prop { utf16le } { utf16 }
-\prop_gput:Nnn \g__str_alias_prop { utf16be } { utf16 }
-\prop_gput:Nnn \g__str_alias_prop { utf32le } { utf32 }
-\prop_gput:Nnn \g__str_alias_prop { utf32be } { utf32 }
-\prop_gput:Nnn \g__str_alias_prop { hexadecimal } { hex }
-\bool_new:N \g__str_error_bool
-\flag_new:n { str_byte }
-\flag_new:n { str_error }
-\group_begin:
-\char_set_lccode:nn { `\* } { `\ }
-\char_set_lccode:nn { `\A } { `\A }
-\tl_to_lowercase:n
- {
- \group_end:
- \cs_new:Npn \__str_to_other:n #1
- {
- \exp_after:wN \__str_to_other_loop:w \tl_to_str:n {#1} ~ %
- A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop
- }
- \cs_new:Npn \__str_to_other_loop:w
- #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \q_stop
- {
- \if_meaning:w A #8
- \__str_to_other_end:w
- \fi:
- \__str_to_other_loop:w
- #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop
- }
- \cs_new:Npn \__str_to_other_end:w \fi: #1 \q_mark #2 * A #3 \q_stop
- { \fi: #2 }
- }
-\group_begin:
-\char_set_lccode:nn { `\* } { `\ }
-\char_set_lccode:nn { `\A } { `\A }
-\tl_to_lowercase:n
- {
- \group_end:
- \cs_new_protected:Npn \__str_gset_other:Nn #1#2
- {
- \tl_gset:Nx #1
- {
- \exp_after:wN \__str_gset_other_loop:w \tl_to_str:n {#2} ~ %
- A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_stop
- }
- }
- \cs_new:Npn \__str_gset_other_loop:w
- #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 ~
- {
- \if_meaning:w A #9
- \__str_gset_other_end:w
- \fi:
- #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * #9
- \__str_gset_other_loop:w *
- }
- \cs_new:Npn \__str_gset_other_end:w \fi: #1 * A #2 \q_stop
- { \fi: #1 }
- }
-\cs_new:Npn \str_count_spaces:N
+\str_const:Nx \c_backslash_str { \cs_to_str:N \\ }
+\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 \% }
+\str_new:N \l_tmpa_str
+\str_new:N \l_tmpb_str
+\str_new:N \g_tmpa_str
+\str_new:N \g_tmpb_str
+\cs_new_nopar:Npn \str_count_spaces:N
{ \exp_args:No \str_count_spaces:n }
\cs_new:Npn \str_count_spaces:n #1
{
@@ -173,7 +92,7 @@
\cs_new:Npn \__str_count_spaces_loop:wwwwwwwww #1~#2~#3~#4~#5~#6~#7~#8~#9~
{
\if_meaning:w X #9
- \exp_after:wN \use_none_delimit_by_q_stop:w
+ \use_i_delimit_by_q_stop:nw
\fi:
\c_nine + \__str_count_spaces_loop:wwwwwwwww
}
@@ -239,12 +158,35 @@
\cs_new:Npn \str_tail_ignore_spaces:n #1
{
\exp_after:wN \__str_tail_auxii:w
- \tl_to_str:n {#1} X X \q_stop
+ \tl_to_str:n {#1} \q_mark \q_mark \q_stop
+ }
+\cs_new:Npn \__str_tail_auxii:w #1 #2 \q_mark #3 \q_stop { #2 }
+\group_begin:
+\char_set_lccode:nn { `\* } { `\ }
+\char_set_lccode:nn { `\A } { `\A }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new:Npn \__str_to_other:n #1
+ {
+ \exp_after:wN \__str_to_other_loop:w \tl_to_str:n {#1} ~ %
+ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop
+ }
+ \cs_new:Npn \__str_to_other_loop:w
+ #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \q_stop
+ {
+ \if_meaning:w A #8
+ \__str_to_other_end:w
+ \fi:
+ \__str_to_other_loop:w
+ #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop
+ }
+ \cs_new:Npn \__str_to_other_end:w \fi: #1 \q_mark #2 * A #3 \q_stop
+ { \fi: #2 }
}
-\cs_new:Npn \__str_tail_auxii:w #1 #2 X #3 \q_stop { #2 }
\cs_new:Npn \__str_skip_c_zero:w #1;
{
- \if_int_compare:w \__int_eval:w #1 > \c_eight
+ \if_int_compare:w #1 > \c_eight
\exp_after:wN \__str_skip_loop:wNNNNNNNN
\else:
\exp_after:wN \__str_skip_end:w
@@ -257,16 +199,11 @@
\cs_new:Npn \__str_skip_end:w #1 ;
{
\exp_after:wN \__str_skip_end:NNNNNNNN
- \if_case:w \if_int_compare:w #1 > \c_zero #1 \else: 0 \fi: \exp_stop_f:
- \or: \or: \or: \or: \or: \or: \or: \or:
+ \if_case:w #1 \exp_stop_f: \or: \or: \or: \or: \or: \or: \or: \or:
}
\cs_new:Npn \__str_skip_end:NNNNNNNN #1#2#3#4#5#6#7#8 { \fi: \c_zero }
\cs_new:Npn \__str_collect_delimit_by_q_stop:w #1;
- {
- \exp_after:wN \__str_collect_loop:wn
- \int_use:N \__int_eval:w #1 ;
- { }
- }
+ { \__str_collect_loop:wn #1 ; { } }
\cs_new:Npn \__str_collect_loop:wn #1 ;
{
\if_int_compare:w #1 > \c_seven
@@ -306,8 +243,7 @@
\exp_after:wN \__str_item:ww
\int_use:N \__int_eval:w #2 \exp_after:wN ;
\__int_value:w \__str_count_unsafe:n {#1} ;
- { } #1
- \q_stop
+ #1 \q_stop
}
\cs_new:Npn \__str_item:ww #1; #2;
{
@@ -317,7 +253,8 @@
{ \use_none_delimit_by_q_stop:w }
{
\exp_after:wN \use_i_delimit_by_q_stop:nw
- \tex_romannumeral:D \__str_skip_c_zero:w #1 + #2 + \c_one ;
+ \tex_romannumeral:D \exp_after:wN \__str_skip_c_zero:w
+ \int_use:N \__int_eval:w #1 + #2 ;
}
}
{
@@ -325,590 +262,80 @@
{ \use_none_delimit_by_q_stop:w }
{
\exp_after:wN \use_i_delimit_by_q_stop:nw
- \tex_romannumeral:D \__str_skip_c_zero:w #1 ;
+ \tex_romannumeral:D \__str_skip_c_zero:w #1 ; { }
}
}
}
-\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
- {
- \exp_args:Nf \__str_substr_unsafe:nnn
- { \__str_to_other:n {#1} } {#2} {#3}
- }
- }
-\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
- {
- \exp_after:wN \__str_substr:www
- \__int_value:w \__str_count_unsafe:n {#1} \exp_after:wN ;
- \int_use:N \__int_eval:w #2 + \c_zero \exp_after:wN ;
- \int_use:N \__int_eval:w
- \exp_args:Nf \__str_substr:nN {#3} \c_max_int ;
- { } #1
- \q_stop
- }
-\cs_new:Npn \__str_substr:nN #1 #2
- { \tl_if_empty:nTF {#1} {#2} {#1} }
-\cs_new:Npn \__str_substr:www #1; #2; #3;
- {
- \exp_args:Nf \__str_substr:nnw
- { \__str_substr_normalize_range:nn {#2} {#1} }
- { \__str_substr_normalize_range:nn {#3} {#1} }
- }
-\cs_new:Npn \__str_substr:nnw #1#2
- {
- \exp_after:wN \__str_collect_delimit_by_q_stop:w
- \int_use:N \__int_eval:w #2 + \c_one - #1 \exp_after:wN ;
- \tex_romannumeral:D \__str_skip_c_zero:w #1 ;
- }
-\cs_new:Npn \__str_substr_normalize_range:nn #1#2
+\cs_new:Npn \__str_range_normalize:nn #1#2
{
\int_eval:n
{
\if_int_compare:w #1 < \c_zero
- \if_int_compare:w #1 < - #2 \exp_stop_f:
+ \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:
- #2
- \else:
+ \if_int_compare:w #1 < #2 \exp_stop_f:
#1
+ \else:
+ #2
\fi:
\fi:
}
}
-\prg_new_conditional:Npnn \str_if_eq:NN #1#2 { p , TF , T , F }
- {
- \if_int_compare:w \pdftex_strcmp:D { \tl_to_str:N #1 } { \tl_to_str:N #2 }
- = \c_zero \prg_return_true: \else: \prg_return_false: \fi:
- }
-\prg_new_conditional:Npnn \__str_if_contains_char:NN #1#2 { T , TF }
+\cs_new_nopar:Npn \str_range:Nnn { \exp_args:No \str_range:nnn }
+\cs_new:Npn \str_range:nnn #1#2#3
{
- \exp_after:wN \__str_if_contains_char_aux:NN \exp_after:wN #2
- #1 { \__prg_break:n { ? \fi: } }
- \__prg_break_point:
- \prg_return_false:
+ \exp_args:Nf \tl_to_str:n
+ {
+ \exp_args:Nf \__str_range_unsafe:nnn
+ { \__str_to_other:n {#1} } {#2} {#3}
+ }
}
-\prg_new_conditional:Npnn \__str_if_contains_char:nN #1#2 { TF }
+\cs_new:Npn \str_range_ignore_spaces:nnn #1
+ { \exp_args:No \__str_range_unsafe:nnn { \tl_to_str:n {#1} } }
+\cs_new:Npn \__str_range_unsafe:nnn #1#2#3
{
- \__str_if_contains_char_aux:NN #2 #1 { \__prg_break:n { ? \fi: } }
- \__prg_break_point:
- \prg_return_false:
+ \exp_after:wN \__str_range:www
+ \__int_value:w \__str_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 \__str_if_contains_char_aux:NN #1#2
+\cs_new:Npn \__str_range:www #1; #2; #3;
{
- \if_charcode:w #1 #2
- \exp_after:wN \__str_if_contains_char_true:
- \fi:
- \__str_if_contains_char_aux:NN #1
+ \exp_args:Nf \__str_range:nnw
+ { \__str_range_normalize:nn {#2} {#1} }
+ { \__str_range_normalize:nn {#3} {#1} }
}
-\cs_new_nopar:Npn \__str_if_contains_char_true:
- { \__prg_break:n { \prg_return_true: \use_none:n } }
-\prg_new_conditional:Npnn \__str_octal_use:N #1 { TF }
+\cs_new:Npn \__str_range:nnw #1#2
{
- \if_int_compare:w \c_one < '1 \token_to_str:N #1 \exp_stop_f:
- #1 \prg_return_true:
- \else:
- \prg_return_false:
- \fi:
+ \exp_after:wN \__str_collect_delimit_by_q_stop:w
+ \int_use:N \__int_eval:w #2 - #1 \exp_after:wN ;
+ \tex_romannumeral:D \__str_skip_c_zero:w #1 ;
}
-\prg_new_conditional:Npnn \__str_hexadecimal_use:N #1 { TF }
+\prg_new_conditional:Npnn \str_if_eq:NN #1#2 { p , TF , T , F }
{
- \if_int_compare:w \c_two < "1 \token_to_str:N #1 \exp_stop_f:
- #1 \prg_return_true:
- \else:
- \if_case:w \__int_eval:w
- \exp_after:wN ` \token_to_str:N #1 - `a
- \__int_eval_end:
- A
- \or: B
- \or: C
- \or: D
- \or: E
- \or: F
- \else:
- \prg_return_false:
- \exp_after:wN \use_none:n
- \fi:
- \prg_return_true:
- \fi:
+ \if_int_compare:w \pdftex_strcmp:D { \tl_to_str:N #1 } { \tl_to_str:N #2 }
+ = \c_zero \prg_return_true: \else: \prg_return_false: \fi:
}
\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 }
-\group_begin:
- \char_set_catcode_other:n { \c_zero }
- \tl_set:Nx \l__str_internal_tl { \tl_to_str:n { 0123456789ABCDEF } }
- \exp_args:No \tl_map_inline:nn { \l__str_internal_tl " }
- { \char_set_lccode:nn {`#1} { \c_zero } }
- \tl_map_inline:Nn \l__str_internal_tl
- {
- \tl_map_inline:Nn \l__str_internal_tl
- {
- \char_set_lccode:nn { \c_zero } {"#1##1}
- \tl_to_lowercase:n
- {
- \tl_const:cx
- { c__str_byte_ \int_eval:n {"#1##1} _tl }
- { ^^@ #1 ##1 }
- }
- }
- }
-\group_end:
-\tl_const:cn { c__str_byte_-1_tl } { { } \use_none:n { } }
-\cs_new:Npn \__str_output_byte:n #1
- { \__str_output_byte:w #1 \__str_output_end: }
-\cs_new_nopar:Npn \__str_output_byte:w
- {
- \exp_after:wN \exp_after:wN
- \exp_after:wN \use_i:nnn
- \cs:w c__str_byte_ \int_use:N \__int_eval:w
- }
-\cs_new:Npn \__str_output_hexadecimal:n #1
- { \__str_output_hexadecimal:w #1 \__str_output_end: }
-\cs_new_nopar:Npn \__str_output_hexadecimal:w
- {
- \exp_after:wN \exp_after:wN
- \exp_after:wN \use_none:n
- \cs:w c__str_byte_ \int_use:N \__int_eval:w
- }
-\cs_new_nopar:Npn \__str_output_end:
- { \__int_eval_end: _tl \cs_end: }
-\cs_new:Npn \__str_output_byte_pair_be:n #1
- {
- \exp_args:Nf \__str_output_byte_pair:nnN
- { \int_div_truncate:nn { #1 } { "100 } } {#1} \use:nn
- }
-\cs_new:Npn \__str_output_byte_pair_le:n #1
- {
- \exp_args:Nf \__str_output_byte_pair:nnN
- { \int_div_truncate:nn { #1 } { "100 } } {#1} \use_ii_i:nn
- }
-\cs_new:Npn \__str_output_byte_pair:nnN #1#2#3
- {
- #3
- { \__str_output_byte:n { #1 } }
- { \__str_output_byte:n { #2 - #1 * "100 } }
- }
-\cs_new_protected:Npn \__str_convert_gmap:N #1
- {
- \tl_gset:Nx \g__str_result_tl
- {
- \exp_after:wN \__str_convert_gmap_loop:NN
- \exp_after:wN #1
- \g__str_result_tl { ? \__prg_break: }
- \__prg_break_point:
- }
- }
-\cs_new:Npn \__str_convert_gmap_loop:NN #1#2
- {
- \use_none:n #2
- #1#2
- \__str_convert_gmap_loop:NN #1
- }
-\cs_new_protected:Npn \__str_convert_gmap_internal:N #1
- {
- \tl_gset:Nx \g__str_result_tl
- {
- \exp_after:wN \__str_convert_gmap_internal_loop:Nww
- \exp_after:wN #1
- \g__str_result_tl \s__tl \q_stop \__prg_break: \s__tl
- \__prg_break_point:
- }
- }
-\cs_new:Npn \__str_convert_gmap_internal_loop:Nww #1 #2 \s__tl #3 \s__tl
- {
- \use_none_delimit_by_q_stop:w #3 \q_stop
- #1 {#3}
- \__str_convert_gmap_internal_loop:Nww #1
- }
-\cs_new_protected:Npn \__str_if_flag_error:nnx #1
- {
- \flag_if_raised:nTF {#1}
- { \__msg_kernel_error:nnx { str } }
- { \use_none:nn }
- }
-\cs_new_protected:Npn \__str_if_flag_no_error:nnx #1#2#3
- { \flag_if_raised:nT {#1} { \bool_gset_true:N \g__str_error_bool } }
-\cs_new_protected:Npn \__str_if_flag_times:nT #1#2
- { \flag_if_raised:nT {#1} { #2~(x \flag_height:n {#1} ) } }
-\cs_new_protected_nopar:Npn \str_set_convert:Nnnn
- { \__str_convert:nNNnnn { } \tl_set_eq:NN }
-\cs_new_protected_nopar:Npn \str_gset_convert:Nnnn
- { \__str_convert:nNNnnn { } \tl_gset_eq:NN }
-\prg_new_protected_conditional:Npnn
- \str_set_convert:Nnnn #1#2#3#4 { T , F , TF }
- {
- \bool_gset_false:N \g__str_error_bool
- \__str_convert:nNNnnn
- { \cs_set_eq:NN \__str_if_flag_error:nnx \__str_if_flag_no_error:nnx }
- \tl_set_eq:NN #1 {#2} {#3} {#4}
- \bool_if:NTF \g__str_error_bool \prg_return_false: \prg_return_true:
- }
-\prg_new_protected_conditional:Npnn
- \str_gset_convert:Nnnn #1#2#3#4 { T , F , TF }
- {
- \bool_gset_false:N \g__str_error_bool
- \__str_convert:nNNnnn
- { \cs_set_eq:NN \__str_if_flag_error:nnx \__str_if_flag_no_error:nnx }
- \tl_gset_eq:NN #1 {#2} {#3} {#4}
- \bool_if:NTF \g__str_error_bool \prg_return_false: \prg_return_true:
- }
-\cs_new_protected:Npn \__str_convert:nNNnnn #1#2#3#4#5#6
- {
- \group_begin:
- #1
- \__str_gset_other:Nn \g__str_result_tl {#4}
- \exp_after:wN \__str_convert:wwwnn
- \tl_to_str:n {#5} /// \q_stop
- { decode } { unescape }
- \prg_do_nothing:
- \__str_convert_decode_:
- \exp_after:wN \__str_convert:wwwnn
- \tl_to_str:n {#6} /// \q_stop
- { encode } { escape }
- \use_ii_i:nn
- \__str_convert_encode_:
- \group_end:
- #2 #3 \g__str_result_tl
- }
-\cs_new_protected:Npn \__str_convert:wwwnn
- #1 / #2 // #3 \q_stop #4#5
- {
- \__str_convert:nnn {enc} {#4} {#1}
- \__str_convert:nnn {esc} {#5} {#2}
- \exp_args:Ncc \__str_convert:NNnNN
- { __str_convert_#4_#1: } { __str_convert_#5_#2: } {#2}
- }
-\cs_new_protected:Npn \__str_convert:NNnNN #1#2#3#4#5
- {
- \if_meaning:w #1 #5
- \tl_if_empty:nF {#3}
- { \__msg_kernel_error:nnx { str } { native-escaping } {#3} }
- #1
- \else:
- #4 #2 #1
- \fi:
- }
-\cs_new_protected:Npn \__str_convert:nnn #1#2#3
- {
- \cs_if_exist:cF { __str_convert_#2_#3: }
- {
- \exp_args:Nx \__str_convert:nnnn
- { \__str_convert_lowercase_alphanum:n {#3} }
- {#1} {#2} {#3}
- }
- }
-\cs_new_protected:Npn \__str_convert:nnnn #1#2#3#4
- {
- \cs_if_exist:cF { __str_convert_#3_#1: }
- {
- \prop_get:NnNF \g__str_alias_prop {#1} \l__str_internal_tl
- { \tl_set:Nn \l__str_internal_tl {#1} }
- \cs_if_exist:cF { __str_convert_#3_ \l__str_internal_tl : }
- {
- \file_if_exist:nTF { l3str-#2- \l__str_internal_tl .def }
- {
- \group_begin:
- \__str_load_catcodes:
- \file_input:n { l3str-#2- \l__str_internal_tl .def }
- \group_end:
- }
- {
- \tl_clear:N \l__str_internal_tl
- \__msg_kernel_error:nnxx { str } { unknown-#2 } {#4} {#1}
- }
- }
- \cs_if_exist:cF { __str_convert_#3_#1: }
- {
- \cs_gset_eq:cc { __str_convert_#3_#1: }
- { __str_convert_#3_ \l__str_internal_tl : }
- }
- }
- \cs_gset_eq:cc { __str_convert_#3_#4: } { __str_convert_#3_#1: }
- }
-\cs_new:Npn \__str_convert_lowercase_alphanum:n #1
- {
- \exp_after:wN \__str_convert_lowercase_alphanum_loop:N
- \tl_to_str:n {#1} { ? \__prg_break: }
- \__prg_break_point:
- }
-\cs_new:Npn \__str_convert_lowercase_alphanum_loop:N #1
- {
- \use_none:n #1
- \if_int_compare:w `#1 < \c_ninety_one
- \if_int_compare:w `#1 < \c_sixty_five
- \if_int_compare:w \c_one < 1#1 \exp_stop_f:
- #1
- \fi:
- \else:
- \__str_output_byte:n { `#1 + \c_thirty_two }
- \fi:
- \else:
- \if_int_compare:w `#1 < \c_one_hundred_twenty_three
- \if_int_compare:w `#1 < \c_ninety_seven
- \else:
- #1
- \fi:
- \fi:
- \fi:
- \__str_convert_lowercase_alphanum_loop:N
- }
-\cs_new_protected:Npn \__str_load_catcodes:
- {
- \char_set_catcode_escape:N \\
- \char_set_catcode_group_begin:N \{
- \char_set_catcode_group_end:N \}
- \char_set_catcode_math_toggle:N \$
- \char_set_catcode_alignment:N \&
- \char_set_catcode_parameter:N \#
- \char_set_catcode_math_superscript:N \^
- \char_set_catcode_ignore:N \ %
- \char_set_catcode_space:N \~
- \tl_map_function:nN { abcdefghijklmnopqrstuvwxyz_:ABCDEFILNPSTUX }
- \char_set_catcode_letter:N
- \tl_map_function:nN { 0123456789"'?*+-.(),`!/<>[];= }
- \char_set_catcode_other:N
- \char_set_catcode_comment:N \%
- \int_set:Nn \tex_endlinechar:D {32}
- }
-\pdftex_if_engine:TF
- { \cs_new_eq:NN \__str_filter_bytes:n \use:n }
- {
- \cs_new:Npn \__str_filter_bytes:n #1
- {
- \__str_filter_bytes_aux:N #1
- { ? \__prg_break: }
- \__prg_break_point:
- }
- \cs_new:Npn \__str_filter_bytes_aux:N #1
- {
- \use_none:n #1
- \if_int_compare:w `#1 < 256 \exp_stop_f:
- #1
- \else:
- \flag_raise:n { str_byte }
- \fi:
- \__str_filter_bytes_aux:N
- }
- }
-\pdftex_if_engine:TF
- { \cs_new_protected_nopar:Npn \__str_convert_unescape_: { } }
- {
- \cs_new_protected_nopar:Npn \__str_convert_unescape_:
- {
- \flag_clear:n { str_byte }
- \tl_gset:Nx \g__str_result_tl
- { \exp_args:No \__str_filter_bytes:n \g__str_result_tl }
- \__str_if_flag_error:nnx { str_byte } { non-byte } { bytes }
- }
- }
-\cs_new_eq:NN \__str_convert_unescape_bytes: \__str_convert_unescape_:
-\cs_new_protected_nopar:Npn \__str_convert_escape_: { }
-\cs_new_eq:NN \__str_convert_escape_bytes: \__str_convert_escape_:
-\cs_new_protected_nopar:Npn \__str_convert_decode_:
- { \__str_convert_gmap:N \__str_decode_native_char:N }
-\cs_new:Npn \__str_decode_native_char:N #1
- { #1 \s__tl \__int_value:w `#1 \s__tl }
-\group_begin:
- \char_set_catcode_other:n { 0 }
- \pdftex_if_engine:TF
- {
- \cs_new_protected_nopar:Npn \__str_convert_encode_:
- {
- \flag_clear:n { str_error }
- \__str_convert_gmap_internal:N \__str_encode_native_char:n
- \__str_if_flag_error:nnx { str_error }
- { pdfTeX-native-overflow } { }
- }
- \cs_new:Npn \__str_encode_native_char:n #1
- {
- \if_int_compare:w #1 < \c_two_hundred_fifty_six
- \__str_output_byte:n {#1}
- \else:
- \flag_raise:n { str_error }
- ?
- \fi:
- }
- \__msg_kernel_new:nnnn { str } { pdfTeX-native-overflow }
- { Character~code~too~large~for~pdfTeX. }
- {
- The~pdfTeX~engine~only~supports~8-bit~characters:~
- valid~character~codes~are~in~the~range~[0,255].~
- To~manipulate~arbitrary~Unicode,~use~LuaTeX~or~XeTeX.
- }
- }
- {
- \cs_new_protected_nopar:Npn \__str_convert_encode_:
- {
- \int_zero:N \l__tl_build_offset_int
- \__tl_gbuild_x:Nw \g__str_result_tl
- \exp_after:wN \__str_encode_native_loop:w
- \g__str_result_tl \s__tl { \q_stop \__prg_break: } \s__tl
- \__prg_break_point:
- \__tl_build_end:
- }
- \cs_new_protected:Npn \__str_encode_native_loop:w #1 \s__tl #2 \s__tl
- {
- \use_none_delimit_by_q_stop:w #2 \q_stop
- \tex_lccode:D \l__str_internal_int \__int_eval:w #2 \__int_eval_end:
- \tl_to_lowercase:n { \__tl_build_one:n { ^^@ } }
- \__str_encode_native_loop:w
- }
- }
-\group_end:
-\cs_new_protected:Npn \__str_declare_eight_bit_encoding:nnn #1#2#3
- {
- \tl_set:Nn \l__str_internal_tl {#1}
- \cs_new_protected_nopar:cpn { __str_convert_decode_#1: }
- { \__str_convert_decode_eight_bit:n {#1} }
- \cs_new_protected_nopar:cpn { __str_convert_encode_#1: }
- { \__str_convert_encode_eight_bit:n {#1} }
- \tl_const:cn { c__str_encoding_#1_tl } {#2}
- \tl_const:cn { c__str_encoding_#1_missing_tl } {#3}
- }
-\cs_new_protected:Npn \__str_convert_decode_eight_bit:n #1
- {
- \group_begin:
- \int_zero:N \l__str_internal_int
- \exp_last_unbraced:Nx \__str_decode_eight_bit_load:nn
- { \tl_use:c { c__str_encoding_#1_tl } }
- { \q_stop \__prg_break: } { }
- \__prg_break_point:
- \exp_last_unbraced:Nx \__str_decode_eight_bit_load_missing:n
- { \tl_use:c { c__str_encoding_#1_missing_tl } }
- { \q_stop \__prg_break: }
- \__prg_break_point:
- \flag_clear:n { str_error }
- \__str_convert_gmap:N \__str_decode_eight_bit_char:N
- \__str_if_flag_error:nnx { str_error } { decode-8-bit } {#1}
- \group_end:
- }
-\cs_new_protected:Npn \__str_decode_eight_bit_load:nn #1#2
- {
- \use_none_delimit_by_q_stop:w #1 \q_stop
- \tex_dimen:D "#1 = \l__str_internal_int sp \scan_stop:
- \tex_skip:D \l__str_internal_int = "#1 sp \scan_stop:
- \tex_toks:D \l__str_internal_int \exp_after:wN { \__int_value:w "#2 }
- \tex_advance:D \l__str_internal_int \c_one
- \__str_decode_eight_bit_load:nn
- }
-\cs_new_protected:Npn \__str_decode_eight_bit_load_missing:n #1
- {
- \use_none_delimit_by_q_stop:w #1 \q_stop
- \tex_dimen:D "#1 = \l__str_internal_int sp \scan_stop:
- \tex_skip:D \l__str_internal_int = "#1 sp \scan_stop:
- \tex_toks:D \l__str_internal_int \exp_after:wN
- { \int_use:N \c__str_replacement_char_int }
- \tex_advance:D \l__str_internal_int \c_one
- \__str_decode_eight_bit_load_missing:n
- }
-\cs_new:Npn \__str_decode_eight_bit_char:N #1
- {
- #1 \s__tl
- \if_int_compare:w \tex_dimen:D `#1 < \l__str_internal_int
- \if_int_compare: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 \s__tl
- }
-\cs_new_protected:Npn \__str_convert_encode_eight_bit:n #1
- {
- \group_begin:
- \int_zero:N \l__str_internal_int
- \exp_last_unbraced:Nx \__str_encode_eight_bit_load:nn
- { \tl_use:c { c__str_encoding_#1_tl } }
- { \q_stop \__prg_break: } { }
- \__prg_break_point:
- \flag_clear:n { str_error }
- \__str_convert_gmap_internal:N \__str_encode_eight_bit_char:n
- \__str_if_flag_error:nnx { str_error } { encode-8-bit } {#1}
- \group_end:
- }
-\cs_new_protected:Npn \__str_encode_eight_bit_load:nn #1#2
- {
- \use_none_delimit_by_q_stop:w #1 \q_stop
- \tex_dimen:D "#2 = \l__str_internal_int sp \scan_stop:
- \tex_skip:D \l__str_internal_int = "#2 sp \scan_stop:
- \exp_args:NNf \tex_toks:D \l__str_internal_int
- { \__str_output_byte:n { "#1 } }
- \tex_advance:D \l__str_internal_int \c_one
- \__str_encode_eight_bit_load:nn
- }
-\cs_new:Npn \__str_encode_eight_bit_char:n #1
- {
- \if_int_compare:w #1 > \c_max_register_int
- \flag_raise:n { str_error }
- \else:
- \if_int_compare:w \tex_dimen:D #1 < \l__str_internal_int
- \if_int_compare: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:
- \exp_after:wN \exp_after:wN \exp_after:wN \use_none:nn
- \fi:
- \fi:
- \__str_encode_eight_bit_char_aux:n {#1}
- \fi:
- }
-\cs_new:Npn \__str_encode_eight_bit_char_aux:n #1
- {
- \if_int_compare:w #1 < \c_two_hundred_fifty_six
- \__str_output_byte:n {#1}
- \else:
- \flag_raise:n { str_error }
- \fi:
- }
-\__msg_kernel_new:nnn { str } { unknown-esc }
- { Escaping~scheme~'#1'~(filtered:~'#2')~unknown. }
-\__msg_kernel_new:nnn { str } { unknown-enc }
- { Encoding~scheme~'#1'~(filtered:~'#2')~unknown. }
-\__msg_kernel_new:nnnn { str } { native-escaping }
- { The~'native'~encoding~scheme~does~not~support~any~escaping. }
- {
- Since~native~strings~do~not~consist~in~bytes,~
- none~of~the~escaping~methods~make~sense.~
- The~specified~escaping,~'#1',~will be ignored.
- }
-\__msg_kernel_new:nnn { str } { file-not-found }
- { File~'l3str-#1.def'~not~found. }
-\pdftex_if_engine:F
- {
- \__msg_kernel_new:nnnn { str } { non-byte }
- { String~invalid~in~escaping~'#1':~it~may~only~contain~bytes. }
- {
- Some~characters~in~the~string~you~asked~to~convert~are~not~
- 8-bit~characters.~Perhaps~the~string~is~a~'native'~Unicode~string?~
- If~it~is,~try~using\\
- \\
- \iow_indent:n
- {
- \iow_char:N\\str_set_convert:Nnnn \\
- \ \ <str~var>~\{~<string>~\}~\{~native~\}~\{~<target~encoding>~\}
- }
- }
- }
-\__msg_kernel_new:nnnn { str } { decode-8-bit }
- { Invalid~string~in~encoding~'#1'. }
- {
- LaTeX~came~across~a~byte~which~is~not~defined~to~represent~
- any~character~in~the~encoding~'#1'.
- }
-\__msg_kernel_new:nnnn { str } { encode-8-bit }
- { Unicode~string~cannot~be~converted~to~encoding~'#1'. }
+\cs_new:Npn \str_substr:Nnn #1 { \__str_substr:nnn { \str_range:Nnn #1 } }
+\cs_new:Npn \str_substr:nnn #1 { \__str_substr:nnn { \str_range:nnn {#1} } }
+\cs_new:Npn \str_substr_ignore_spaces:nnn #1
+ { \__str_substr:nnn { \str_range_ignore_spaces:nnn {#1} } }
+\cs_new:Npn \__str_substr:nnn #1#2#3
{
- The~encoding~'#1'~only~contains~a~subset~of~all~Unicode~characters.~
- LaTeX~was~asked~to~convert~a~string~to~that~encoding,~but~that~
- string~contains~a~character~that~'#1'~does~not~support.
+ \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} } }
}
-\cs_new_eq:NN \str_length:N \str_count:N
-\cs_new_eq:NN \str_length:n \str_count:n
-\cs_new_eq:NN \str_length_ignore_spaces:n \str_count_ignore_spaces:n
+\cs_new_eq:NN \c_lbrace_str \c_left_brace_str
+\cs_new_eq:NN \c_rbrace_str \c_right_brace_str
%%
%%
%% End of file `l3str.sty'.