diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty | 641 |
1 files changed, 379 insertions, 262 deletions
diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty index 671cb91fc11..b3ce165d5e8 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty @@ -6,7 +6,7 @@ %% %% l3regex.dtx (with options: `package') %% -%% Copyright (C) 2011-2016 The LaTeX3 Project +%% Copyright (C) 2011-2017 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 @@ -19,8 +19,8 @@ %% and all files in that bundle must be distributed together. %% %% File: l3regex.dtx Copyright (C) 2011-2017 The LaTeX3 Project -\RequirePackage{expl3}[2017/04/01] -\@ifpackagelater{expl3}{2017/04/01} +\RequirePackage{expl3}[2017/05/13] +\@ifpackagelater{expl3}{2017/05/13} {} {% \PackageError{l3regex}{Support package l3kernel too old} @@ -32,10 +32,46 @@ }% \endinput } -\ProvidesExplPackage{l3regex}{2017/04/01}{} +\ProvidesExplPackage{l3regex}{2017/05/13}{} {L3 Experimental regular expressions} -\RequirePackage{l3tl-build, l3tl-analysis, l3str-convert} +\RequirePackage{l3tl-build, l3tl-analysis, l3intarray} \cs_generate_variant:Nn \tl_to_str:n { V } +\cs_new_protected:Npn \__regex_standard_escapechar: + { \int_set:Nn \tex_escapechar:D { `\\ } } +\cs_new:Npn \__regex_toks_use:w { \tex_the:D \tex_toks:D } +\cs_new_protected:Npn \__regex_toks_clear:N #1 + { \tex_toks:D #1 { } } +\cs_new_eq:NN \__regex_toks_set:Nn \tex_toks:D +\cs_new_protected:Npn \__regex_toks_set:No #1 + { \__regex_toks_set:Nn #1 \exp_after:wN } +\cs_new_protected:Npn \__regex_toks_memcpy:NNn #1#2#3 + { + \prg_replicate:nn {#3} + { + \tex_toks:D #1 = \tex_toks:D #2 + \int_incr:N #1 + \int_incr:N #2 + } + } +\cs_new_protected:Npn \__regex_toks_put_left:Nx #1#2 + { + \cs_set:Npx \__regex_tmp:w { #2 } + \tex_toks:D #1 \exp_after:wN \exp_after:wN \exp_after:wN + { \exp_after:wN \__regex_tmp:w \tex_the:D \tex_toks:D #1 } + } +\cs_new_protected:Npn \__regex_toks_put_right:Nx #1#2 + { + \cs_set:Npx \__regex_tmp:w {#2} + \tex_toks:D #1 \exp_after:wN + { \tex_the:D \tex_toks:D \exp_after:wN #1 \__regex_tmp:w } + } +\cs_new_protected:Npn \__regex_toks_put_right:Nn #1#2 + { \tex_toks:D #1 \exp_after:wN { \tex_the:D \tex_toks:D #1 #2 } } +\cs_new:Npn \__regex_current_cs_to_str: + { + \exp_after:wN \exp_after:wN \exp_after:wN \cs_to_str:N + \tex_the:D \tex_toks:D \l__regex_current_pos_int + } \cs_new:Npn \__regex_tmp:w { } \tl_new:N \l__regex_internal_a_tl \tl_new:N \l__regex_internal_b_tl @@ -50,8 +86,15 @@ \__regex_branch:n { \__regex_class:NnnnN \c_true_bool { } { 1 } { 0 } \c_true_bool } } +\__intarray_new:Nn \g__regex_charcode_intarray { 65536 } +\__intarray_new:Nn \g__regex_catcode_intarray { 65536 } +\__intarray_new:Nn \g__regex_balance_intarray { 65536 } \int_new:N \l__regex_balance_int \tl_new:N \l__regex_cs_name_tl +\int_const:Nn \c__regex_ascii_min_int { 0 } +\int_const:Nn \c__regex_ascii_max_control_int { 31 } +\int_const:Nn \c__regex_ascii_max_int { 127 } +\int_const:Nn \c__regex_ascii_lower_int { `a - `A } \cs_new_protected:Npn \__regex_break_true:w #1 \__regex_break_point:TF #2 #3 {#2} \cs_new_protected:Npn \__regex_break_point:TF #1 #2 { #2 } @@ -108,12 +151,12 @@ \if_int_compare:w \l__regex_current_char_int > `Z \exp_stop_f: \if_int_compare:w \l__regex_current_char_int > `z \exp_stop_f: \else: \if_int_compare:w \l__regex_current_char_int < `a \exp_stop_f: \else: - \int_sub:Nn \l__regex_case_changed_char_int { \c__str_ascii_lower_int } + \int_sub:Nn \l__regex_case_changed_char_int { \c__regex_ascii_lower_int } \fi: \fi: \else: \if_int_compare:w \l__regex_current_char_int < `A \exp_stop_f: \else: - \int_add:Nn \l__regex_case_changed_char_int { \c__str_ascii_lower_int } + \int_add:Nn \l__regex_case_changed_char_int { \c__regex_ascii_lower_int } \fi: \fi: } @@ -152,12 +195,7 @@ \int_compare:nNnTF \l__regex_current_catcode_int = 0 { \tl_set:Nx \l__regex_internal_a_tl - { - \scan_stop: - \exp_after:wN \exp_after:wN \exp_after:wN \cs_to_str:N - \tex_the:D \tex_toks:D \l__regex_current_pos_int - \scan_stop: - } + { \scan_stop: \__regex_current_cs_to_str: \scan_stop: } \tl_if_in:noTF { \scan_stop: #1 \scan_stop: } \l__regex_internal_a_tl { \__regex_break_true:w } { } } @@ -168,12 +206,7 @@ \int_compare:nNnT \l__regex_current_catcode_int = 0 { \group_begin: - \tl_set:Nx \l__regex_cs_name_tl - { - \exp_after:wN \exp_after:wN - \exp_after:wN \cs_to_str:N - \tex_the:D \tex_toks:D \l__regex_current_pos_int - } + \tl_set:Nx \l__regex_cs_name_tl { \__regex_current_cs_to_str: } \__regex_single_match: \__regex_disable_submatches: \__regex_build_for_cs:n {#1} @@ -222,16 +255,16 @@ \cs_new_protected:Npn \__regex_posix_ascii: { \__regex_item_caseful_range:nn - \c__str_ascii_min_int - \c__str_ascii_max_int + \c__regex_ascii_min_int + \c__regex_ascii_max_int } \cs_new_eq:NN \__regex_posix_blank: \__regex_prop_h: \cs_new_protected:Npn \__regex_posix_cntrl: { \__regex_item_caseful_range:nn - \c__str_ascii_min_int - \c__str_ascii_max_control_int - \__regex_item_caseful_equal:n \c__str_ascii_max_int + \c__regex_ascii_min_int + \c__regex_ascii_max_control_int + \__regex_item_caseful_equal:n \c__regex_ascii_max_int } \cs_new_eq:NN \__regex_posix_digit: \__regex_prop_d: \cs_new_protected:Npn \__regex_posix_graph: @@ -267,8 +300,8 @@ \cs_set:Npn \__regex_escape_unescaped:N ##1 { #1 } \cs_set:Npn \__regex_escape_escaped:N ##1 { #2 } \cs_set:Npn \__regex_escape_raw:N ##1 { #3 } - \int_set:Nn \tex_escapechar:D { `\\ } - \__str_gset_other:Nn \g__regex_internal_tl { #4 } + \__regex_standard_escapechar: + \tl_gset:Nx \g__regex_internal_tl { \__str_to_other_fast:n {#4} } \tl_set:Nx \l__regex_internal_b_tl { \exp_after:wN \__regex_escape_loop:N \g__regex_internal_tl @@ -321,36 +354,19 @@ } \cs_new:Npn \__regex_escape_x_end:w #1 ; { - \int_compare:nNnTF {#1} > \c__str_max_byte_int - { \__regex_escape_x_large:n {#1} } + \int_compare:nNnTF {#1} > \c_max_char_int + { + \if_false: { \fi: } + \__tl_build_one:o \l__regex_internal_b_tl + \__msg_kernel_error:nnx { regex } { x-overflow } {#1} + \tl_set:Nx \l__regex_internal_b_tl + { \if_false: } \fi: + } { \exp_last_unbraced:Nf \__regex_escape_raw:N - { \__str_output_byte:n {#1} } + { \char_generate:nn {#1} { 12 } } } } -\group_begin: - \char_set_catcode_other:n { 0 } - \cs_new:Npn \__regex_escape_x_large:n #1 - { - \if_false: { \fi: } - \__tl_build_one:o \l__regex_internal_b_tl - \int_compare:nNnTF {#1} > \c_max_char_int - { - \__msg_kernel_error:nnx { regex } { x-overflow } {#1} - \tl_set:Nx \l__regex_internal_b_tl - { \if_false: } \fi: - } - { - \char_set_lccode:nn { 0 } {#1} - \tex_lowercase:D - { - \tl_set:Nx \l__regex_internal_b_tl - { \if_false: } \fi: - \__regex_escape_raw:N ^^@ - } - } - } -\group_end: \cs_new:Npn \__regex_escape_x_test:N #1 { \str_if_eq_x:nnTF {#1} { break } { ; } @@ -368,7 +384,7 @@ \if_charcode:w \c_left_brace_str #1 \exp_after:wN \__regex_escape_x_loop:N \else: - \__str_hexadecimal_use:NTF #1 + \__regex_hexadecimal_use:NTF #1 { \exp_after:wN \__regex_escape_x:N } { ; \exp_after:wN \__regex_escape_loop:N \exp_after:wN #1 } \fi: @@ -377,7 +393,7 @@ { \str_if_eq_x:nnTF {#1} { break } { ; } { - \__str_hexadecimal_use:NTF #1 + \__regex_hexadecimal_use:NTF #1 { ; \__regex_escape_loop:N } { ; \__regex_escape_loop:N #1 } } @@ -387,7 +403,7 @@ \str_if_eq_x:nnTF {#1} { break } { ; \__regex_escape_x_loop_error:n { } {#1} } { - \__str_hexadecimal_use:NTF #1 + \__regex_hexadecimal_use:NTF #1 { \__regex_escape_x_loop:N } { \token_if_eq_charcode:NNTF \c_space_token #1 @@ -410,11 +426,32 @@ \tl_set:Nx \l__regex_internal_b_tl { \if_false: } \fi: \__regex_escape_loop:N #1 } +\prg_new_conditional:Npnn \__regex_hexadecimal_use:N #1 { TF } + { + \if_int_compare:w 1 < "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: + } \prg_new_conditional:Npnn \__regex_char_if_special:N #1 { TF } { \if_int_compare:w `#1 > `Z \exp_stop_f: \if_int_compare:w `#1 > `z \exp_stop_f: - \if_int_compare:w `#1 < \c__str_ascii_max_int + \if_int_compare:w `#1 < \c__regex_ascii_max_int \prg_return_true: \else: \prg_return_false: \fi: \else: \if_int_compare:w `#1 < `a \exp_stop_f: @@ -605,7 +642,7 @@ \cs_new_protected:Npn \__regex_compile:n #1 { \__regex_compile:w - \int_set:Nn \tex_escapechar:D { `\\ } + \__regex_standard_escapechar: \int_set_eq:NN \l__regex_mode_int \c__regex_outer_mode_int \__regex_escape_use:nnnn { @@ -1199,7 +1236,7 @@ { \if_int_odd:w \__int_eval:w \l__regex_catcodes_int / #1 \__int_eval_end: \else: - \tex_advance:D \l__regex_catcodes_int #1 + \int_add:Nn \l__regex_catcodes_int {#1} \fi: } \cs_new_protected:Npn \__regex_compile_c_lbrack_end: @@ -1327,8 +1364,8 @@ } \cs_new_protected:Npn \__regex_compile_u_in_cs: { - \exp_args:NNo \__str_gset_other:Nn \g__regex_internal_tl - { \l__regex_internal_a_tl } + \tl_gset:Nx \g__regex_internal_tl + { \exp_args:No \__str_to_other_fast:n { \l__regex_internal_a_tl } } \__tl_build_one:x { \tl_map_function:NN \g__regex_internal_tl @@ -1520,6 +1557,7 @@ { control~sequence~ \seq_use:Nn \l__regex_internal_seq { ~or~ } } } \int_new:N \l__regex_min_state_int +\int_set:Nn \l__regex_min_state_int { 1 } \int_new:N \l__regex_max_state_int \int_new:N \l__regex_left_state_int \int_new:N \l__regex_right_state_int @@ -1533,7 +1571,7 @@ } \cs_new_protected:Npn \__regex_build:N #1 { - \int_set:Nn \tex_escapechar:D { `\\ } + \__regex_standard_escapechar: \int_zero:N \l__regex_capturing_group_int \int_set_eq:NN \l__regex_max_state_int \l__regex_min_state_int \__regex_build_new_state: @@ -1573,27 +1611,13 @@ \seq_pop:NN \l__regex_right_state_seq \l__regex_internal_a_tl \int_set:Nn \l__regex_right_state_int \l__regex_internal_a_tl } -\cs_new_protected:Npn \__regex_toks_put_left:Nx #1#2 - { - \cs_set:Npx \__regex_tmp:w { #2 } - \tex_toks:D #1 \exp_after:wN \exp_after:wN \exp_after:wN - { \exp_after:wN \__regex_tmp:w \tex_the:D \tex_toks:D #1 } - } -\cs_new_protected:Npn \__regex_toks_put_right:Nx #1#2 - { - \cs_set:Npx \__regex_tmp:w {#2} - \tex_toks:D #1 \exp_after:wN - { \tex_the:D \tex_toks:D \exp_after:wN #1 \__regex_tmp:w } - } -\cs_new_protected:Npn \__regex_toks_put_right:Nn #1#2 - { \tex_toks:D #1 \exp_after:wN { \tex_the:D \tex_toks:D #1 #2 } } \cs_new_protected:Npn \__regex_build_transition_left:NNN #1#2#3 { \__regex_toks_put_left:Nx #2 { #1 { \int_eval:n { #3 - #2 } } } } \cs_new_protected:Npn \__regex_build_transition_right:nNn #1#2#3 { \__regex_toks_put_right:Nx #2 { #1 { \int_eval:n { #3 - #2 } } } } \cs_new_protected:Npn \__regex_build_new_state: { - \tex_toks:D \l__regex_max_state_int { } + \__regex_toks_clear:N \l__regex_max_state_int \int_set_eq:NN \l__regex_left_state_int \l__regex_right_state_int \int_set_eq:NN \l__regex_right_state_int \l__regex_max_state_int \int_incr:N \l__regex_max_state_int @@ -1756,15 +1780,12 @@ ( #1 - 1 ) * ( \l__regex_internal_b_int - \l__regex_internal_a_int ) } - \tex_advance:D \l__regex_right_state_int \l__regex_internal_c_int - \tex_advance:D \l__regex_max_state_int \l__regex_internal_c_int - \prg_replicate:nn \l__regex_internal_c_int - { - \tex_toks:D \l__regex_internal_b_int - = \tex_toks:D \l__regex_internal_a_int - \int_incr:N \l__regex_internal_a_int - \int_incr:N \l__regex_internal_b_int - } + \int_add:Nn \l__regex_right_state_int { \l__regex_internal_c_int } + \int_add:Nn \l__regex_max_state_int { \l__regex_internal_c_int } + \__regex_toks_memcpy:NNn + \l__regex_internal_b_int + \l__regex_internal_a_int + \l__regex_internal_c_int \fi: } \cs_new_protected:Npn \__regex_group_repeat:nnN #1#2#3 @@ -1892,6 +1913,8 @@ \int_new:N \l__regex_step_int \int_new:N \l__regex_min_active_int \int_new:N \l__regex_max_active_int +\__intarray_new:Nn \g__regex_state_active_intarray { 65536 } +\__intarray_new:Nn \g__regex_thread_state_intarray { 65536 } \tl_new:N \l__regex_every_match_tl \bool_new:N \l__regex_fresh_thread_bool \bool_new:N \l__regex_empty_success_bool @@ -1912,12 +1935,13 @@ \bool_gset_false:N \g__regex_success_bool \int_step_inline:nnnn \l__regex_min_state_int { 1 } { \l__regex_max_state_int - 1 } - { \tex_dimen:D ##1 ~ 1 sp \scan_stop: } + { \__intarray_gset_fast:Nnn \g__regex_state_active_intarray {##1} { 1 } } \int_set_eq:NN \l__regex_min_active_int \l__regex_max_state_int \int_zero:N \l__regex_step_int \int_set_eq:NN \l__regex_success_pos_int \l__regex_min_pos_int - \int_set:Nn \l__regex_submatch_int + \int_set:Nn \l__regex_min_submatch_int { 2 * \l__regex_max_state_int } + \int_set_eq:NN \l__regex_submatch_int \l__regex_min_submatch_int \bool_set_false:N \l__regex_empty_success_bool \__regex_match_once: } @@ -1958,7 +1982,7 @@ } \cs_new_protected:Npn \__regex_match_loop: { - \tex_advance:D \l__regex_step_int 2 \exp_stop_f: + \int_add:Nn \l__regex_step_int { 2 } \int_incr:N \l__regex_current_pos_int \int_set_eq:NN \l__regex_last_char_int \l__regex_current_char_int \int_set_eq:NN \l__regex_case_changed_char_int \c_max_int @@ -1966,8 +1990,11 @@ \use:x { \int_set_eq:NN \l__regex_max_active_int \l__regex_min_active_int - \exp_after:wN \__regex_match_one_active:w - \int_use:N \l__regex_min_active_int ; + \int_step_function:nnnN + { \l__regex_min_active_int } + { 1 } + { \l__regex_max_active_int - 1 } + \__regex_match_one_active:n } \__prg_break_point: \bool_set_false:N \l__regex_fresh_thread_bool %^^A was arg of break_point:n @@ -1977,25 +2004,21 @@ \fi: \fi: } -\cs_new:Npn \__regex_match_one_active:w #1; +\cs_new:Npn \__regex_match_one_active:n #1 { - \if_int_compare:w #1 < \l__regex_max_active_int - \__regex_use_state_and_submatches:nn - { \__int_value:w \tex_skip:D #1 } - { \tex_the:D \tex_toks:D #1 } - \exp_after:wN \__regex_match_one_active:w - \__int_value:w \__int_eval:w #1 + 1 \exp_after:wN ; - \fi: + \__regex_use_state_and_submatches:nn + { \__intarray_item_fast:Nn \g__regex_thread_state_intarray {#1} } + { \__regex_toks_use:w #1 } } \cs_new_protected:Npn \__regex_query_set:nnn #1#2#3 { - \tex_muskip:D \l__regex_current_pos_int - = \etex_gluetomu:D - #3 sp - plus #2 sp - minus \l__regex_balance_int sp - \scan_stop: - \tex_toks:D \l__regex_current_pos_int {#1} + \__intarray_gset_fast:Nnn \g__regex_charcode_intarray + { \l__regex_current_pos_int } {#3} + \__intarray_gset_fast:Nnn \g__regex_catcode_intarray + { \l__regex_current_pos_int } {#2} + \__intarray_gset_fast:Nnn \g__regex_balance_intarray + { \l__regex_current_pos_int } { \l__regex_balance_int } + \__regex_toks_set:Nn \l__regex_current_pos_int {#1} \int_incr:N \l__regex_current_pos_int \if_case:w #2 \exp_stop_f: \or: \int_incr:N \l__regex_balance_int @@ -2005,22 +2028,26 @@ \cs_new_protected:Npn \__regex_query_get: { \l__regex_current_char_int - = \etex_mutoglue:D \tex_muskip:D \l__regex_current_pos_int - \l__regex_current_catcode_int = \etex_gluestretch:D - \etex_mutoglue:D \tex_muskip:D \l__regex_current_pos_int + = \__intarray_item_fast:Nn \g__regex_charcode_intarray + { \l__regex_current_pos_int } \scan_stop: + \l__regex_current_catcode_int + = \__intarray_item_fast:Nn \g__regex_catcode_intarray + { \l__regex_current_pos_int } \scan_stop: } \cs_new_protected:Npn \__regex_use_state: { - \tex_dimen:D \l__regex_current_state_int - = \l__regex_step_int sp \scan_stop: - \tex_the:D \tex_toks:D \l__regex_current_state_int - \tex_dimen:D \l__regex_current_state_int - = \__int_eval:w \l__regex_step_int + 1 \__int_eval_end: sp \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_state_active_intarray + { \l__regex_current_state_int } { \l__regex_step_int } + \__regex_toks_use:w \l__regex_current_state_int + \__intarray_gset_fast:Nnn \g__regex_state_active_intarray + { \l__regex_current_state_int } { \l__regex_step_int + 1 } } \cs_new_protected:Npn \__regex_use_state_and_submatches:nn #1 #2 { \int_set:Nn \l__regex_current_state_int {#1} - \if_int_compare:w \tex_dimen:D \l__regex_current_state_int + \if_int_compare:w + \__intarray_item_fast:Nn \g__regex_state_active_intarray + { \l__regex_current_state_int } < \l__regex_step_int \tl_set:Nn \l__regex_current_submatches_prop {#2} \exp_after:wN \__regex_use_state: @@ -2045,7 +2072,10 @@ \int_add:Nn \l__regex_current_state_int {#2} \exp_not:n { - \if_int_compare:w \tex_dimen:D \l__regex_current_state_int #1 + \if_int_compare:w + \__intarray_item_fast:Nn \g__regex_state_active_intarray + { \l__regex_current_state_int } + #1 \exp_after:wN \__regex_use_state: \fi: } @@ -2063,12 +2093,13 @@ \cs_new_protected:Npn \__regex_store_state:n #1 { \__regex_store_submatches: - \tex_skip:D \l__regex_max_active_int = #1 sp \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_thread_state_intarray + { \l__regex_max_active_int } {#1} \int_incr:N \l__regex_max_active_int } \cs_new_protected:Npn \__regex_store_submatches: { - \tex_toks:D \l__regex_max_active_int \exp_after:wN + \__regex_toks_set:No \l__regex_max_active_int { \l__regex_current_submatches_prop } } \cs_new_protected:Npn \__regex_disable_submatches: @@ -2095,14 +2126,16 @@ } } \int_new:N \l__regex_replacement_csnames_int +\tl_new:N \l__regex_replacement_category_tl +\seq_new:N \l__regex_replacement_category_seq \tl_new:N \l__regex_balance_tl \cs_new:Npn \__regex_replacement_balance_one_match:n #1 { - \__regex_submatch_balance:n {#1} } \cs_new:Npn \__regex_replacement_do_one_match:n #1 { \__regex_query_range:nn - { \etex_glueshrink:D \tex_skip:D #1 } - { \tex_skip:D #1 } + { \__intarray_item_fast:Nn \g__regex_submatch_prev_intarray {#1} } + { \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray {#1} } } \cs_new:Npn \__regex_replacement_exp_not:N #1 { \exp_not:n {#1} } \cs_new:Npn \__regex_query_range:nn #1#2 @@ -2118,22 +2151,35 @@ \else: \exp_after:wN \__prg_break: \fi: - \tex_the:D \tex_toks:D #1 \exp_stop_f: + \__regex_toks_use:w #1 \exp_stop_f: \exp_after:wN \__regex_query_range_loop:ww \__int_value:w \__int_eval:w #1 + 1 ; #2 ; } \cs_new:Npn \__regex_query_submatch:n #1 { \__regex_query_range:nn - { \tex_skip:D \__int_eval:w #1 } - { \etex_gluestretch:D \tex_skip:D \__int_eval:w #1 } + { \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray {#1} } + { \__intarray_item_fast:Nn \g__regex_submatch_end_intarray {#1} } } \cs_new_protected:Npn \__regex_submatch_balance:n #1 { - \etex_glueshrink:D \etex_mutoglue:D \etex_muexpr:D - \tex_muskip:D \etex_gluestretch:D \tex_skip:D #1 - - \tex_muskip:D \tex_skip:D #1 - \scan_stop: + \__int_eval:w + \int_compare:nNnTF + { \__intarray_item_fast:Nn \g__regex_submatch_end_intarray {#1} } = 0 + { 0 } + { + \__intarray_item_fast:Nn \g__regex_balance_intarray + { \__intarray_item_fast:Nn \g__regex_submatch_end_intarray {#1} } + } + - + \int_compare:nNnTF + { \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray {#1} } = 0 + { 0 } + { + \__intarray_item_fast:Nn \g__regex_balance_intarray + { \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray {#1} } + } + \__int_eval_end: } \cs_new_protected:Npn \__regex_replacement:n #1 { @@ -2143,10 +2189,14 @@ \__regex_escape_use:nnnn { \if_charcode:w \c_right_brace_str ##1 - \__regex_replacement_rbrace:N \else: \__tl_build_one:n \fi: ##1 + \__regex_replacement_rbrace:N + \else: + \__regex_replacement_normal:n + \fi: + ##1 } { \__regex_replacement_escaped:N ##1 } - { \__tl_build_one:n ##1 } + { \__regex_replacement_normal:n ##1 } {#1} \prg_do_nothing: \prg_do_nothing: \if_int_compare:w \l__regex_replacement_csnames_int > 0 \exp_stop_f: @@ -2155,6 +2205,12 @@ \__tl_build_one:x { \prg_replicate:nn \l__regex_replacement_csnames_int \cs_end: } \fi: + \seq_if_empty:NF \l__regex_replacement_category_seq + { + \__msg_kernel_error:nnx { regex } { replacement-missing-rparen } + { \seq_count:N \l__regex_replacement_category_seq } + \seq_clear:N \l__regex_replacement_category_seq + } \cs_gset:Npx \__regex_replacement_balance_one_match:n ##1 { + \int_use:N \l__regex_balance_int @@ -2169,11 +2225,27 @@ \cs_set:Npn \__regex_replacement_do_one_match:n ##1 { \__regex_query_range:nn - { \etex_glueshrink:D \tex_skip:D ##1 } - { \tex_skip:D ##1 } + { \__intarray_item_fast:Nn \g__regex_submatch_prev_intarray {##1} } + { \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray {##1} } #1 } } +\cs_new_protected:Npn \__regex_replacement_normal:n #1 + { + \tl_if_empty:NTF \l__regex_replacement_category_tl + { \__tl_build_one:n {#1} } + { % ( + \token_if_eq_charcode:NNTF #1 ) + { + \seq_pop:NN \l__regex_replacement_category_seq + \l__regex_replacement_category_tl + } + { + \use:c { __regex_replacement_c_ \l__regex_replacement_category_tl :w } + \__regex_replacement_normal:n {#1} + } + } + } \cs_new_protected:Npn \__regex_replacement_escaped:N #1 { \cs_if_exist_use:cF { __regex_replacement_#1:w } @@ -2181,7 +2253,8 @@ \if_int_compare:w 1 < 1#1 \exp_stop_f: \__regex_replacement_put_submatch:n {#1} \else: - \__tl_build_one:o { \token_to_str:N #1 } + \exp_args:No \__regex_replacement_normal:n + { \token_to_str:N #1 } \fi: } } @@ -2197,28 +2270,26 @@ } \cs_new_protected:Npn \__regex_replacement_g:w #1#2 { - \str_if_eq_x:nnTF { #1#2 } { \__tl_build_one:n \c_left_brace_str } - { - \int_zero:N \l__regex_internal_a_int - \__regex_replacement_g_digits:NN - } + \str_if_eq_x:nnTF { #1#2 } { \__regex_replacement_normal:n \c_left_brace_str } + { \l__regex_internal_a_int = \__regex_replacement_g_digits:NN } { \__regex_replacement_error:NNN g #1 #2 } } -\cs_new_protected:Npn \__regex_replacement_g_digits:NN #1#2 +\cs_new:Npn \__regex_replacement_g_digits:NN #1#2 { - \token_if_eq_meaning:NNTF #1 \__tl_build_one:n + \token_if_eq_meaning:NNTF #1 \__regex_replacement_normal:n { \if_int_compare:w 1 < 1#2 \exp_stop_f: - \int_set:Nn \l__regex_internal_a_int - { 10 * \l__regex_internal_a_int + #2 } + #2 \exp_after:wN \use_i:nnn \exp_after:wN \__regex_replacement_g_digits:NN \else: + \exp_stop_f: \exp_after:wN \__regex_replacement_error:NNN \exp_after:wN g \fi: } { + \exp_stop_f: \if_meaning:w \__regex_replacement_rbrace:N #1 \exp_args:No \__regex_replacement_put_submatch:n { \int_use:N \l__regex_internal_a_int } @@ -2232,34 +2303,31 @@ } \cs_new_protected:Npn \__regex_replacement_c:w #1#2 { - \token_if_eq_meaning:NNTF #1 \__tl_build_one:n + \token_if_eq_meaning:NNTF #1 \__regex_replacement_normal:n { - \cs_if_exist_use:cF { __regex_replacement_c_#2:w } - { \__regex_replacement_error:NNN c #1#2 } + \exp_after:wN \token_if_eq_charcode:NNTF \c_left_brace_str #2 + { \__regex_replacement_cu_aux:Nw \__regex_replacement_exp_not:N } + { + \cs_if_exist:cTF { __regex_replacement_c_#2:w } + { \__regex_replacement_cat:NNN #2 } + { \__regex_replacement_error:NNN c #1#2 } + } } { \__regex_replacement_error:NNN c #1#2 } } -\cs_new_protected:cpn { __regex_replacement_c_ \c_left_brace_str :w } +\cs_new_protected:Npn \__regex_replacement_cu_aux:Nw #1 { \if_case:w \l__regex_replacement_csnames_int - \__tl_build_one:n - { \exp_not:n { \exp_after:wN \__regex_replacement_exp_not:N \cs:w } } + \__tl_build_one:n { \exp_not:n { \exp_after:wN #1 \cs:w } } \else: - \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:N \cs:w } } + \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } } \fi: \int_incr:N \l__regex_replacement_csnames_int } \cs_new_protected:Npn \__regex_replacement_u:w #1#2 { - \str_if_eq_x:nnTF { #1#2 } { \__tl_build_one:n \c_left_brace_str } - { - \if_case:w \l__regex_replacement_csnames_int - \__tl_build_one:n { \exp_not:n { \exp_after:wN \exp_not:V \cs:w } } - \else: - \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } } - \fi: - \int_incr:N \l__regex_replacement_csnames_int - } + \str_if_eq_x:nnTF { #1#2 } { \__regex_replacement_normal:n \c_left_brace_str } + { \__regex_replacement_cu_aux:Nw \exp_not:V } { \__regex_replacement_error:NNN u #1#2 } } \cs_new_protected:Npn \__regex_replacement_rbrace:N #1 @@ -2268,18 +2336,36 @@ \__tl_build_one:n \cs_end: \int_decr:N \l__regex_replacement_csnames_int \else: - \__tl_build_one:n #1 + \__regex_replacement_normal:n {#1} \fi: } +\cs_new_protected:Npn \__regex_replacement_cat:NNN #1#2#3 + { + \token_if_eq_meaning:NNTF \prg_do_nothing: #3 + { \__msg_kernel_error:nn { regex } { replacement-catcode-end } } + { + \int_compare:nNnTF { \l__regex_replacement_csnames_int } > 0 + { + \__msg_kernel_error:nnnn + { regex } { replacement-catcode-in-cs } {#1} {#3} + #2 #3 + } + { + \str_if_eq:nnTF { #2 #3 } { \__regex_replacement_normal:n ( } % ) + { + \seq_push:NV \l__regex_replacement_category_seq + \l__regex_replacement_category_tl + \tl_set:Nn \l__regex_replacement_category_tl {#1} + } + { \use:c { __regex_replacement_c_#1:w } #2 #3 } + } + } + } \group_begin: \cs_new_protected:Npn \__regex_replacement_char:nNN #1#2#3 { - \if_meaning:w \prg_do_nothing: #3 - \__msg_kernel_error:nn { regex } { replacement-catcode-end } - \else: - \tex_lccode:D 0 = `#3 \scan_stop: - \tex_lowercase:D { \__tl_build_one:n {#1} } - \fi: + \tex_lccode:D 0 = `#3 \scan_stop: + \tex_lowercase:D { \__tl_build_one:n {#1} } } \char_set_catcode_active:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_A:w @@ -2324,15 +2410,11 @@ } \cs_new_protected:Npn \__regex_replacement_c_S:w #1#2 { - \if_meaning:w \prg_do_nothing: #2 - \__msg_kernel_error:nn { regex } { replacement-catcode-end } - \else: - \if_int_compare:w `#2 = 0 \exp_stop_f: - \__msg_kernel_error:nn { regex } { replacement-null-space } - \fi: - \tex_lccode:D `\ = `#2 \scan_stop: - \tex_lowercase:D { \__tl_build_one:n {~} } + \if_int_compare:w `#2 = 0 \exp_stop_f: + \__msg_kernel_error:nn { regex } { replacement-null-space } \fi: + \tex_lccode:D `\ = `#2 \scan_stop: + \tex_lowercase:D { \__tl_build_one:n {~} } } \char_set_catcode_alignment:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_T:w @@ -2406,8 +2488,12 @@ \int_new:N \l__regex_match_count_int \flag_new:n { __regex_begin } \flag_new:n { __regex_end } +\int_new:N \l__regex_min_submatch_int \int_new:N \l__regex_submatch_int \int_new:N \l__regex_zeroth_submatch_int +\__intarray_new:Nn \g__regex_submatch_prev_intarray { 65536 } +\__intarray_new:Nn \g__regex_submatch_begin_intarray { 65536 } +\__intarray_new:Nn \g__regex_submatch_end_intarray { 65536 } \cs_new_protected:Npn \__regex_return: { \if_meaning:w \c_true_bool \g__regex_success_bool @@ -2461,15 +2547,29 @@ { \if_int_compare:w \l__regex_start_pos_int < \l__regex_success_pos_int \__regex_extract: - \tex_skip:D \l__regex_zeroth_submatch_int - = \l__regex_start_pos_int sp - plus \tex_skip:D \l__regex_zeroth_submatch_int \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_submatch_prev_intarray + { \l__regex_zeroth_submatch_int } { 0 } + \__intarray_gset_fast:Nnn \g__regex_submatch_end_intarray + { \l__regex_zeroth_submatch_int } + { + \__intarray_item_fast:Nn \g__regex_submatch_begin_intarray + { \l__regex_zeroth_submatch_int } + } + \__intarray_gset_fast:Nnn \g__regex_submatch_begin_intarray + { \l__regex_zeroth_submatch_int } + { \l__regex_start_pos_int } \fi: } #1 \__regex_match:n {#2} - \tex_skip:D \l__regex_submatch_int - = \l__regex_start_pos_int sp plus \l__regex_max_pos_int sp \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_submatch_prev_intarray + { \l__regex_submatch_int } { 0 } + \__intarray_gset_fast:Nnn \g__regex_submatch_end_intarray + { \l__regex_submatch_int } + { \l__regex_max_pos_int } + \__intarray_gset_fast:Nnn \g__regex_submatch_begin_intarray + { \l__regex_submatch_int } + { \l__regex_start_pos_int } \int_incr:N \l__regex_submatch_int \if_meaning:w \c_true_bool \l__regex_empty_success_bool \if_int_compare:w \l__regex_start_pos_int = \l__regex_max_pos_int @@ -2487,7 +2587,7 @@ { \s__seq \int_step_function:nnnN - { 2 * \l__regex_max_state_int } + { \l__regex_min_submatch_int } { 1 } { \l__regex_submatch_int - 1 } \__regex_extract_seq_aux:n @@ -2533,7 +2633,12 @@ \int_set_eq:NN \l__regex_zeroth_submatch_int \l__regex_submatch_int \prg_replicate:nn \l__regex_capturing_group_int { - \tex_skip:D \l__regex_submatch_int 0 sp \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_submatch_begin_intarray + { \l__regex_submatch_int } { 0 } + \__intarray_gset_fast:Nnn \g__regex_submatch_end_intarray + { \l__regex_submatch_int } { 0 } + \__intarray_gset_fast:Nnn \g__regex_submatch_prev_intarray + { \l__regex_submatch_int } { 0 } \int_incr:N \l__regex_submatch_int } \prop_map_inline:Nn \l__regex_success_submatches_prop @@ -2545,21 +2650,14 @@ \fi: \__int_eval:w \l__regex_zeroth_submatch_int + ##1 {##2} } - \tex_skip:D \l__regex_zeroth_submatch_int - = \tex_the:D \tex_skip:D \l__regex_zeroth_submatch_int - minus \l__regex_start_pos_int sp \scan_stop: + \__intarray_gset_fast:Nnn \g__regex_submatch_prev_intarray + { \l__regex_zeroth_submatch_int } { \l__regex_start_pos_int } \fi: } \cs_new_protected:Npn \__regex_extract_b:wn #1 < #2 - { - \tex_skip:D #1 = #2 sp - plus \etex_gluestretch:D \tex_skip:D #1 \scan_stop: - } + { \__intarray_gset_fast:Nnn \g__regex_submatch_begin_intarray {#1} {#2} } \cs_new_protected:Npn \__regex_extract_e:wn #1 > #2 - { - \tex_skip:D #1 - = 1 \tex_skip:D #1 plus #2 sp \scan_stop: - } + { \__intarray_gset_fast:Nnn \g__regex_submatch_end_intarray {#1} {#2} } \cs_new_protected:Npn \__regex_replace_once:nnN #1#2#3 { \group_begin: @@ -2580,7 +2678,10 @@ { \__regex_replacement_do_one_match:n { \l__regex_zeroth_submatch_int } \__regex_query_range:nn - { \etex_gluestretch:D \tex_skip:D \l__regex_zeroth_submatch_int } + { + \__intarray_item_fast:Nn \g__regex_submatch_end_intarray + { \l__regex_zeroth_submatch_int } + } { \l__regex_max_pos_int } } \__regex_group_end_replace:N #3 @@ -2597,7 +2698,7 @@ { 0 \int_step_function:nnnN - { 2 * \l__regex_max_state_int } + { \l__regex_min_submatch_int } \l__regex_capturing_group_int { \l__regex_submatch_int - 1 } \__regex_replacement_balance_one_match:n @@ -2605,7 +2706,7 @@ \tl_set:Nx \l__regex_internal_a_tl { \int_step_function:nnnN - { 2 * \l__regex_max_state_int } + { \l__regex_min_submatch_int } \l__regex_capturing_group_int { \l__regex_submatch_int - 1 } \__regex_replacement_do_one_match:n @@ -2641,38 +2742,38 @@ } } \__msg_kernel_new:nnnn { regex } { trailing-backslash } - { Trailing~escape~character~`\iow_char:N\\'. } + { Trailing~escape~character~'\iow_char:N\\'. } { A~regular~expression~or~its~replacement~text~ends~with~ - the~escape~character~`\iow_char:N\\'.~It~will~be~ignored. + the~escape~character~'\iow_char:N\\'.~It~will~be~ignored. } \__msg_kernel_new:nnnn { regex } { x-missing-rbrace } - { Missing~closing~brace~in~`\iow_char:N\\x'~hexadecimal~sequence. } + { Missing~closing~brace~in~'\iow_char:N\\x'~hexadecimal~sequence. } { You~wrote~something~like~ - `\iow_char:N\\x\{...#1'.~ + '\iow_char:N\\x\{...#1'.~ The~closing~brace~is~missing. } \__msg_kernel_new:nnnn { regex } { x-overflow } - { Character~code~`#1'~too~large~in~`\iow_char:N\\x'~hexadecimal~sequence. } + { Character~code~'#1'~too~large~in~'\iow_char:N\\x'~hexadecimal~sequence. } { You~wrote~something~like~ - `\iow_char:N\\x\{\int_to_Hex:n{#1}\}'.~ + '\iow_char:N\\x\{\int_to_Hex:n{#1}\}'.~ The~character~code~#1~is~larger~than~ the~maximum~value~\int_use:N \c_max_char_int. } \__msg_kernel_new:nnnn { regex } { invalid-quantifier } - { Braced~quantifier~`#1'~may~not~be~followed~by~`#2'. } + { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. } { - The~character~`#2'~is~invalid~in~the~braced~quantifier~`#1'.~ - The~only~valid~quantifiers~are~`*',~`?',~`+',~`{<int>}',~ - `{<min>,}'~and~`{<min>,<max>}',~optionally~followed~by~`?'. + The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~ + The~only~valid~quantifiers~are~'*',~'?',~'+',~'{<int>}',~ + '{<min>,}'~and~'{<min>,<max>}',~optionally~followed~by~'?'. } \__msg_kernel_new:nnnn { regex } { missing-rbrack } { Missing~right~bracket~inserted~in~regular~expression. } { LaTeX~was~given~a~regular~expression~where~a~character~class~ - was~started~with~`[',~but~the~matching~`]'~is~missing. + was~started~with~'[',~but~the~matching~']'~is~missing. } \__msg_kernel_new:nnnn { regex } { missing-rparen } { @@ -2692,7 +2793,7 @@ } \__msg_kernel_new:nnnn { regex } { bad-escape } { - Invalid~escape~`\iow_char:N\\#1'~ + Invalid~escape~'\iow_char:N\\#1'~ \__regex_if_in_cs:TF { within~a~control~sequence. } { \__regex_if_in_class:TF @@ -2701,102 +2802,102 @@ } } { - The~escape~sequence~`\iow_char:N\\#1'~may~not~appear~ + The~escape~sequence~'\iow_char:N\\#1'~may~not~appear~ \__regex_if_in_cs:TF { within~a~control~sequence~test~introduced~by~ - `\iow_char:N\\c\iow_char:N\{'. + '\iow_char:N\\c\iow_char:N\{'. } { \__regex_if_in_class:TF { within~a~character~class~ } - { following~a~category~test~such~as~`\iow_char:N\\cL'~ } + { following~a~category~test~such~as~'\iow_char:N\\cL'~ } because~it~does~not~match~exactly~one~character. } } \__msg_kernel_new:nnnn { regex } { range-missing-end } - { Invalid~end-point~for~range~`#1-#2'~in~character~class. } + { Invalid~end-point~for~range~'#1-#2'~in~character~class. } { - The~end-point~`#2'~of~the~range~`#1-#2'~may~not~serve~as~an~ + The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~ end-point~for~a~range:~alphanumeric~characters~should~not~be~ escaped,~and~non-alphanumeric~characters~should~be~escaped. } \__msg_kernel_new:nnnn { regex } { range-backwards } - { Range~`[#1-#2]'~out~of~order~in~character~class. } + { Range~'[#1-#2]'~out~of~order~in~character~class. } { - In~ranges~of~characters~`[x-y]'~appearing~in~character~classes,~ + In~ranges~of~characters~'[x-y]'~appearing~in~character~classes,~ the~first~character~code~must~not~be~larger~than~the~second.~ - Here,~`#1'~has~character~code~\int_eval:n {`#1},~while~ - `#2'~has~character~code~\int_eval:n {`#2}. + Here,~'#1'~has~character~code~\int_eval:n {`#1},~while~ + '#2'~has~character~code~\int_eval:n {`#2}. } \__msg_kernel_new:nnnn { regex } { c-bad-mode } - { Invalid~nested~`\iow_char:N\\c'~escape~in~regular~expression. } + { Invalid~nested~'\iow_char:N\\c'~escape~in~regular~expression. } { - The~`\iow_char:N\\c'~escape~cannot~be~used~within~ - a~control~sequence~test~`\iow_char:N\\c{...}'.~ - To~combine~several~category~tests,~use~`\iow_char:N\\c[...]'. + The~'\iow_char:N\\c'~escape~cannot~be~used~within~ + a~control~sequence~test~'\iow_char:N\\c{...}'.~ + To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'. } \__msg_kernel_new:nnnn { regex } { c-missing-rbrace } - { Missing~right~brace~inserted~for~`\iow_char:N\\c'~escape. } + { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. } { LaTeX~was~given~a~regular~expression~where~a~ - `\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~ - with~a~closing~brace~`\iow_char:N\}'. + '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~ + with~a~closing~brace~'\iow_char:N\}'. } \__msg_kernel_new:nnnn { regex } { c-missing-rbrack } - { Missing~right~bracket~inserted~for~`\iow_char:N\\c'~escape. } + { Missing~right~bracket~inserted~for~'\iow_char:N\\c'~escape. } { - A~construction~`\iow_char:N\\c[...'~appears~in~a~ - regular~expression,~but~the~closing~`]'~is~not~present. + A~construction~'\iow_char:N\\c[...'~appears~in~a~ + regular~expression,~but~the~closing~']'~is~not~present. } \__msg_kernel_new:nnnn { regex } { c-missing-category } - { Invalid~character~`#1'~following~`\iow_char:N\\c'~escape. } + { Invalid~character~'#1'~following~'\iow_char:N\\c'~escape. } { - In~regular~expressions,~the~`\iow_char:N\\c'~escape~sequence~ + In~regular~expressions,~the~'\iow_char:N\\c'~escape~sequence~ may~only~be~followed~by~a~left~brace,~a~left~bracket,~or~a~ capital~letter~representing~a~character~category,~namely~ - one~of~`ABCDELMOPSTU'. + one~of~'ABCDELMOPSTU'. } \__msg_kernel_new:nnnn { regex } { c-trailing } - { Trailing~category~code~escape~`\iow_char:N\\c'... } + { Trailing~category~code~escape~'\iow_char:N\\c'... } { - A~regular~expression~ends~with~`\iow_char:N\\c'~followed~ + A~regular~expression~ends~with~'\iow_char:N\\c'~followed~ by~a~letter.~It~will~be~ignored. } \__msg_kernel_new:nnnn { regex } { u-missing-lbrace } - { Missing~left~brace~following~`\iow_char:N\\u'~escape. } + { Missing~left~brace~following~'\iow_char:N\\u'~escape. } { - The~`\iow_char:N\\u'~escape~sequence~must~be~followed~by~ + The~'\iow_char:N\\u'~escape~sequence~must~be~followed~by~ a~brace~group~with~the~name~of~the~variable~to~use. } \__msg_kernel_new:nnnn { regex } { u-missing-rbrace } - { Missing~right~brace~inserted~for~`\iow_char:N\\u'~escape. } + { Missing~right~brace~inserted~for~'\iow_char:N\\u'~escape. } { LaTeX~ \str_if_eq_x:nnTF { } {#2} { reached~the~end~of~the~string~ } - { encountered~an~escaped~alphanumeric~character `\iow_char:N\\#2'~ } - when~parsing~the~argument~of~an~`\iow_char:N\\u\iow_char:N\{...\}'~escape. + { encountered~an~escaped~alphanumeric~character '\iow_char:N\\#2'~ } + when~parsing~the~argument~of~an~'\iow_char:N\\u\iow_char:N\{...\}'~escape. } \__msg_kernel_new:nnnn { regex } { posix-unsupported } - { POSIX~collating~element~`[#1 ~ #1]'~not~supported. } + { POSIX~collating~element~'[#1 ~ #1]'~not~supported. } { - The~`[.foo.]'~and~`[=bar=]'~syntaxes~have~a~special~meaning~ + The~'[.foo.]'~and~'[=bar=]'~syntaxes~have~a~special~meaning~ in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~ Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class? } \__msg_kernel_new:nnnn { regex } { posix-unknown } - { POSIX~class~`[:#1:]'~unknown. } + { POSIX~class~'[:#1:]'~unknown. } { - `[:#1:]'~is~not~among~the~known~POSIX~classes~ - `[:alnum:]',~`[:alpha:]',~`[:ascii:]',~`[:blank:]',~ - `[:cntrl:]',~`[:digit:]',~`[:graph:]',~`[:lower:]',~ - `[:print:]',~`[:punct:]',~`[:space:]',~`[:upper:]',~ - `[:word:]',~and~`[:xdigit:]'. + '[:#1:]'~is~not~among~the~known~POSIX~classes~ + '[:alnum:]',~'[:alpha:]',~'[:ascii:]',~'[:blank:]',~ + '[:cntrl:]',~'[:digit:]',~'[:graph:]',~'[:lower:]',~ + '[:print:]',~'[:punct:]',~'[:space:]',~'[:upper:]',~ + '[:word:]',~and~'[:xdigit:]'. } \__msg_kernel_new:nnnn { regex } { posix-missing-close } - { Missing~closing~`:]'~for~POSIX~class. } - { The~POSIX~syntax~`#1'~must~be~followed~by~`:]',~not~`#2'. } + { Missing~closing~':]'~for~POSIX~class. } + { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. } \__msg_kernel_new:nnnn { regex } { result-unbalanced } { Missing~brace~inserted~when~#1. } { @@ -2806,58 +2907,68 @@ #2~left,~#3~right. } \__msg_kernel_new:nnnn { regex } { unknown-option } - { Unknown~option~`#1'~for~regular~expressions. } + { Unknown~option~'#1'~for~regular~expressions. } { - The~only~available~option~is~`case-insensitive',~toggled~by~ - `(?i)'~and~`(?-i)'. + The~only~available~option~is~'case-insensitive',~toggled~by~ + '(?i)'~and~'(?-i)'. } \__msg_kernel_new:nnnn { regex } { special-group-unknown } - { Unknown~special~group~`#1~...'~in~a~regular~expression. } + { Unknown~special~group~'#1~...'~in~a~regular~expression. } { - The~only~valid~constructions~starting~with~`(?'~are~ - `(?:~...~)',~`(?|~...~)',~`(?i)',~and~`(?-i)'. + The~only~valid~constructions~starting~with~'(?'~are~ + '(?:~...~)',~'(?|~...~)',~'(?i)',~and~'(?-i)'. } \__msg_kernel_new:nnnn { regex } { replacement-c } - { Misused~`\iow_char:N\\c'~command~in~a~replacement~text. } + { Misused~'\iow_char:N\\c'~command~in~a~replacement~text. } { - In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~ - can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~ - or~a~brace~group,~not~by~`#1'. + In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~ + can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~ + or~a~brace~group,~not~by~'#1'. } \__msg_kernel_new:nnnn { regex } { replacement-u } - { Misused~`\iow_char:N\\u'~command~in~a~replacement~text. } + { Misused~'\iow_char:N\\u'~command~in~a~replacement~text. } { - In~a~replacement~text,~the~`\iow_char:N\\u'~escape~sequence~ + In~a~replacement~text,~the~'\iow_char:N\\u'~escape~sequence~ must~be~~followed~by~a~brace~group~holding~the~name~of~the~ variable~to~use. } \__msg_kernel_new:nnnn { regex } { replacement-g } { - Missing~brace~for~the~`\iow_char:N\\g'~construction~ + Missing~brace~for~the~'\iow_char:N\\g'~construction~ in~a~replacement~text. } { In~the~replacement~text~for~a~regular~expression~search,~ - submatches~are~represented~either~as~`\iow_char:N \\g{dd..d}',~ - or~`\\d',~where~`d'~are~single~digits.~Here,~a~brace~is~missing. + submatches~are~represented~either~as~'\iow_char:N \\g{dd..d}',~ + or~'\\d',~where~'d'~are~single~digits.~Here,~a~brace~is~missing. } \__msg_kernel_new:nnnn { regex } { replacement-catcode-end } { - Missing~character~for~the~`\iow_char:N\\c<category><character>'~ + Missing~character~for~the~'\iow_char:N\\c<category><character>'~ construction~in~a~replacement~text. } { - In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~ - can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~representing~ + In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~ + can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~representing~ the~character~category.~Then,~a~character~must~follow.~LaTeX~ reached~the~end~of~the~replacement~when~looking~for~that. } +\__msg_kernel_new:nnnn { regex } { replacement-catcode-in-cs } + { + Category~code~'\iow_char:N\\c#1#3'~ignored~inside~ + '\iow_char:N\\c\{...\}'~in~a~replacement~text. + } + { + In~a~replacement~text,~the~category~codes~of~the~argument~of~ + '\iow_char:N\\c\{...\}'~are~ignored~when~building~the~control~ + sequence~name. + } \__msg_kernel_new:nnnn { regex } { replacement-null-space } { TeX~cannot~build~a~space~token~with~character~code~0. } { You~asked~for~a~character~token~with~category~space,~ and~character~code~0,~for~instance~through~ - `\iow_char:N\\cS\iow_char:N\\x00'.~ + '\iow_char:N\\cS\iow_char:N\\x00'.~ This~specific~case~is~impossible~and~will~be~replaced~ by~a~normal~space. } @@ -2867,6 +2978,12 @@ There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~ missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } . } +\__msg_kernel_new:nnnn { regex } { replacement-missing-rparen } + { Missing~right~parenthesis~inserted~in~replacement~text. } + { + There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~ + missing~right~\int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } . + } \cs_new:Npn \__regex_msg_repeated:nnN #1#2#3 { \str_if_eq_x:nnF { #1 #2 } { 1 0 } |