diff options
author | Karl Berry <karl@freefriends.org> | 2011-11-25 00:13:53 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-11-25 00:13:53 +0000 |
commit | ffc8e17b8078900ab7932786f99a36a7f3b1166c (patch) | |
tree | 4e6b90567c8ee8bff06b06a3868c14b7e9f06eef /Master/texmf-dist/tex | |
parent | 3c7032087650de924a1aead943de992a2c689248 (diff) |
l3experimental 2966 (19nov11)
git-svn-id: svn://tug.org/texlive/trunk@24655 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
6 files changed, 1438 insertions, 1077 deletions
diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty index 29045fcdea9..07d568d94e9 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty @@ -46,113 +46,121 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{expl3} -\GetIdInfo$Id: l3regex.dtx 2895 2011-10-09 15:58:19Z joseph $ +\GetIdInfo$Id: l3regex.dtx 2943 2011-10-30 15:59:43Z bruno $ {L3 Experimental Regular Expressions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \RequirePackage{l3str} +\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 } \cs_new:Npn \regex_tmp:w { } \tl_new:N \g_regex_tmpa_tl \tl_new:N \l_regex_tmpa_tl \tl_new:N \l_regex_tmpb_tl \int_new:N \l_regex_tmpa_int -\tl_new:N \l_regex_pattern_str +\int_new:N \l_regex_tmpb_int \int_new:N \l_regex_max_state_int \int_new:N \l_regex_left_state_int \int_new:N \l_regex_right_state_int -\seq_new:N \l_regex_left_state_seq -\seq_new:N \l_regex_right_state_seq +\seq_new:N \l_regex_group_begin_seq +\seq_new:N \l_regex_group_end_seq \int_new:N \l_regex_capturing_group_int \seq_new:N \l_regex_capturing_group_seq \tl_new:N \l_regex_one_or_group_tl -\int_new:N \l_regex_repetition_int -\bool_new:N \l_regex_look_behind_bool -\tl_new:N \l_regex_look_behind_str \cs_new_eq:NN \regex_build_tmp_class:n \use_none:n \bool_new:N \l_regex_class_bool \tl_new:N \l_regex_class_tl \tl_const:Nn \c_regex_d_tl { - \regex_item_range:nn {48} {57} % 0--9 + \regex_item_range:nn { \c_forty_eight } { 57 } % 0--9 } \tl_const:Nn \c_regex_D_tl { - \regex_item_more:n {57} % 9 - \regex_item_range:nn {0} {47} % 0 + \regex_item_geq:n { \c_fifty_eight } % > `9 + \regex_item_range:nn { \c_zero } { 47 } % 0 } \tl_const:Nn \c_regex_h_tl { - \regex_item_equal:n {32} % space - \regex_item_equal:n {9} % tab + \regex_item_equal:n { \c_thirty_two } % space + \regex_item_equal:n { \c_nine } % tab } \tl_const:Nn \c_regex_H_tl { - \regex_item_neq:n {32} % space - \regex_item_neq:n {9} % tab - \regex_break_true:w + \regex_item_geq:n { 33 } % > space + \regex_item_range:nn { \c_ten } { 31 } % tab < ... < space + \regex_item_range:nn { \c_zero } { \c_eight } % < tab } \tl_const:Nn \c_regex_s_tl { - \regex_item_equal:n {32} % space - \regex_item_neq:n {11} % vtab - \regex_item_range:nn {9} {13} % tab, lf, vtab, ff, cr + \regex_item_equal:n { \c_thirty_two } % space + \regex_item_range:nn { \c_nine } { \c_ten } % tab, lf + \regex_item_range:nn { \c_twelve } { \c_thirteen } % ff, cr } \tl_const:Nn \c_regex_S_tl { - \regex_item_more:n {32} % > space - \regex_item_range:nn {14} {31} % tab < ... < space - \regex_item_range:nn {0} {8} % < tab - \regex_item_equal:n {11} % vtab + \regex_item_geq:n { 33 } % > space + \regex_item_range:nn { \c_fourteen } { 31 } % tab < ... < space + \regex_item_range:nn { \c_zero } { \c_eight } % < tab + \regex_item_equal:n { \c_eleven } % vtab } \tl_const:Nn \c_regex_v_tl { - \regex_item_range:nn {10} {13} % lf, vtab, ff, cr + \regex_item_range:nn { \c_ten } { \c_thirteen } % lf, vtab, ff, cr } \tl_const:Nn \c_regex_V_tl { - \regex_item_more:n {13} % cr - \regex_item_range:nn {0} {9} % < lf + \regex_item_geq:n { \c_fourteen } % >cr + \regex_item_range:nn { \c_zero } { \c_nine } % < lf } \tl_const:Nn \c_regex_w_tl { - \regex_item_range:nn {97} {122} % a--z - \regex_item_range:nn {65} {90} % A--Z - \regex_item_range:nn {48} {57} % 0--9 - \regex_item_equal:n {95} % _ + \regex_item_range:nn { \c_ninety_seven } { 122 } % a--z + \regex_item_range:nn { \c_sixty_five } { 90 } % A--Z + \regex_item_range:nn { \c_forty_eight } { 57 } % 0--9 + \regex_item_equal:n { 95 } % _ } \tl_const:Nn \c_regex_W_tl { - \regex_item_range:nn {0} {47} % <`0 - \regex_item_range:nn {58} {64} % (`9+1)--(`A-1) - \regex_item_range:nn {91} {94} % (`Z+1)--(`_-1) - \regex_item_equal:n {96} % ` - \regex_item_more:n {122} % z + \regex_item_range:nn { \c_zero } { 47 } % <`0 + \regex_item_range:nn { \c_fifty_eight } { 64 } % (`9+1)--(`A-1) + \regex_item_range:nn { \c_ninety_one } { 94 } % (`Z+1)--(`_-1) + \regex_item_equal:n { 96 } % ` + \regex_item_geq:n { \c_one_hundred_twenty_three } % z } \tl_const:Nn \c_regex_N_tl { - \regex_item_neq:n {10} % lf - \regex_break_true:w + \regex_item_geq:n { \c_eleven } % > lf + \regex_item_range:nn { \c_zero } { \c_nine } % < lf } -\tl_new:N \l_regex_query_str -\int_new:N \l_regex_start_step_int -\int_new:N \l_regex_current_char_int +\tl_new:N \l_regex_query_other_str \int_new:N \l_regex_current_step_int +\int_new:N \l_regex_start_step_int +\int_new:N \l_regex_success_step_int \int_new:N \l_regex_unique_step_int +\int_new:N \l_regex_current_char_int +\int_new:N \l_regex_last_char_int +\int_new:N \l_regex_case_changed_char_int +\bool_new:N \l_regex_caseless_bool \int_new:N \l_regex_current_state_int \prop_new:N \l_regex_current_submatches_prop +\prop_new:N \l_regex_success_submatches_prop \int_new:N \l_regex_max_index_int \tl_new:N \l_regex_every_match_tl +\bool_new:N \l_regex_success_bool \cs_new_protected:Npn \regex_last_match_empty_no:F #1 {#1} \cs_new_protected:Npn \regex_last_match_empty_yes:F { \int_compare:nNnF \l_regex_start_step_int = \l_regex_current_step_int } \cs_new_eq:NN \regex_last_match_empty:F \regex_last_match_empty_no:F -\bool_new:N \l_regex_success_bool \bool_new:N \l_regex_success_empty_bool -\int_new:N \l_regex_success_step_int -\prop_new:N \l_regex_success_submatches_prop \bool_new:N \l_regex_fresh_thread_bool \seq_new:N \g_regex_submatches_seq \int_new:N \g_regex_match_count_int +\seq_new:N \g_regex_extract_all_seq \seq_new:N \g_regex_split_seq \tl_new:N \l_regex_replacement_tl \tl_new:N \g_regex_replaced_str @@ -169,40 +177,43 @@ \tex_toks:D #1 \exp_after:wN { \tex_the:D \tex_toks:D \exp_after:wN #1 \regex_tmp:w } } -\cs_new_eq:NN \regex_if_tail_stop:N \quark_if_recursion_tail_stop:N -\cs_new_protected_nopar:Npn \regex_if_tail_error:Nn #1#2 - { \quark_if_recursion_tail_stop_do:Nn #1 { \regex_build_error:n {#2} } } -\cs_new_protected_nopar:Npn \regex_build_error:n #1 +\cs_new_nopar:Npn \regex_query_substr:NN #1#2 { - \msg_error:nnxx { regex } { build-error } {\int_eval:n{#1}} - { - \prg_case_int:nnn {#1} - { - {-999} {File~not~found} - {-998} {Unsupported~construct} - {-997} {The~regular~expression~is~too~large~(32768~states).} - {1} {\iow_char:N\\~at~end~of~pattern } - {4} {Numbers~out~of~order~in~\iow_char:N\{\iow_char\}~quantifier.} - {6} {Missing~terminating~\iow_char:N\]~for~character~class } - {7} {Invalid~escape~sequence~in~character~class} - {8} {Range~out~of~order~in~character~class} - {22} {Mismatched~parentheses} - {34} {Character~value~in~\iow_char:N\\x{...}~sequence~is~too~large} - } - { Internal~bug. } - } + \exp_after:wN \regex_query_substr_aux:NN + \exp_after:wN #1 + \exp_after:wN #2 + \l_regex_query_other_str + \q_stop + } +\cs_new:Npn \regex_query_substr_aux:NN #1#2 + { + \str_skip_do:nn {#1} + { \str_collect_do:nn { #2 - #1 } { \use_i_delimit_by_q_stop:nw } } + } +\cs_new_protected_nopar:Npn \regex_seq_pop:N #1 + { + \seq_pop:NN #1 \l_regex_tmpa_tl + \l_regex_tmpa_tl + } +\cs_new_protected_nopar:Npn \regex_seq_get:N #1 + { + \seq_get:NN #1 \l_regex_tmpa_tl + \l_regex_tmpa_tl } -\msg_new:nnn { regex } { build-error } { (error~#1): ~ #2 } -\cs_new_nopar:Npn \regex_break_true:w #1 \regex_break_point:TF #2 #3 {#2} -\cs_new_nopar:Npn \regex_break_false:w #1 \regex_break_point:TF #2 #3 {#3} -\cs_new_eq:NN \regex_break_point:TF \use_ii:nn -\cs_new_nopar:Npn \regex_item_equal:n #1 +\cs_new_protected_nopar:Npn \regex_item_dot:T + { \int_compare:nNnF \l_regex_current_char_int = \c_minus_one } +\cs_new_protected_nopar:Npn \regex_break_true:w + #1 \regex_break_point:TF #2 #3 {#2} +\cs_new_protected_nopar:Npn \regex_break_false:w + #1 \regex_break_point:TF #2 #3 {#3} +\cs_new_protected_nopar:Npn \regex_break_point:TF #1 #2 { #2 } +\cs_new_protected_nopar:Npn \regex_item_caseful_equal:n #1 { \if_num:w #1 = \l_regex_current_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_range:nn #1 #2 +\cs_new_protected_nopar:Npn \regex_item_caseful_range:nn #1 #2 { \reverse_if:N \if_num:w #1 > \l_regex_current_char_int \reverse_if:N \if_num:w #2 < \l_regex_current_char_int @@ -210,24 +221,60 @@ \fi: \fi: } -\cs_new_nopar:Npn \regex_item_less:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseful_geq:n #1 { - \if_num:w #1 > \l_regex_current_char_int + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_more:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseless_equal:n #1 { - \if_num:w #1 < \l_regex_current_char_int + \if_num:w #1 = \l_regex_current_char_int + \exp_after:wN \regex_break_true:w + \fi: + \if_num:w #1 = \l_regex_case_changed_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_neq:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseless_range:nn #1 #2 { - \if_num:w #1 = \l_regex_current_char_int - \exp_after:wN \regex_break_false:w + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int + \reverse_if:N \if_num:w #2 < \l_regex_current_char_int + \exp_after:wN \exp_after:wN \exp_after:wN \regex_break_true:w + \fi: + \fi: + \reverse_if:N \if_num:w #1 > \l_regex_case_changed_char_int + \reverse_if:N \if_num:w #2 < \l_regex_case_changed_char_int + \exp_after:wN \exp_after:wN \exp_after:wN \regex_break_true:w + \fi: \fi: } +\cs_new_protected_nopar:Npn \regex_item_caseless_geq:n #1 + { + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int + \exp_after:wN \regex_break_true:w + \fi: + \reverse_if:N \if_num:w #1 > \l_regex_case_changed_char_int + \exp_after:wN \regex_break_true:w + \fi: + } +\cs_new:Npn \regex_item_equal:n { \regex_item_caseful_equal:n } +\cs_new:Npn \regex_item_range:nn { \regex_item_caseful_range:nn } +\cs_new:Npn \regex_item_geq:n { \regex_item_caseful_geq:n } +\cs_new_protected_nopar:Npn \regex_build_caseless: + { + \bool_set_true:N \l_regex_caseless_bool + \cs_set:Npn \regex_item_equal:n { \regex_item_caseless_equal:n } + \cs_set:Npn \regex_item_range:nn { \regex_item_caseless_range:nn } + \cs_set:Npn \regex_item_geq:n { \regex_item_caseless_geq:n } + } +\cs_new_protected_nopar:Npn \regex_build_caseful: + { + \bool_set_false:N \l_regex_caseless_bool + \cs_set:Npn \regex_item_equal:n { \regex_item_caseful_equal:n } + \cs_set:Npn \regex_item_range:nn { \regex_item_caseful_range:nn } + \cs_set:Npn \regex_item_geq:n { \regex_item_caseful_geq:n } + } \cs_new_protected:Npn \regex_get_digits:nw #1 { \tex_afterassignment:D \regex_tmp:w @@ -235,65 +282,71 @@ { \exp_not:n {#1} { \if_false: } } \fi: - \regex_get_digits_aux:N + \regex_get_digits_aux:NN } -\cs_new_nopar:Npn \regex_get_digits_aux:N #1 +\cs_new_nopar:Npn \regex_get_digits_aux:NN #1#2 { - \if_num:w 9 < 1 \exp_not:N #1 \exp_stop_f: - \else: - \if_charcode:w \c_space_token \exp_not:N #1 + \if_meaning:w \regex_build_raw:N #1 + \if_charcode:w \c_space_token \exp_not:N #2 \else: - \regex_get_digits_end:w + \if_num:w 9 < 1 \exp_not:N #2 \exp_stop_f: + #2 + \else: + \regex_get_digits_end:w #1 #2 + \fi: \fi: + \else: + \regex_get_digits_end:w #1 #2 \fi: - #1 \regex_get_digits_aux:N + \regex_get_digits_aux:NN } -\cs_new_nopar:Npn \regex_get_digits_end:w - \fi: \fi: #1 \regex_get_digits_aux:N +\cs_new_nopar:Npn \regex_get_digits_end:w #1 \fi: #2 \regex_get_digits_aux:NN { - \fi: \fi: + \fi: #2 \if_false: { { \fi: } } #1 } +\prg_new_conditional:Npnn \regex_token_if_other_digit:N #1 { TF } + { + \if_num:w \c_nine < 1 \exp_not:N #1 \exp_stop_f: + \prg_return_true: \else: \prg_return_false: \fi: + } \prg_new_conditional:Npnn \regex_aux_char_if_special:N #1 { TF } { - \if_num:w `#1 < 97 \exp_stop_f: - \if_num:w `#1 < 58 \exp_stop_f: - \if_num:w \int_eval:w (`#1 - \c_eight)/\c_sixteen = \c_two - \prg_return_true: - \else: - \prg_return_false: - \fi: + \if_num:w `#1 < \c_ninety_one + \if_num:w `#1 < \c_fifty_eight + \if_num:w `#1 < \c_forty_eight + \if_num:w `#1 < \c_thirty_two + \prg_return_false: \else: \prg_return_true: \fi: + \else: \prg_return_false: \fi: \else: - \if_num:w \int_eval:w `#1 / 26 = \c_three - \prg_return_false: - \else: - \prg_return_true: - \fi: + \if_num:w `#1 < \c_sixty_five + \prg_return_true: \else: \prg_return_false: \fi: \fi: \else: - \if_num:w \int_eval:w `#1 / \c_five = 25 \exp_stop_f: - \prg_return_true: + \if_num:w `#1 < \c_one_hundred_twenty_three + \if_num:w `#1 < \c_ninety_seven + \prg_return_true: \else: \prg_return_false: \fi: \else: - \prg_return_false: + \if_num:w `#1 < \c_one_hundred_twenty_seven + \prg_return_true: \else: \prg_return_false: \fi: \fi: \fi: } \prg_new_conditional:Npnn \regex_aux_char_if_alphanumeric:N #1 { TF } { - \if_num:w `#1 < 91 \exp_stop_f: - \if_num:w `#1 < 65 \exp_stop_f: - \if_num:w \c_nine < 1 #1 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \if_num:w `#1 < \c_ninety_one + \if_num:w `#1 < \c_fifty_eight + \if_num:w `#1 < \c_forty_eight + \prg_return_false: \else: \prg_return_true: \fi: \else: - \prg_return_true: + \if_num:w `#1 < \c_sixty_five + \prg_return_false: \else: \prg_return_true: \fi: \fi: \else: - \if_num:w \int_eval:w (`#1-\c_six)/26 = \c_four - \prg_return_true: + \if_num:w `#1 < \c_one_hundred_twenty_three + \if_num:w `#1 < \c_ninety_seven + \prg_return_false: \else: \prg_return_true: \fi: \else: \prg_return_false: \fi: @@ -301,8 +354,8 @@ } \cs_new_protected_nopar:Npn \regex_build_new_state: { - \int_compare:nNnTF \l_regex_max_state_int > {32766} - { \regex_build_error:n {-997} } + \int_compare:nNnTF \l_regex_max_state_int > { 32766 } + { \msg_error:nn { regex } { -997 } } { \int_incr:N \l_regex_max_state_int \tex_toks:D \l_regex_max_state_int { \s_regex_toks } @@ -314,15 +367,15 @@ { \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int - { #1 { \int_use:N #2 } } + { #1 { \int_eval:n { #2 - \l_regex_left_state_int } } } } \cs_new_protected_nopar:Npn \regex_build_transitions_aux:NNNN #1#2#3#4 { \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { - #1 { \int_use:N #2 } - #3 { \int_use:N #4 } + #1 { \int_eval:n { #2 - \l_regex_left_state_int } } + #3 { \int_eval:n { #4 - \l_regex_left_state_int } } } } \cs_new_protected:Npn \regex_build:n #1 @@ -363,25 +416,19 @@ \cs_set_eq:NN \regex_build_control:N \regex_build_default_control:N \cs_set_eq:NN \regex_build_raw:N \regex_build_default_raw:N \int_set_eq:NN \l_regex_capturing_group_int \c_zero - \int_zero:N \l_regex_left_state_int - \int_zero:N \l_regex_right_state_int \int_zero:N \l_regex_max_state_int \regex_build_new_state: \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_action_start_wildcard:nn - { \int_use:N \l_regex_left_state_int } - { \int_use:N \l_regex_right_state_int } - } + { \regex_action_start_wildcard:nn {0} {1} } } \cs_new_protected_nopar:Npn \regex_build_end: { \seq_if_empty:NF \l_regex_capturing_group_seq { - \regex_build_error:n {22} + \msg_error:nn { regex } {22} \prg_replicate:nn - { \seq_length:N \l_regex_capturing_group_seq } % ( + { \seq_length:N \l_regex_capturing_group_seq } { \regex_build_close_aux: \regex_build_group_: } } \regex_toks_put_right:Nx \l_regex_right_state_int @@ -399,7 +446,13 @@ \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \int_compare:nNnT {#1} = \l_regex_current_step_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_protected_nopar:cpn { regex_build_$: } % $ @@ -409,71 +462,72 @@ { \exp_not:N \int_compare:nNnT \c_minus_one = \l_regex_current_char_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_eq:Nc \regex_build_Z: { regex_build_$: } %$ \cs_new_eq:Nc \regex_build_z: { regex_build_$: } %$ \cs_new_protected_nopar:Npn \regex_build_b: { - \bool_set_true:N \l_regex_look_behind_bool \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \regex_if_word_boundary:TF - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } { } } } \cs_new_protected_nopar:Npn \regex_build_B: { - \bool_set_true:N \l_regex_look_behind_bool \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \regex_if_word_boundary:TF { } - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_protected_nopar:Npn \regex_if_word_boundary:TF { - \tl_if_empty:NTF \l_regex_look_behind_str - { \c_regex_w_tl } - { - \group_begin: - \cs_set_nopar:Npx \regex_tmp:w - { - \int_set:Nn \l_regex_current_char_int - { ` \str_head:N \l_regex_look_behind_str } - } - \regex_tmp:w - \c_regex_w_tl - \regex_break_point:TF - { \group_end: \c_regex_W_tl } - { \group_end: \c_regex_w_tl } - } + \group_begin: + \int_set_eq:NN \l_regex_current_char_int \l_regex_last_char_int + \c_regex_w_tl + \regex_break_point:TF + { \group_end: \c_regex_W_tl \regex_item_equal:n { -1 } } + { \group_end: \c_regex_w_tl } \regex_break_point:TF } \cs_new_protected_nopar:Npn \regex_build_default_raw:N #1 { \cs_set:Npx \regex_build_tmp_class:n ##1 { - \exp_not:n { \exp_not:N \if_num:w } - \int_value:w `#1 = \l_regex_current_char_int - \regex_action_cost:n { ##1 } - \exp_not:n { \exp_not:N \fi: } + \regex_item_equal:n { \int_value:w `#1 } + \regex_break_point:TF { \regex_action_cost:n { ##1 } } { } } \regex_build_one_quantifier: } \cs_new_protected_nopar:cpn { regex_build_.: } { \cs_set:Npn \regex_build_tmp_class:n ##1 - { - \exp_not:N \if_num:w \c_minus_one < \l_regex_current_char_int - \regex_action_cost:n {##1} - \exp_not:N \fi: - } + { \regex_item_dot:T { \regex_action_cost:n {##1} } } \regex_build_one_quantifier: } \cs_new_protected_nopar:Npn \regex_build_char_type:N #1 @@ -481,9 +535,7 @@ \cs_set:Npn \regex_build_tmp_class:n ##1 { \exp_not:N #1 - \exp_not:N \regex_break_point:TF - { \regex_action_cost:n {##1} } - { } + \regex_break_point:TF { \regex_action_cost:n {##1} } { } } \regex_build_one_quantifier: } @@ -518,16 +570,8 @@ { \exp_not:o \l_regex_class_tl \bool_if:NTF \l_regex_class_bool - { - \exp_not:N \regex_break_point:TF - { \regex_action_cost:n {##1} } - { } - } - { - \exp_not:N \regex_break_point:TF - { } - { \regex_action_cost:n {##1} } - } + { \regex_break_point:TF { \regex_action_cost:n {##1} } { } } + { \regex_break_point:TF { } { \regex_action_cost:n {##1} } } } \regex_build_one_quantifier: } @@ -553,7 +597,7 @@ \cs_new_protected_nopar:Npn \regex_class_single:N #1 { \tl_put_right:Nx \l_regex_class_tl - { \exp_not:N \regex_item_equal:n { \int_value:w `#1 } } + { \regex_item_equal:n { \int_value:w `#1 } } } \cs_new_protected_nopar:Npn \regex_class_range:Nw #1#2#3 { @@ -572,14 +616,14 @@ \cs_new_protected_nopar:Npn \regex_class_range_put:NN #1#2 { \if_num:w `#1 > `#2 \exp_stop_f: - \regex_build_error:n {8} + \msg_error:nn { regex } {8} \else: \tl_put_right:Nx \l_regex_class_tl { \if_num:w `#1 = `#2 \exp_stop_f: - \exp_not:N \regex_item_equal:n + \regex_item_equal:n \else: - \exp_not:N \regex_item_range:nn { \int_value:w `#1 } + \regex_item_range:nn { \int_value:w `#1 } \fi: { \int_value:w `#2 } } @@ -651,26 +695,29 @@ \exp_not:N \regex_build_raw:N \c_lbrace_str #1#2 } } -\cs_new_protected_nopar:Npn \regex_build_quantifier_lbrace:nnw #1#2#3 +\cs_new_protected_nopar:Npn \regex_build_quantifier_lbrace:nnw #1#2#3#4 { - \str_if_eq:xxTF { \exp_not:N #3 } { \c_rbrace_str } + \str_if_eq:xxTF + { \exp_not:n {#3#4} } + { \exp_not:N \regex_build_control:N \c_rbrace_str } { \tl_if_empty:nTF {#2} - { \regex_build_quantifier_aux:nnN { {#1} {\c_max_int} } {nn} } + { \regex_build_quantifier_aux:nnNN { {#1} } { n* } } { \int_compare:nNnT {#1} > {#2} - { \regex_build_error:n {4} } - \regex_build_quantifier_aux:nnN { {#1} {#2} } {nn} + { \msg_error:nn { regex } {4} } + \regex_build_quantifier_aux:nnNN { {#1} {#2} } { nn } } } { \regex_build_quantifier_end:n { } \use:x { - \exp_not:n { \exp_args:No \tl_map_function:nN } - { \c_lbrace_str #1 #2 , } - \regex_build_raw:N + \exp_args:No \tl_map_function:nN + { \c_lbrace_str #1 , #2 } + \regex_build_raw:N } + #3 #4 } } \cs_new_protected_nopar:Npn \regex_build_quantifier_end:n #1 @@ -726,71 +773,27 @@ \regex_action_free:n \l_regex_tmpa_int } \cs_new_protected_nopar:Npn \regex_build_one_n: #1 - { - \int_set_eq:NN \l_regex_tmpa_int \l_regex_right_state_int - \regex_build_new_state: - \regex_build_new_state: - \regex_toks_put_right:Nx \l_regex_tmpa_int - { %^^A safe \if nesting? - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \else: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } - \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_build_tmp_class:n - { \int_use:N \l_regex_tmpa_int } - } - } + { \prg_replicate:nn {#1} { \regex_build_one_: } } \cs_new_eq:cN { regex_build_one_n?: } \regex_build_one_n: -\cs_new_protected_nopar:Npn \regex_build_one_nn: #1#2 +\cs_new_protected_nopar:cpx { regex_build_one_n*: } #1 { - \regex_build_one_nn_aux:nn {#1} - { - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \regex_action_repeat_copy:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \fi: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - } + \exp_not:N \prg_replicate:nn {#1} { \exp_not:N \regex_build_one_: } + \exp_not:c { regex_build_one_*: } } -\cs_new_protected_nopar:cpn { regex_build_one_nn?: } #1#2 +\cs_new_protected_nopar:cpx { regex_build_one_n*?: } #1 { - \regex_build_one_nn_aux:nn {#1} - { - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \fi: - } + \exp_not:N \prg_replicate:nn {#1} { \exp_not:N \regex_build_one_: } + \exp_not:c { regex_build_one_*?: } } -\cs_new_protected_nopar:Npn \regex_build_one_nn_aux:nn #1#2 +\cs_new_protected_nopar:Npn \regex_build_one_nn_aux:Nnn #1#2#3 { - \int_set_eq:NN \l_regex_tmpa_int \l_regex_right_state_int - \regex_build_new_state: - \regex_build_new_state: - \regex_toks_put_right:Nx \l_regex_tmpa_int - { - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \else: - #2 - \exp_not:N \fi: - } - \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_build_tmp_class:n - { \int_use:N \l_regex_tmpa_int } - } + \prg_replicate:nn {#2} { \regex_build_one_: } + \prg_replicate:nn {#3-#2} {#1} } +\cs_new_protected_nopar:Npx \regex_build_one_nn: + { \regex_build_one_nn_aux:Nnn \exp_not:c { regex_build_one_?: } } +\cs_new_protected_nopar:cpx { regex_build_one_nn?: } + { \regex_build_one_nn_aux:Nnn \exp_not:c { regex_build_one_??: } } \cs_new_protected_nopar:cpn { regex_build_(: } #1#2 { \str_if_eq:nnTF { #1 #2 } { \regex_build_control:N ? } @@ -806,10 +809,19 @@ \cs_new_protected_nopar:Npn \regex_build_open_aux: { \regex_build_new_state: - \seq_push:Nx \l_regex_left_state_seq - { \int_use:N \l_regex_left_state_int } - \seq_push:Nx \l_regex_right_state_seq - { \int_use:N \l_regex_right_state_int } + \seq_push:Nx \l_regex_group_begin_seq + { + \int_set:Nn \l_regex_left_state_int + { \int_use:N \l_regex_left_state_int } + } + \bool_if:NTF \l_regex_caseless_bool + { \seq_push:Nn \l_regex_group_end_seq { \regex_build_caseless: } } + { \seq_push:Nn \l_regex_group_end_seq { \regex_build_caseful: } } + \seq_push:Nx \l_regex_group_end_seq + { + \int_set:Nn \l_regex_right_state_int + { \int_use:N \l_regex_right_state_int } + } \regex_build_begin_alternation: } \cs_new_protected_nopar:cpn { regex_build_|: } @@ -820,7 +832,7 @@ \cs_new_protected_nopar:cpn { regex_build_): } { \seq_if_empty:NTF \l_regex_capturing_group_seq - { \regex_build_error:n {22} } + { \msg_error:nn { regex } { 22 } } { \regex_build_close_aux: \regex_build_group_quantifier: @@ -829,30 +841,41 @@ \cs_new_protected_nopar:Npn \regex_build_close_aux: { \regex_build_end_alternation: - \seq_pop:NN \l_regex_left_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_left_state_int \l_regex_tmpa_tl - \seq_pop:NN \l_regex_right_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_right_state_int \l_regex_tmpa_tl + \regex_seq_pop:N \l_regex_group_begin_seq + \regex_seq_pop:N \l_regex_group_end_seq + \regex_seq_pop:N \l_regex_group_end_seq } \cs_new_protected_nopar:Npn \regex_build_begin_alternation: { \regex_build_new_state: - \seq_get:NN \l_regex_left_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_left_state_int \l_regex_tmpa_tl + \regex_seq_get:N \l_regex_group_begin_seq \regex_toks_put_right:Nx \l_regex_left_state_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } \cs_new_protected_nopar:Npn \regex_build_end_alternation: { - \seq_get:NN \l_regex_right_state_seq \l_regex_tmpa_tl - \regex_toks_put_right:Nx \l_regex_right_state_int - { \regex_action_free:n { \l_regex_tmpa_tl } } + \int_set_eq:NN \l_regex_left_state_int \l_regex_right_state_int + \regex_seq_get:N \l_regex_group_end_seq + \regex_toks_put_right:Nx \l_regex_left_state_int + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } \cs_new_protected_nopar:Npn \regex_build_special_group:NN #1#2 { \cs_if_exist_use:cF { regex_build_special_group_\token_to_str:N #2 : } { - \regex_build_error:n { -998 } + \msg_error:nn { regex } { -998 } \regex_build_control:N ( % ) \regex_build_raw:N ? #1 #2 @@ -863,6 +886,40 @@ \seq_push:Nx \l_regex_capturing_group_seq { * } \regex_build_open_aux: } +\cs_new_protected_nopar:Npn \regex_build_special_group_i: + { + \regex_build_options:NNN + + \regex_build_raw:N i + } +\cs_new_protected_nopar:cpn { regex_build_special_group_-: } + { + \regex_build_options:NNN - + } +\cs_new_protected_nopar:Npn \regex_build_options:NNN #1#2#3 + { + \token_if_eq_meaning:NNTF \regex_build_raw:N #2 + { + \cs_if_exist_use:cF { regex_build_option_#1#3: } + { \msg_error:nnx { regex } { unknown-option } { #3 } } + \regex_build_options:NNN #1 + } + { + \prg_case_str:nnn { #3 } + { % ( + { ) } { } + { - } { \regex_build_options:NNN - } + } + { \msg_error:nnx { regex } { invalid-in-option } { #3 } } + } + } +\cs_new_protected_nopar:cpn { regex_build_option_+i: } + { + \regex_build_caseless: + \cs_set_eq:NN \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + } +\cs_new_protected_nopar:cpn { regex_build_option_-i: } + { \regex_build_caseful: } \cs_new_protected_nopar:Npn \regex_build_group_quantifier: { \tl_set:Nn \l_regex_one_or_group_tl { group } @@ -891,21 +948,33 @@ \int_set_eq:NN \l_regex_tmpa_int \l_regex_left_state_int \regex_build_new_state: \tex_toks:D \l_regex_right_state_int = \tex_toks:D \l_regex_tmpa_int - \use:x + \regex_toks_put_left:Nx \l_regex_right_state_int + { + \int_set:Nn \l_regex_current_state_int + { \int_use:N \l_regex_tmpa_int } % ^^A here we lie! + } + \cs_set:Npx \regex_tmp:w { \tex_toks:D \l_regex_tmpa_int - { \s_regex_toks #1 { \int_use:N \l_regex_right_state_int } } + { + \s_regex_toks + #1 { \int_eval:n { \l_regex_right_state_int - \l_regex_tmpa_int } } + } } + \regex_tmp:w \regex_build_group_submatches:NN \l_regex_right_state_int \l_regex_left_state_int - \int_set_eq:NN \l_regex_right_state_int \l_regex_left_state_int } \cs_new_protected_nopar:Npn \regex_build_group_qs_aux:NN #1#2 { \regex_build_group_shift:N \regex_action_free:n + \int_set_eq:NN \l_regex_right_state_int \l_regex_left_state_int \regex_build_transition_aux:NN \regex_action_free:n #1 #2 \l_regex_tmpa_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { \int_eval:n { \l_regex_right_state_int - \l_regex_tmpa_int } } + } } \cs_new_protected_nopar:cpn { regex_build_group_?: } { @@ -945,77 +1014,63 @@ \regex_action_free:n \l_regex_right_state_int \regex_action_free:n \l_regex_tmpa_int } -\cs_new_protected_nopar:Npn \regex_build_group_n: #1 +\cs_new_protected_nopar:Npn \regex_build_group_n_aux:n #1 { - \regex_build_group_shift:N \regex_action_repeat_move:n - \regex_build_transition_aux:NN - \regex_action_free:n \l_regex_tmpa_int - \use:x + \regex_toks_put_right:Nx \l_regex_right_state_int { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } + \regex_action_free:n + { \int_eval:n { \l_regex_max_state_int - \l_regex_left_state_int } } } - } -\cs_new_eq:cN { regex_build_group_n?: } \regex_build_group_n: -\cs_new_protected_nopar:Npn \regex_build_group_nn: #1#2 - { - \regex_build_group_shift:N \regex_action_repeat_move:n - \regex_build_transition_aux:NN - \regex_action_free:n \l_regex_tmpa_int - \use:x + \int_set_eq:NN \l_regex_tmpa_int \l_regex_left_state_int + \int_set:Nn \l_regex_tmpb_int { \l_regex_max_state_int + \c_one } + \int_set:Nn \l_regex_max_state_int { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \fi: - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } + \l_regex_left_state_int - \c_one + + #1 * ( \l_regex_max_state_int - \l_regex_left_state_int + \c_one ) + } + \int_until_do:nNnn \l_regex_tmpb_int > \l_regex_max_state_int + { + \tex_toks:D \l_regex_tmpb_int = \tex_toks:D \l_regex_tmpa_int + \int_incr:N \l_regex_tmpa_int + \int_incr:N \l_regex_tmpb_int } } -\cs_new_protected_nopar:cpn { regex_build_group_nn?: } #1#2 - { - \regex_build_group_shift:N \regex_action_repeat_move:n +\cs_new_protected_nopar:Npn \regex_build_group_n: #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} \regex_build_transition_aux:NN + \regex_action_free:n \l_regex_right_state_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int + } +\cs_new_eq:cN { regex_build_group_n?: } \regex_build_group_n: +\cs_new_protected_nopar:cpn { regex_build_group_n*: } #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} + \regex_build_transitions_aux:NNNN \regex_action_free:n \l_regex_tmpa_int - \use:x - { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \fi: - \exp_not:N \fi: - } - } + \regex_action_free:n \l_regex_right_state_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int } -\cs_new_protected:Npn \regex_if_state_free:nT #1 - { - \if_num:w \tex_dimen:D #1 = \l_regex_unique_step_int - \exp_after:wN \use_none:n - \else: - \exp_after:wN \use:n - \fi: +\cs_new_protected_nopar:cpn { regex_build_group_n*?: } #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} + \regex_build_transitions_aux:NNNN + \regex_action_free:n \l_regex_right_state_int + \regex_action_free:n \l_regex_tmpa_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int + } +\cs_new_protected_nopar:Npn \regex_build_group_nn: #1#2 + { % ^^A Not Implemented Yet! + \msg_expandable_error:n { Quantifier~{m,n}~not~implemented~yet } + \use:c { regex_build_group_n*: } {#1} + } +\cs_new_protected_nopar:cpn { regex_build_group_nn?: } #1#2 + { % ^^A Not Implemented Yet! + \msg_expandable_error:n { Quantifier~{m,n}~not~implemented~yet } + \use:c { regex_build_group_n*?: } {#1} } \cs_new_protected:Npn \regex_store_state:n #1 { @@ -1023,23 +1078,24 @@ \tex_skip:D \l_regex_max_index_int #1 sp \scan_stop: \regex_store_submatches:n {#1} } -\cs_new_protected_nopar:Npn \regex_state_use_submatches: +\cs_new_protected_nopar:Npn \regex_state_use_with_submatches: { \regex_state_use_aux:n { } } \cs_new_protected_nopar:Npn \regex_state_use: { \regex_state_use_aux:n { \exp_after:wN \regex_state_use_aux_ii:w } } -\cs_new:Npn \regex_state_use_aux_ii:w #1 \s_regex_toks { } -\cs_new_protected:Npn \regex_state_use_aux:n #1 - { - \regex_if_state_free:nT { \l_regex_current_state_int } - { - \tex_dimen:D \l_regex_current_state_int - = \l_regex_unique_step_int sp \scan_stop: - #1 \tex_the:D \tex_toks:D \l_regex_current_state_int \scan_stop: - } +\cs_new_nopar:Npn \regex_state_use_aux_ii:w #1 \s_regex_toks { } +\cs_new_protected_nopar:Npn \regex_state_use_aux:n #1 + { + \if_num:w \tex_dimen:D \l_regex_current_state_int + < \l_regex_unique_step_int + \tex_dimen:D \l_regex_current_state_int + = \l_regex_unique_step_int sp \scan_stop: + #1 \tex_the:D \tex_toks:D \exp_after:wN \l_regex_current_state_int + \fi: + \scan_stop: } \cs_new_protected_nopar:Npn \regex_disable_submatches: { - \cs_set_eq:NN \regex_state_use_submatches: \regex_state_use: + \cs_set_eq:NN \regex_state_use_with_submatches: \regex_state_use: \cs_set_eq:NN \regex_store_submatches:n \regex_protected_use_none:n \cs_set_eq:NN \regex_action_submatches:n @@ -1048,55 +1104,73 @@ \cs_new_protected:Npn \regex_protected_use_none:n #1 { } \cs_new_protected:Npn \regex_store_submatches:n #1 { - \exp_after:wN \regex_store_submatches_aux:Nw - \exp_after:wN \l_regex_current_submatches_prop - \tex_the:D \tex_toks:D #1 \scan_stop: \q_stop - { #1 } + \tex_toks:D #1 \exp_after:wN + { + \tex_romannumeral:D + \exp_after:wN \regex_store_submatches_aux:w + \tex_the:D \tex_toks:D #1 + } } -\cs_new_protected:Npn \regex_store_submatches_aux:Nw #1 #2 \s_regex_toks +\cs_new_protected:Npn \regex_store_submatches_aux:w #1 \s_regex_toks { - \exp_args:No \regex_store_submatches_aux_ii:wnnwwn { #1 } - #2 - \regex_state_submatches:nn { \c_minus_one } { \q_prop } + \regex_store_submatches_aux_ii:Nnnw + #1 + \regex_state_submatches:nn \c_minus_one \q_prop \s_regex_toks } -\cs_new_protected:Npn \regex_store_submatches_aux_ii:wnnwwn - #1 \regex_state_submatches:nn #2#3 #4 \s_regex_toks #5 \q_stop #6 +\cs_new_protected:Npn \regex_store_submatches_aux_ii:Nnnw + \regex_state_submatches:nn #1 #2 #3 \s_regex_toks { - \tex_toks:D #6 \exp_after:wN + \exp_after:wN \c_zero + \exp_after:wN \regex_state_submatches:nn \exp_after:wN { - \exp_after:wN \regex_state_submatches:nn \exp_after:wN - { \int_value:w \int_eval:w \l_regex_unique_step_int + \c_one } - { #1 } - \regex_state_submatches:nn {#2} {#3} - \s_regex_toks - #5 + \int_value:w \int_eval:w + \l_regex_unique_step_int + \c_one + \exp_after:wN } + \exp_after:wN { \l_regex_current_submatches_prop } + \regex_state_submatches:nn {#1} {#2} + \s_regex_toks } \cs_new_protected:Npn \regex_state_submatches:nn #1#2 { \if_num:w #1 = \l_regex_unique_step_int - \tl_set:Nn \l_regex_current_submatches_prop {#2} + \tl_set:Nn \l_regex_current_submatches_prop { #2 } \fi: } \cs_new_protected:Npn \regex_match:n #1 { - \tl_set:Nx \l_regex_query_str { \tl_to_other_str:n {#1} } + \tl_set:Nx \l_regex_query_other_str { \tl_to_other_str:n {#1} } \regex_match_initial_setup: \regex_match_once: } \cs_new_protected_nopar:Npn \regex_match_once: { \regex_match_setup: - \exp_after:wN \regex_match_once_aux: \l_regex_query_str + \exp_after:wN \regex_match_once_aux: \l_regex_query_other_str \q_recursion_tail \q_recursion_stop \bool_if:NT \l_regex_success_bool { \l_regex_every_match_tl } } \cs_new_protected_nopar:Npn \regex_match_once_aux: - { \str_skip_do:nn { \l_regex_start_step_int } { \regex_match_loop:N } } + { + \int_compare:nNnTF \l_regex_start_step_int = \c_zero + { + \int_set_eq:NN \l_regex_current_char_int \c_minus_one + \regex_match_loop:N + } + { + \str_skip_do:nn + { \l_regex_start_step_int - \c_one } + { \regex_match_once_aux_ii:N } + } + } +\cs_new_protected_nopar:Npn \regex_match_once_aux_ii:N #1 + { + \int_set:Nn \l_regex_current_char_int { `#1 } + \regex_match_loop:N + } \cs_new_protected_nopar:Npn \regex_match_initial_setup: { - \tl_clear:N \l_regex_look_behind_str \prg_stepwise_inline:nnnn {1} {1} { \l_regex_max_state_int } { \tex_dimen:D ##1 \c_minus_one sp \scan_stop: } \int_set_eq:NN \l_regex_unique_step_int \c_minus_one @@ -1118,20 +1192,11 @@ \int_zero:N \l_regex_max_index_int \regex_store_state:n {1} } -\cs_new_protected_nopar:Npn \regex_match_loop_setup: - { - \int_incr:N \l_regex_current_step_int - \int_incr:N \l_regex_unique_step_int - \bool_set_false:N \l_regex_fresh_thread_bool - } \cs_new_eq:NN \s_regex_step \scan_stop: \cs_new:Npn \regex_break_step:w #1 \s_regex_step { } \cs_new_protected_nopar:Npn \regex_match_loop:N #1 { - \regex_match_loop_setup: - \token_if_eq_meaning:NNTF #1 \q_recursion_tail - { \int_set_eq:NN \l_regex_current_char_int \c_minus_one } - { \int_set:Nn \l_regex_current_char_int {`#1} } + \regex_match_loop_setup:N #1 \cs_set_nopar:Npx \regex_tmp:w { \int_zero:N \l_regex_max_index_int @@ -1145,19 +1210,49 @@ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: \quark_if_recursion_tail_stop:N #1 - \bool_if:NT \l_regex_look_behind_bool - { \tl_put_left:Nx \l_regex_look_behind_str {#1} } \regex_match_loop:N } \cs_new_nopar:Npn \regex_match_one_index:n #1 { - \regex_match_one_index_aux:n { \int_value:w \tex_skip:D #1 } + \regex_match_one_index_aux:n + { \int_value:w \tex_skip:D #1 } } \cs_new_protected_nopar:Npn \regex_match_one_index_aux:n #1 { \int_set:Nn \l_regex_current_state_int {#1} \prop_clear:N \l_regex_current_submatches_prop - \regex_state_use_submatches: + \regex_state_use_with_submatches: + } +\cs_new_protected_nopar:Npn \regex_match_loop_setup:N #1 + { + \int_incr:N \l_regex_current_step_int + \int_incr:N \l_regex_unique_step_int + \bool_set_false:N \l_regex_fresh_thread_bool + \int_set_eq:NN \l_regex_last_char_int \l_regex_current_char_int + \if_meaning:w #1 \q_recursion_tail + \int_set_eq:NN \l_regex_current_char_int \c_minus_one + \else: + \int_set:Nn \l_regex_current_char_int {`#1} + \fi: + \regex_match_loop_case_hook: + } +\cs_new_protected_nopar:Npn \regex_match_loop_case_hook: { } +\cs_new_protected_nopar:Npn \regex_match_loop_caseless_hook: + { + \int_set_eq:NN \l_regex_case_changed_char_int \l_regex_current_char_int + \if_num:w \l_regex_current_char_int < \c_ninety_one + \if_num:w \l_regex_current_char_int < \c_sixty_five + \else: + \int_add:Nn \l_regex_case_changed_char_int { \c_thirty_two } + \fi: + \else: + \if_num:w \l_regex_current_char_int < \c_one_hundred_twenty_three + \if_num:w \l_regex_current_char_int < \c_ninety_seven + \else: + \int_sub:Nn \l_regex_case_changed_char_int { \c_thirty_two } + \fi: + \fi: + \fi: } \cs_new_protected_nopar:Npn \regex_action_start_wildcard:nn #1#2 { @@ -1167,7 +1262,10 @@ \regex_action_cost:n {#1} } \cs_new_protected_nopar:Npn \regex_action_cost:n #1 - { \regex_store_state:n {#1} } + { + \exp_args:Nf \regex_store_state:n %^^A optimize! + { \int_eval:n { \l_regex_current_state_int + #1 } } + } \cs_new_protected_nopar:Npn \regex_action_success: { \regex_last_match_empty:F @@ -1184,30 +1282,22 @@ } \cs_new_protected_nopar:Npn \regex_action_free:n #1 { - \regex_if_state_free:nT {#1} + \cs_set_nopar:Npx \regex_tmp:w { - \use:x - { - \int_set:Nn \l_regex_current_state_int {#1} - \regex_store_submatches:n { \l_regex_current_state_int } - \regex_state_use: - \int_set:Nn \l_regex_current_state_int - { \int_use:N \l_regex_current_state_int } - \tl_set:Nn \exp_not:N \l_regex_current_submatches_prop - { \exp_not:o \l_regex_current_submatches_prop } - } + \int_add:Nn \l_regex_current_state_int {#1} + \regex_state_use: + \int_set:Nn \l_regex_current_state_int + { \int_use:N \l_regex_current_state_int } + \tl_set:Nn \exp_not:N \l_regex_current_submatches_prop + { \exp_not:o \l_regex_current_submatches_prop } } + \regex_tmp:w } \cs_new_protected_nopar:Npn \regex_action_submatch:n #1 { \prop_put:Nno \l_regex_current_submatches_prop {#1} { \int_use:N \l_regex_current_step_int } - \regex_store_submatches:n { \l_regex_current_state_int } } -\cs_new_protected_nopar:Npn \regex_action_repeat_copy:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_repeat_move:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_no_repeat_copy:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_no_repeat_move:n { \ERROR } \cs_new_protected_nopar:Npn \regex_extract: { \seq_gclear:N \g_regex_submatches_seq @@ -1217,11 +1307,7 @@ \regex_extract_aux:nTF { ##1 } { \seq_gput_right:Nx \g_regex_submatches_seq - { - \str_from_to:Nnn \l_regex_query_str - { \l_regex_tmpa_tl } - { \l_regex_tmpb_tl } - } + { \regex_query_substr:NN \l_regex_tmpa_tl \l_regex_tmpb_tl } } { \seq_gput_right:Nn \g_regex_submatches_seq { } } } @@ -1253,9 +1339,13 @@ = \int_use:N \l_regex_max_state_int \l_regex_capturing_group_int = \int_use:N \l_regex_capturing_group_int - \bool_if:NTF \l_regex_look_behind_bool - { \bool_set_true:N \l_regex_look_behind_bool } - { \bool_set_false:N \l_regex_look_behind_bool } + \token_if_eq_meaning:NNT + \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + { + \cs_set_eq:NN \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + } \prg_stepwise_function:nnnN {1} {1} {\l_regex_max_state_int} \regex_set_aux:n @@ -1269,7 +1359,7 @@ \cs_new:Npn \regex_nfa:Nw #1 #2 \regex_nfa_end: { \msg_expandable_error:n { Automaton~#1 used~incorrectly. } } \cs_new_eq:NN \regex_nfa_end: \scan_stop: -\prg_new_protected_conditional:Npnn \regex_check_nfa:N #1 { TF } +\prg_new_protected_conditional:Npnn \regex_check_nfa:N #1 { T , TF } { \exp_after:wN \regex_check_nfa_aux:Nw #1 \q_stop } \cs_new:Npn \regex_check_nfa_aux:Nw #1 #2 \q_stop { @@ -1280,11 +1370,6 @@ \prg_return_false: \fi: } -\msg_new:nnn { regex } { not-nfa } - { - I~was~expecting~a~regular~expression~variable.\\ - Instead,~I~got~#1. - } \cs_new_protected_nopar:Npn \regex_use:N #1 { \exp_after:wN \use_none:nn #1 } \cs_new_protected:Npn \regex_user_aux:n #1 @@ -1296,7 +1381,7 @@ } \cs_new_protected_nopar:Npn \regex_return_after_group: { - \if_bool:N \l_regex_success_bool + \if_meaning:w \c_true_bool \l_regex_success_bool \group_insert_after:N \prg_return_true: \else: \group_insert_after:N \prg_return_false: @@ -1304,7 +1389,7 @@ } \cs_new_protected_nopar:Npn \regex_extract_after_group:N #1 { - \if_bool:N \l_regex_success_bool + \if_meaning:w \c_true_bool \l_regex_success_bool \regex_extract: \group_insert_after:N \seq_set_eq:NN \group_insert_after:N #1 @@ -1359,7 +1444,7 @@ } \cs_new_protected:Npn \regex_count:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1375,9 +1460,8 @@ \regex_count_after_group:N #3 } } - { } } -\cs_new_protected:Npn \regex_extract:nnN #1#2#3 +\cs_new_protected:Npn \regex_extract_once:nnN #1#2#3 { \regex_user_aux:n { @@ -1386,7 +1470,8 @@ \regex_extract_after_group:N #3 } } -\prg_new_protected_conditional:Npnn \regex_extract:nnN #1#2#3 { T , F , TF } +\prg_new_protected_conditional:Npnn \regex_extract_once:nnN #1#2#3 + { T , F , TF } { \regex_user_aux:n { @@ -1396,9 +1481,9 @@ \regex_return_after_group: } } -\cs_new_protected:Npn \regex_extract:NnN #1#2#3 +\cs_new_protected:Npn \regex_extract_once:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1407,9 +1492,9 @@ \regex_extract_after_group:N #3 } } - { } } -\prg_new_protected_conditional:Npnn \regex_extract:NnN #1#2#3 { T , F , TF } +\prg_new_protected_conditional:Npnn \regex_extract_once:NnN #1#2#3 + { T , F , TF } { \regex_check_nfa:NTF #1 { @@ -1423,6 +1508,48 @@ } { \prg_return_false: } } +\cs_new_protected:Npn \regex_extract_all:nnN #1#2#3 + { + \regex_user_aux:n + { + \seq_gclear:N \g_regex_extract_all_seq + \tl_set:Nn \l_regex_every_match_tl { \regex_extract_all_aux: } + \regex_build:n {#1} + \regex_match:n {#2} + \regex_extract_all_after_group:N #3 + } + } +\cs_new_protected:Npn \regex_extract_all:NnN #1#2#3 + { + \regex_check_nfa:NT #1 + { + \regex_user_aux:n + { + \seq_gclear:N \g_regex_extract_all_seq + \tl_set:Nn \l_regex_every_match_tl { \regex_extract_all_aux: } + \regex_use:N #1 + \regex_match:n {#2} + \regex_extract_all_after_group:N #3 + } + } + } +\cs_new_protected_nopar:Npn \regex_extract_all_aux: + { + \regex_extract: + \seq_gconcat:NNN \g_regex_extract_all_seq + \g_regex_extract_all_seq \g_regex_submatches_seq + \regex_match_once: + } +\cs_new_protected_nopar:Npn \regex_extract_all_after_group:N #1 + { + \seq_if_empty:NF \g_regex_extract_all_seq + { + \regex_extract: + \group_insert_after:N \seq_set_eq:NN + \group_insert_after:N #1 + \group_insert_after:N \g_regex_extract_all_seq + } + } \cs_new_protected:Npn \regex_split:nnN #1#2#3 { \regex_user_aux:n @@ -1436,7 +1563,7 @@ } \cs_new_protected:Npn \regex_split:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1447,7 +1574,6 @@ \regex_split_after_group:N #3 } } - { } } \cs_new_protected_nopar:Npn \regex_split_aux: { @@ -1459,9 +1585,8 @@ { \seq_gput_left:Nx \g_regex_submatches_seq { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \l_regex_tmpa_tl } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_tmpa_tl } } { \msg_error:nn { regex } { internal } } @@ -1480,9 +1605,8 @@ { \seq_gput_right:Nx \g_regex_split_seq { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \int_use:N \l_regex_current_step_int } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_current_step_int } } \group_insert_after:N \seq_set_eq:NN @@ -1494,40 +1618,57 @@ \str_aux_escape:NNNn \prg_do_nothing: \regex_replacement_escaped:N - \regex_replacement_raw:N + \prg_do_nothing: {#1} \tl_set_eq:NN \l_regex_replacement_tl \g_str_result_tl \tl_set:Nx \l_regex_replacement_tl { \l_regex_replacement_tl \prg_do_nothing: } } -\cs_new_nopar:Npn \regex_replacement_raw:N { \exp_not:N \prg_do_nothing: } \cs_new_nopar:Npn \regex_replacement_escaped:N #1 { - \if_num:w 9 < 1 #1 \exp_stop_f: - \exp_not:N \regex_replacement_escaped_ii:nN {#1} - \else: - #1 - \fi: + \regex_token_if_other_digit:NTF #1 + { + \exp_not:n + { \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } } {#1} + } + { + \token_if_eq_charcode:NNTF g #1 + { \exp_not:N \regex_replacement_submatch:w } + { #1 } + } } -\cs_new_nopar:Npn \regex_replacement_escaped_ii:nN #1#2 +\cs_new_nopar:Npn \regex_replacement_submatch:w #1 { - \regex_token_if_other_digit:NTF #2 - { \regex_replacement_escaped_ii:nN {#1#2} } - { \exp_not:N \seq_item:Nn \exp_not:N \g_regex_submatches_seq {#1} #2 } + \exp_after:wN \token_if_eq_meaning:NNTF \c_lbrace_str #1 + { \regex_replacement_submatch_aux:nN { } } + { + \regex_token_if_other_digit:NTF #1 + { \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } } + { \msg_expandable_error:n { \g misused~in~replacement~text. } } + #1 + } } -\prg_new_conditional:Npnn \regex_token_if_other_digit:N #1 { TF } +\cs_new_nopar:Npn \regex_replacement_submatch_aux:nN #1 #2 { - \if_num:w 9 < 1 \exp_not:N #1 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \regex_token_if_other_digit:NTF #2 + { \regex_replacement_submatch_aux:nN {#1#2} } + { + \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } {#1} + \exp_after:wN \token_if_eq_meaning:NNF \c_rbrace_str #2 + { + \msg_expandable_error:n { \g misused~in~replacement~text. } + #2 + } + } } \cs_new_protected_nopar:Npn \regex_replace_after_group:N #1 { - \group_insert_after:N \tl_set_eq:NN + \group_insert_after:N \tl_set:Nx \group_insert_after:N #1 - \group_insert_after:N \g_regex_replaced_str + \group_insert_after:N { + \group_insert_after:N \tl_to_str:N + \group_insert_after:N \g_regex_replaced_str + \group_insert_after:N } } \cs_new_protected:Npn \regex_replace_once_aux:Nn #1#2 { @@ -1539,15 +1680,16 @@ \regex_extract: \regex_extract_aux:nTF {0} { + \cs_set_nopar:Npn \regex_tmp:w + { \str_skip_do:nn { \l_regex_tmpb_tl } { } } \tl_gset:Nx \g_regex_replaced_str { - \str_from_to:Nnn \l_regex_query_str {0} { \l_regex_tmpa_tl } + \regex_query_substr:NN \c_zero \l_regex_tmpa_tl \l_regex_replacement_tl - \str_from_to:Nnn \l_regex_query_str - { \l_regex_tmpb_tl } { \c_max_int } + \exp_after:wN \regex_tmp:w \l_regex_query_other_str } } - { \tl_gset_eq:NN \g_regex_replaced_str \l_regex_query_str } + { \tl_gset_eq:NN \g_regex_replaced_str \l_regex_query_other_str } \group_end: } \cs_new_protected:Npn \regex_replace_once:nnN #1#2#3 @@ -1592,12 +1734,10 @@ \tl_gclear:N \g_regex_replaced_str #2 \exp_args:No \regex_match:n {#1} + \cs_set_nopar:Npn \regex_tmp:w + { \str_skip_do:nn { \l_regex_start_step_int } { } } \tl_gput_right:Nx \g_regex_replaced_str - { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \c_max_int } - } + { \exp_after:wN \regex_tmp:w \l_regex_query_other_str } \group_end: } \cs_new_protected_nopar:Npn \regex_replace_all_aux: @@ -1607,9 +1747,8 @@ { \tl_gput_right:Nx \g_regex_replaced_str { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \l_regex_tmpa_tl } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_tmpa_tl \l_regex_replacement_tl } } @@ -1632,6 +1771,26 @@ \regex_replacement:n {#2} } } +\msg_new:nnn { regex } { -998 } { Unsupported~construct } +\msg_new:nnn { regex } { -997 } + { The~regular~expression~is~too~large~(32768~states). } +\msg_new:nnn { regex } { 1 } { \iow_char:N\\~at~end~of~pattern } +\msg_new:nnn { regex } { 4 } + { Numbers~out~of~order~in~\iow_char:N\{\iow_char\}~quantifier. } +\msg_new:nnn { regex } { 6 } + { Missing~terminating~\iow_char:N\]~for~character~class } +\msg_new:nnn { regex } { 7 } + { Invalid~escape~sequence~in~character~class } +\msg_new:nnn { regex } { 8 } + { Range~out~of~order~in~character~class } +\msg_new:nnn { regex } { 22 } { Mismatched~parentheses } +\msg_new:nnn { regex } { 34 } + { Character~value~in~\iow_char:N\\x{...}~sequence~is~too~large } +\msg_new:nnn { regex } { not-nfa } + { + LaTeX~was~expecting~a~regular~expression~variable.\\ + Instead,~LaTeX~found~'#1'. + } %% %% %% End of file `l3regex-trace.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty index 5da00fdd3d0..c57f415bc47 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty @@ -46,113 +46,121 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{expl3} -\GetIdInfo$Id: l3regex.dtx 2895 2011-10-09 15:58:19Z joseph $ +\GetIdInfo$Id: l3regex.dtx 2943 2011-10-30 15:59:43Z bruno $ {L3 Experimental Regular Expressions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \RequirePackage{l3str} +\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 } \cs_new:Npn \regex_tmp:w { } \tl_new:N \g_regex_tmpa_tl \tl_new:N \l_regex_tmpa_tl \tl_new:N \l_regex_tmpb_tl \int_new:N \l_regex_tmpa_int -\tl_new:N \l_regex_pattern_str +\int_new:N \l_regex_tmpb_int \int_new:N \l_regex_max_state_int \int_new:N \l_regex_left_state_int \int_new:N \l_regex_right_state_int -\seq_new:N \l_regex_left_state_seq -\seq_new:N \l_regex_right_state_seq +\seq_new:N \l_regex_group_begin_seq +\seq_new:N \l_regex_group_end_seq \int_new:N \l_regex_capturing_group_int \seq_new:N \l_regex_capturing_group_seq \tl_new:N \l_regex_one_or_group_tl -\int_new:N \l_regex_repetition_int -\bool_new:N \l_regex_look_behind_bool -\tl_new:N \l_regex_look_behind_str \cs_new_eq:NN \regex_build_tmp_class:n \use_none:n \bool_new:N \l_regex_class_bool \tl_new:N \l_regex_class_tl \tl_const:Nn \c_regex_d_tl { - \regex_item_range:nn {48} {57} % 0--9 + \regex_item_range:nn { \c_forty_eight } { 57 } % 0--9 } \tl_const:Nn \c_regex_D_tl { - \regex_item_more:n {57} % 9 - \regex_item_range:nn {0} {47} % 0 + \regex_item_geq:n { \c_fifty_eight } % > `9 + \regex_item_range:nn { \c_zero } { 47 } % 0 } \tl_const:Nn \c_regex_h_tl { - \regex_item_equal:n {32} % space - \regex_item_equal:n {9} % tab + \regex_item_equal:n { \c_thirty_two } % space + \regex_item_equal:n { \c_nine } % tab } \tl_const:Nn \c_regex_H_tl { - \regex_item_neq:n {32} % space - \regex_item_neq:n {9} % tab - \regex_break_true:w + \regex_item_geq:n { 33 } % > space + \regex_item_range:nn { \c_ten } { 31 } % tab < ... < space + \regex_item_range:nn { \c_zero } { \c_eight } % < tab } \tl_const:Nn \c_regex_s_tl { - \regex_item_equal:n {32} % space - \regex_item_neq:n {11} % vtab - \regex_item_range:nn {9} {13} % tab, lf, vtab, ff, cr + \regex_item_equal:n { \c_thirty_two } % space + \regex_item_range:nn { \c_nine } { \c_ten } % tab, lf + \regex_item_range:nn { \c_twelve } { \c_thirteen } % ff, cr } \tl_const:Nn \c_regex_S_tl { - \regex_item_more:n {32} % > space - \regex_item_range:nn {14} {31} % tab < ... < space - \regex_item_range:nn {0} {8} % < tab - \regex_item_equal:n {11} % vtab + \regex_item_geq:n { 33 } % > space + \regex_item_range:nn { \c_fourteen } { 31 } % tab < ... < space + \regex_item_range:nn { \c_zero } { \c_eight } % < tab + \regex_item_equal:n { \c_eleven } % vtab } \tl_const:Nn \c_regex_v_tl { - \regex_item_range:nn {10} {13} % lf, vtab, ff, cr + \regex_item_range:nn { \c_ten } { \c_thirteen } % lf, vtab, ff, cr } \tl_const:Nn \c_regex_V_tl { - \regex_item_more:n {13} % cr - \regex_item_range:nn {0} {9} % < lf + \regex_item_geq:n { \c_fourteen } % >cr + \regex_item_range:nn { \c_zero } { \c_nine } % < lf } \tl_const:Nn \c_regex_w_tl { - \regex_item_range:nn {97} {122} % a--z - \regex_item_range:nn {65} {90} % A--Z - \regex_item_range:nn {48} {57} % 0--9 - \regex_item_equal:n {95} % _ + \regex_item_range:nn { \c_ninety_seven } { 122 } % a--z + \regex_item_range:nn { \c_sixty_five } { 90 } % A--Z + \regex_item_range:nn { \c_forty_eight } { 57 } % 0--9 + \regex_item_equal:n { 95 } % _ } \tl_const:Nn \c_regex_W_tl { - \regex_item_range:nn {0} {47} % <`0 - \regex_item_range:nn {58} {64} % (`9+1)--(`A-1) - \regex_item_range:nn {91} {94} % (`Z+1)--(`_-1) - \regex_item_equal:n {96} % ` - \regex_item_more:n {122} % z + \regex_item_range:nn { \c_zero } { 47 } % <`0 + \regex_item_range:nn { \c_fifty_eight } { 64 } % (`9+1)--(`A-1) + \regex_item_range:nn { \c_ninety_one } { 94 } % (`Z+1)--(`_-1) + \regex_item_equal:n { 96 } % ` + \regex_item_geq:n { \c_one_hundred_twenty_three } % z } \tl_const:Nn \c_regex_N_tl { - \regex_item_neq:n {10} % lf - \regex_break_true:w + \regex_item_geq:n { \c_eleven } % > lf + \regex_item_range:nn { \c_zero } { \c_nine } % < lf } -\tl_new:N \l_regex_query_str -\int_new:N \l_regex_start_step_int -\int_new:N \l_regex_current_char_int +\tl_new:N \l_regex_query_other_str \int_new:N \l_regex_current_step_int +\int_new:N \l_regex_start_step_int +\int_new:N \l_regex_success_step_int \int_new:N \l_regex_unique_step_int +\int_new:N \l_regex_current_char_int +\int_new:N \l_regex_last_char_int +\int_new:N \l_regex_case_changed_char_int +\bool_new:N \l_regex_caseless_bool \int_new:N \l_regex_current_state_int \prop_new:N \l_regex_current_submatches_prop +\prop_new:N \l_regex_success_submatches_prop \int_new:N \l_regex_max_index_int \tl_new:N \l_regex_every_match_tl +\bool_new:N \l_regex_success_bool \cs_new_protected:Npn \regex_last_match_empty_no:F #1 {#1} \cs_new_protected:Npn \regex_last_match_empty_yes:F { \int_compare:nNnF \l_regex_start_step_int = \l_regex_current_step_int } \cs_new_eq:NN \regex_last_match_empty:F \regex_last_match_empty_no:F -\bool_new:N \l_regex_success_bool \bool_new:N \l_regex_success_empty_bool -\int_new:N \l_regex_success_step_int -\prop_new:N \l_regex_success_submatches_prop \bool_new:N \l_regex_fresh_thread_bool \seq_new:N \g_regex_submatches_seq \int_new:N \g_regex_match_count_int +\seq_new:N \g_regex_extract_all_seq \seq_new:N \g_regex_split_seq \tl_new:N \l_regex_replacement_tl \tl_new:N \g_regex_replaced_str @@ -169,40 +177,43 @@ \tex_toks:D #1 \exp_after:wN { \tex_the:D \tex_toks:D \exp_after:wN #1 \regex_tmp:w } } -\cs_new_eq:NN \regex_if_tail_stop:N \quark_if_recursion_tail_stop:N -\cs_new_protected_nopar:Npn \regex_if_tail_error:Nn #1#2 - { \quark_if_recursion_tail_stop_do:Nn #1 { \regex_build_error:n {#2} } } -\cs_new_protected_nopar:Npn \regex_build_error:n #1 +\cs_new_nopar:Npn \regex_query_substr:NN #1#2 { - \msg_error:nnxx { regex } { build-error } {\int_eval:n{#1}} - { - \prg_case_int:nnn {#1} - { - {-999} {File~not~found} - {-998} {Unsupported~construct} - {-997} {The~regular~expression~is~too~large~(32768~states).} - {1} {\iow_char:N\\~at~end~of~pattern } - {4} {Numbers~out~of~order~in~\iow_char:N\{\iow_char\}~quantifier.} - {6} {Missing~terminating~\iow_char:N\]~for~character~class } - {7} {Invalid~escape~sequence~in~character~class} - {8} {Range~out~of~order~in~character~class} - {22} {Mismatched~parentheses} - {34} {Character~value~in~\iow_char:N\\x{...}~sequence~is~too~large} - } - { Internal~bug. } - } + \exp_after:wN \regex_query_substr_aux:NN + \exp_after:wN #1 + \exp_after:wN #2 + \l_regex_query_other_str + \q_stop + } +\cs_new:Npn \regex_query_substr_aux:NN #1#2 + { + \str_skip_do:nn {#1} + { \str_collect_do:nn { #2 - #1 } { \use_i_delimit_by_q_stop:nw } } + } +\cs_new_protected_nopar:Npn \regex_seq_pop:N #1 + { + \seq_pop:NN #1 \l_regex_tmpa_tl + \l_regex_tmpa_tl + } +\cs_new_protected_nopar:Npn \regex_seq_get:N #1 + { + \seq_get:NN #1 \l_regex_tmpa_tl + \l_regex_tmpa_tl } -\msg_new:nnn { regex } { build-error } { (error~#1): ~ #2 } -\cs_new_nopar:Npn \regex_break_true:w #1 \regex_break_point:TF #2 #3 {#2} -\cs_new_nopar:Npn \regex_break_false:w #1 \regex_break_point:TF #2 #3 {#3} -\cs_new_eq:NN \regex_break_point:TF \use_ii:nn -\cs_new_nopar:Npn \regex_item_equal:n #1 +\cs_new_protected_nopar:Npn \regex_item_dot:T + { \int_compare:nNnF \l_regex_current_char_int = \c_minus_one } +\cs_new_protected_nopar:Npn \regex_break_true:w + #1 \regex_break_point:TF #2 #3 {#2} +\cs_new_protected_nopar:Npn \regex_break_false:w + #1 \regex_break_point:TF #2 #3 {#3} +\cs_new_protected_nopar:Npn \regex_break_point:TF #1 #2 { #2 } +\cs_new_protected_nopar:Npn \regex_item_caseful_equal:n #1 { \if_num:w #1 = \l_regex_current_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_range:nn #1 #2 +\cs_new_protected_nopar:Npn \regex_item_caseful_range:nn #1 #2 { \reverse_if:N \if_num:w #1 > \l_regex_current_char_int \reverse_if:N \if_num:w #2 < \l_regex_current_char_int @@ -210,24 +221,60 @@ \fi: \fi: } -\cs_new_nopar:Npn \regex_item_less:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseful_geq:n #1 { - \if_num:w #1 > \l_regex_current_char_int + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_more:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseless_equal:n #1 { - \if_num:w #1 < \l_regex_current_char_int + \if_num:w #1 = \l_regex_current_char_int + \exp_after:wN \regex_break_true:w + \fi: + \if_num:w #1 = \l_regex_case_changed_char_int \exp_after:wN \regex_break_true:w \fi: } -\cs_new_nopar:Npn \regex_item_neq:n #1 +\cs_new_protected_nopar:Npn \regex_item_caseless_range:nn #1 #2 { - \if_num:w #1 = \l_regex_current_char_int - \exp_after:wN \regex_break_false:w + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int + \reverse_if:N \if_num:w #2 < \l_regex_current_char_int + \exp_after:wN \exp_after:wN \exp_after:wN \regex_break_true:w + \fi: + \fi: + \reverse_if:N \if_num:w #1 > \l_regex_case_changed_char_int + \reverse_if:N \if_num:w #2 < \l_regex_case_changed_char_int + \exp_after:wN \exp_after:wN \exp_after:wN \regex_break_true:w + \fi: \fi: } +\cs_new_protected_nopar:Npn \regex_item_caseless_geq:n #1 + { + \reverse_if:N \if_num:w #1 > \l_regex_current_char_int + \exp_after:wN \regex_break_true:w + \fi: + \reverse_if:N \if_num:w #1 > \l_regex_case_changed_char_int + \exp_after:wN \regex_break_true:w + \fi: + } +\cs_new:Npn \regex_item_equal:n { \regex_item_caseful_equal:n } +\cs_new:Npn \regex_item_range:nn { \regex_item_caseful_range:nn } +\cs_new:Npn \regex_item_geq:n { \regex_item_caseful_geq:n } +\cs_new_protected_nopar:Npn \regex_build_caseless: + { + \bool_set_true:N \l_regex_caseless_bool + \cs_set:Npn \regex_item_equal:n { \regex_item_caseless_equal:n } + \cs_set:Npn \regex_item_range:nn { \regex_item_caseless_range:nn } + \cs_set:Npn \regex_item_geq:n { \regex_item_caseless_geq:n } + } +\cs_new_protected_nopar:Npn \regex_build_caseful: + { + \bool_set_false:N \l_regex_caseless_bool + \cs_set:Npn \regex_item_equal:n { \regex_item_caseful_equal:n } + \cs_set:Npn \regex_item_range:nn { \regex_item_caseful_range:nn } + \cs_set:Npn \regex_item_geq:n { \regex_item_caseful_geq:n } + } \cs_new_protected:Npn \regex_get_digits:nw #1 { \tex_afterassignment:D \regex_tmp:w @@ -235,65 +282,71 @@ { \exp_not:n {#1} { \if_false: } } \fi: - \regex_get_digits_aux:N + \regex_get_digits_aux:NN } -\cs_new_nopar:Npn \regex_get_digits_aux:N #1 +\cs_new_nopar:Npn \regex_get_digits_aux:NN #1#2 { - \if_num:w 9 < 1 \exp_not:N #1 \exp_stop_f: - \else: - \if_charcode:w \c_space_token \exp_not:N #1 + \if_meaning:w \regex_build_raw:N #1 + \if_charcode:w \c_space_token \exp_not:N #2 \else: - \regex_get_digits_end:w + \if_num:w 9 < 1 \exp_not:N #2 \exp_stop_f: + #2 + \else: + \regex_get_digits_end:w #1 #2 + \fi: \fi: + \else: + \regex_get_digits_end:w #1 #2 \fi: - #1 \regex_get_digits_aux:N + \regex_get_digits_aux:NN } -\cs_new_nopar:Npn \regex_get_digits_end:w - \fi: \fi: #1 \regex_get_digits_aux:N +\cs_new_nopar:Npn \regex_get_digits_end:w #1 \fi: #2 \regex_get_digits_aux:NN { - \fi: \fi: + \fi: #2 \if_false: { { \fi: } } #1 } +\prg_new_conditional:Npnn \regex_token_if_other_digit:N #1 { TF } + { + \if_num:w \c_nine < 1 \exp_not:N #1 \exp_stop_f: + \prg_return_true: \else: \prg_return_false: \fi: + } \prg_new_conditional:Npnn \regex_aux_char_if_special:N #1 { TF } { - \if_num:w `#1 < 97 \exp_stop_f: - \if_num:w `#1 < 58 \exp_stop_f: - \if_num:w \int_eval:w (`#1 - \c_eight)/\c_sixteen = \c_two - \prg_return_true: - \else: - \prg_return_false: - \fi: + \if_num:w `#1 < \c_ninety_one + \if_num:w `#1 < \c_fifty_eight + \if_num:w `#1 < \c_forty_eight + \if_num:w `#1 < \c_thirty_two + \prg_return_false: \else: \prg_return_true: \fi: + \else: \prg_return_false: \fi: \else: - \if_num:w \int_eval:w `#1 / 26 = \c_three - \prg_return_false: - \else: - \prg_return_true: - \fi: + \if_num:w `#1 < \c_sixty_five + \prg_return_true: \else: \prg_return_false: \fi: \fi: \else: - \if_num:w \int_eval:w `#1 / \c_five = 25 \exp_stop_f: - \prg_return_true: + \if_num:w `#1 < \c_one_hundred_twenty_three + \if_num:w `#1 < \c_ninety_seven + \prg_return_true: \else: \prg_return_false: \fi: \else: - \prg_return_false: + \if_num:w `#1 < \c_one_hundred_twenty_seven + \prg_return_true: \else: \prg_return_false: \fi: \fi: \fi: } \prg_new_conditional:Npnn \regex_aux_char_if_alphanumeric:N #1 { TF } { - \if_num:w `#1 < 91 \exp_stop_f: - \if_num:w `#1 < 65 \exp_stop_f: - \if_num:w \c_nine < 1 #1 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \if_num:w `#1 < \c_ninety_one + \if_num:w `#1 < \c_fifty_eight + \if_num:w `#1 < \c_forty_eight + \prg_return_false: \else: \prg_return_true: \fi: \else: - \prg_return_true: + \if_num:w `#1 < \c_sixty_five + \prg_return_false: \else: \prg_return_true: \fi: \fi: \else: - \if_num:w \int_eval:w (`#1-\c_six)/26 = \c_four - \prg_return_true: + \if_num:w `#1 < \c_one_hundred_twenty_three + \if_num:w `#1 < \c_ninety_seven + \prg_return_false: \else: \prg_return_true: \fi: \else: \prg_return_false: \fi: @@ -301,8 +354,8 @@ } \cs_new_protected_nopar:Npn \regex_build_new_state: { - \int_compare:nNnTF \l_regex_max_state_int > {32766} - { \regex_build_error:n {-997} } + \int_compare:nNnTF \l_regex_max_state_int > { 32766 } + { \msg_error:nn { regex } { -997 } } { \int_incr:N \l_regex_max_state_int \tex_toks:D \l_regex_max_state_int { \s_regex_toks } @@ -314,15 +367,15 @@ { \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int - { #1 { \int_use:N #2 } } + { #1 { \int_eval:n { #2 - \l_regex_left_state_int } } } } \cs_new_protected_nopar:Npn \regex_build_transitions_aux:NNNN #1#2#3#4 { \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { - #1 { \int_use:N #2 } - #3 { \int_use:N #4 } + #1 { \int_eval:n { #2 - \l_regex_left_state_int } } + #3 { \int_eval:n { #4 - \l_regex_left_state_int } } } } \cs_new_protected:Npn \regex_build:n #1 @@ -363,25 +416,19 @@ \cs_set_eq:NN \regex_build_control:N \regex_build_default_control:N \cs_set_eq:NN \regex_build_raw:N \regex_build_default_raw:N \int_set_eq:NN \l_regex_capturing_group_int \c_zero - \int_zero:N \l_regex_left_state_int - \int_zero:N \l_regex_right_state_int \int_zero:N \l_regex_max_state_int \regex_build_new_state: \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_action_start_wildcard:nn - { \int_use:N \l_regex_left_state_int } - { \int_use:N \l_regex_right_state_int } - } + { \regex_action_start_wildcard:nn {0} {1} } } \cs_new_protected_nopar:Npn \regex_build_end: { \seq_if_empty:NF \l_regex_capturing_group_seq { - \regex_build_error:n {22} + \msg_error:nn { regex } {22} \prg_replicate:nn - { \seq_length:N \l_regex_capturing_group_seq } % ( + { \seq_length:N \l_regex_capturing_group_seq } { \regex_build_close_aux: \regex_build_group_: } } \regex_toks_put_right:Nx \l_regex_right_state_int @@ -399,7 +446,13 @@ \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \int_compare:nNnT {#1} = \l_regex_current_step_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_protected_nopar:cpn { regex_build_$: } % $ @@ -409,71 +462,72 @@ { \exp_not:N \int_compare:nNnT \c_minus_one = \l_regex_current_char_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_eq:Nc \regex_build_Z: { regex_build_$: } %$ \cs_new_eq:Nc \regex_build_z: { regex_build_$: } %$ \cs_new_protected_nopar:Npn \regex_build_b: { - \bool_set_true:N \l_regex_look_behind_bool \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \regex_if_word_boundary:TF - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } { } } } \cs_new_protected_nopar:Npn \regex_build_B: { - \bool_set_true:N \l_regex_look_behind_bool \regex_build_new_state: \regex_toks_put_right:Nx \l_regex_left_state_int { \exp_not:N \regex_if_word_boundary:TF { } - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } } \cs_new_protected_nopar:Npn \regex_if_word_boundary:TF { - \tl_if_empty:NTF \l_regex_look_behind_str - { \c_regex_w_tl } - { - \group_begin: - \cs_set_nopar:Npx \regex_tmp:w - { - \int_set:Nn \l_regex_current_char_int - { ` \str_head:N \l_regex_look_behind_str } - } - \regex_tmp:w - \c_regex_w_tl - \regex_break_point:TF - { \group_end: \c_regex_W_tl } - { \group_end: \c_regex_w_tl } - } + \group_begin: + \int_set_eq:NN \l_regex_current_char_int \l_regex_last_char_int + \c_regex_w_tl + \regex_break_point:TF + { \group_end: \c_regex_W_tl \regex_item_equal:n { -1 } } + { \group_end: \c_regex_w_tl } \regex_break_point:TF } \cs_new_protected_nopar:Npn \regex_build_default_raw:N #1 { \cs_set:Npx \regex_build_tmp_class:n ##1 { - \exp_not:n { \exp_not:N \if_num:w } - \int_value:w `#1 = \l_regex_current_char_int - \regex_action_cost:n { ##1 } - \exp_not:n { \exp_not:N \fi: } + \regex_item_equal:n { \int_value:w `#1 } + \regex_break_point:TF { \regex_action_cost:n { ##1 } } { } } \regex_build_one_quantifier: } \cs_new_protected_nopar:cpn { regex_build_.: } { \cs_set:Npn \regex_build_tmp_class:n ##1 - { - \exp_not:N \if_num:w \c_minus_one < \l_regex_current_char_int - \regex_action_cost:n {##1} - \exp_not:N \fi: - } + { \regex_item_dot:T { \regex_action_cost:n {##1} } } \regex_build_one_quantifier: } \cs_new_protected_nopar:Npn \regex_build_char_type:N #1 @@ -481,9 +535,7 @@ \cs_set:Npn \regex_build_tmp_class:n ##1 { \exp_not:N #1 - \exp_not:N \regex_break_point:TF - { \regex_action_cost:n {##1} } - { } + \regex_break_point:TF { \regex_action_cost:n {##1} } { } } \regex_build_one_quantifier: } @@ -518,16 +570,8 @@ { \exp_not:o \l_regex_class_tl \bool_if:NTF \l_regex_class_bool - { - \exp_not:N \regex_break_point:TF - { \regex_action_cost:n {##1} } - { } - } - { - \exp_not:N \regex_break_point:TF - { } - { \regex_action_cost:n {##1} } - } + { \regex_break_point:TF { \regex_action_cost:n {##1} } { } } + { \regex_break_point:TF { } { \regex_action_cost:n {##1} } } } \regex_build_one_quantifier: } @@ -553,7 +597,7 @@ \cs_new_protected_nopar:Npn \regex_class_single:N #1 { \tl_put_right:Nx \l_regex_class_tl - { \exp_not:N \regex_item_equal:n { \int_value:w `#1 } } + { \regex_item_equal:n { \int_value:w `#1 } } } \cs_new_protected_nopar:Npn \regex_class_range:Nw #1#2#3 { @@ -572,14 +616,14 @@ \cs_new_protected_nopar:Npn \regex_class_range_put:NN #1#2 { \if_num:w `#1 > `#2 \exp_stop_f: - \regex_build_error:n {8} + \msg_error:nn { regex } {8} \else: \tl_put_right:Nx \l_regex_class_tl { \if_num:w `#1 = `#2 \exp_stop_f: - \exp_not:N \regex_item_equal:n + \regex_item_equal:n \else: - \exp_not:N \regex_item_range:nn { \int_value:w `#1 } + \regex_item_range:nn { \int_value:w `#1 } \fi: { \int_value:w `#2 } } @@ -651,26 +695,29 @@ \exp_not:N \regex_build_raw:N \c_lbrace_str #1#2 } } -\cs_new_protected_nopar:Npn \regex_build_quantifier_lbrace:nnw #1#2#3 +\cs_new_protected_nopar:Npn \regex_build_quantifier_lbrace:nnw #1#2#3#4 { - \str_if_eq:xxTF { \exp_not:N #3 } { \c_rbrace_str } + \str_if_eq:xxTF + { \exp_not:n {#3#4} } + { \exp_not:N \regex_build_control:N \c_rbrace_str } { \tl_if_empty:nTF {#2} - { \regex_build_quantifier_aux:nnN { {#1} {\c_max_int} } {nn} } + { \regex_build_quantifier_aux:nnNN { {#1} } { n* } } { \int_compare:nNnT {#1} > {#2} - { \regex_build_error:n {4} } - \regex_build_quantifier_aux:nnN { {#1} {#2} } {nn} + { \msg_error:nn { regex } {4} } + \regex_build_quantifier_aux:nnNN { {#1} {#2} } { nn } } } { \regex_build_quantifier_end:n { } \use:x { - \exp_not:n { \exp_args:No \tl_map_function:nN } - { \c_lbrace_str #1 #2 , } - \regex_build_raw:N + \exp_args:No \tl_map_function:nN + { \c_lbrace_str #1 , #2 } + \regex_build_raw:N } + #3 #4 } } \cs_new_protected_nopar:Npn \regex_build_quantifier_end:n #1 @@ -726,71 +773,27 @@ \regex_action_free:n \l_regex_tmpa_int } \cs_new_protected_nopar:Npn \regex_build_one_n: #1 - { - \int_set_eq:NN \l_regex_tmpa_int \l_regex_right_state_int - \regex_build_new_state: - \regex_build_new_state: - \regex_toks_put_right:Nx \l_regex_tmpa_int - { %^^A safe \if nesting? - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \else: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } - \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_build_tmp_class:n - { \int_use:N \l_regex_tmpa_int } - } - } + { \prg_replicate:nn {#1} { \regex_build_one_: } } \cs_new_eq:cN { regex_build_one_n?: } \regex_build_one_n: -\cs_new_protected_nopar:Npn \regex_build_one_nn: #1#2 +\cs_new_protected_nopar:cpx { regex_build_one_n*: } #1 { - \regex_build_one_nn_aux:nn {#1} - { - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \regex_action_repeat_copy:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \fi: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - } + \exp_not:N \prg_replicate:nn {#1} { \exp_not:N \regex_build_one_: } + \exp_not:c { regex_build_one_*: } } -\cs_new_protected_nopar:cpn { regex_build_one_nn?: } #1#2 +\cs_new_protected_nopar:cpx { regex_build_one_n*?: } #1 { - \regex_build_one_nn_aux:nn {#1} - { - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \fi: - } + \exp_not:N \prg_replicate:nn {#1} { \exp_not:N \regex_build_one_: } + \exp_not:c { regex_build_one_*?: } } -\cs_new_protected_nopar:Npn \regex_build_one_nn_aux:nn #1#2 +\cs_new_protected_nopar:Npn \regex_build_one_nn_aux:Nnn #1#2#3 { - \int_set_eq:NN \l_regex_tmpa_int \l_regex_right_state_int - \regex_build_new_state: - \regex_build_new_state: - \regex_toks_put_right:Nx \l_regex_tmpa_int - { - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \regex_action_repeat_move:n - { \int_use:N \l_regex_left_state_int } - \exp_not:N \else: - #2 - \exp_not:N \fi: - } - \regex_toks_put_right:Nx \l_regex_left_state_int - { - \regex_build_tmp_class:n - { \int_use:N \l_regex_tmpa_int } - } + \prg_replicate:nn {#2} { \regex_build_one_: } + \prg_replicate:nn {#3-#2} {#1} } +\cs_new_protected_nopar:Npx \regex_build_one_nn: + { \regex_build_one_nn_aux:Nnn \exp_not:c { regex_build_one_?: } } +\cs_new_protected_nopar:cpx { regex_build_one_nn?: } + { \regex_build_one_nn_aux:Nnn \exp_not:c { regex_build_one_??: } } \cs_new_protected_nopar:cpn { regex_build_(: } #1#2 { \str_if_eq:nnTF { #1 #2 } { \regex_build_control:N ? } @@ -806,10 +809,19 @@ \cs_new_protected_nopar:Npn \regex_build_open_aux: { \regex_build_new_state: - \seq_push:Nx \l_regex_left_state_seq - { \int_use:N \l_regex_left_state_int } - \seq_push:Nx \l_regex_right_state_seq - { \int_use:N \l_regex_right_state_int } + \seq_push:Nx \l_regex_group_begin_seq + { + \int_set:Nn \l_regex_left_state_int + { \int_use:N \l_regex_left_state_int } + } + \bool_if:NTF \l_regex_caseless_bool + { \seq_push:Nn \l_regex_group_end_seq { \regex_build_caseless: } } + { \seq_push:Nn \l_regex_group_end_seq { \regex_build_caseful: } } + \seq_push:Nx \l_regex_group_end_seq + { + \int_set:Nn \l_regex_right_state_int + { \int_use:N \l_regex_right_state_int } + } \regex_build_begin_alternation: } \cs_new_protected_nopar:cpn { regex_build_|: } @@ -820,7 +832,7 @@ \cs_new_protected_nopar:cpn { regex_build_): } { \seq_if_empty:NTF \l_regex_capturing_group_seq - { \regex_build_error:n {22} } + { \msg_error:nn { regex } { 22 } } { \regex_build_close_aux: \regex_build_group_quantifier: @@ -829,30 +841,41 @@ \cs_new_protected_nopar:Npn \regex_build_close_aux: { \regex_build_end_alternation: - \seq_pop:NN \l_regex_left_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_left_state_int \l_regex_tmpa_tl - \seq_pop:NN \l_regex_right_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_right_state_int \l_regex_tmpa_tl + \regex_seq_pop:N \l_regex_group_begin_seq + \regex_seq_pop:N \l_regex_group_end_seq + \regex_seq_pop:N \l_regex_group_end_seq } \cs_new_protected_nopar:Npn \regex_build_begin_alternation: { \regex_build_new_state: - \seq_get:NN \l_regex_left_state_seq \l_regex_tmpa_tl - \int_set:Nn \l_regex_left_state_int \l_regex_tmpa_tl + \regex_seq_get:N \l_regex_group_begin_seq \regex_toks_put_right:Nx \l_regex_left_state_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } \cs_new_protected_nopar:Npn \regex_build_end_alternation: { - \seq_get:NN \l_regex_right_state_seq \l_regex_tmpa_tl - \regex_toks_put_right:Nx \l_regex_right_state_int - { \regex_action_free:n { \l_regex_tmpa_tl } } + \int_set_eq:NN \l_regex_left_state_int \l_regex_right_state_int + \regex_seq_get:N \l_regex_group_end_seq + \regex_toks_put_right:Nx \l_regex_left_state_int + { + \regex_action_free:n + { + \int_eval:n + { \l_regex_right_state_int - \l_regex_left_state_int } + } + } } \cs_new_protected_nopar:Npn \regex_build_special_group:NN #1#2 { \cs_if_exist_use:cF { regex_build_special_group_\token_to_str:N #2 : } { - \regex_build_error:n { -998 } + \msg_error:nn { regex } { -998 } \regex_build_control:N ( % ) \regex_build_raw:N ? #1 #2 @@ -863,6 +886,40 @@ \seq_push:Nx \l_regex_capturing_group_seq { * } \regex_build_open_aux: } +\cs_new_protected_nopar:Npn \regex_build_special_group_i: + { + \regex_build_options:NNN + + \regex_build_raw:N i + } +\cs_new_protected_nopar:cpn { regex_build_special_group_-: } + { + \regex_build_options:NNN - + } +\cs_new_protected_nopar:Npn \regex_build_options:NNN #1#2#3 + { + \token_if_eq_meaning:NNTF \regex_build_raw:N #2 + { + \cs_if_exist_use:cF { regex_build_option_#1#3: } + { \msg_error:nnx { regex } { unknown-option } { #3 } } + \regex_build_options:NNN #1 + } + { + \prg_case_str:nnn { #3 } + { % ( + { ) } { } + { - } { \regex_build_options:NNN - } + } + { \msg_error:nnx { regex } { invalid-in-option } { #3 } } + } + } +\cs_new_protected_nopar:cpn { regex_build_option_+i: } + { + \regex_build_caseless: + \cs_set_eq:NN \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + } +\cs_new_protected_nopar:cpn { regex_build_option_-i: } + { \regex_build_caseful: } \cs_new_protected_nopar:Npn \regex_build_group_quantifier: { \tl_set:Nn \l_regex_one_or_group_tl { group } @@ -891,21 +948,33 @@ \int_set_eq:NN \l_regex_tmpa_int \l_regex_left_state_int \regex_build_new_state: \tex_toks:D \l_regex_right_state_int = \tex_toks:D \l_regex_tmpa_int - \use:x + \regex_toks_put_left:Nx \l_regex_right_state_int + { + \int_set:Nn \l_regex_current_state_int + { \int_use:N \l_regex_tmpa_int } % ^^A here we lie! + } + \cs_set:Npx \regex_tmp:w { \tex_toks:D \l_regex_tmpa_int - { \s_regex_toks #1 { \int_use:N \l_regex_right_state_int } } + { + \s_regex_toks + #1 { \int_eval:n { \l_regex_right_state_int - \l_regex_tmpa_int } } + } } + \regex_tmp:w \regex_build_group_submatches:NN \l_regex_right_state_int \l_regex_left_state_int - \int_set_eq:NN \l_regex_right_state_int \l_regex_left_state_int } \cs_new_protected_nopar:Npn \regex_build_group_qs_aux:NN #1#2 { \regex_build_group_shift:N \regex_action_free:n + \int_set_eq:NN \l_regex_right_state_int \l_regex_left_state_int \regex_build_transition_aux:NN \regex_action_free:n #1 #2 \l_regex_tmpa_int - { \regex_action_free:n { \int_use:N \l_regex_right_state_int } } + { + \regex_action_free:n + { \int_eval:n { \l_regex_right_state_int - \l_regex_tmpa_int } } + } } \cs_new_protected_nopar:cpn { regex_build_group_?: } { @@ -945,77 +1014,63 @@ \regex_action_free:n \l_regex_right_state_int \regex_action_free:n \l_regex_tmpa_int } -\cs_new_protected_nopar:Npn \regex_build_group_n: #1 +\cs_new_protected_nopar:Npn \regex_build_group_n_aux:n #1 { - \regex_build_group_shift:N \regex_action_repeat_move:n - \regex_build_transition_aux:NN - \regex_action_free:n \l_regex_tmpa_int - \use:x + \regex_toks_put_right:Nx \l_regex_right_state_int { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \regex_action_no_repeat_move:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } + \regex_action_free:n + { \int_eval:n { \l_regex_max_state_int - \l_regex_left_state_int } } } - } -\cs_new_eq:cN { regex_build_group_n?: } \regex_build_group_n: -\cs_new_protected_nopar:Npn \regex_build_group_nn: #1#2 - { - \regex_build_group_shift:N \regex_action_repeat_move:n - \regex_build_transition_aux:NN - \regex_action_free:n \l_regex_tmpa_int - \use:x + \int_set_eq:NN \l_regex_tmpa_int \l_regex_left_state_int + \int_set:Nn \l_regex_tmpb_int { \l_regex_max_state_int + \c_one } + \int_set:Nn \l_regex_max_state_int { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \fi: - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \fi: - } + \l_regex_left_state_int - \c_one + + #1 * ( \l_regex_max_state_int - \l_regex_left_state_int + \c_one ) + } + \int_until_do:nNnn \l_regex_tmpb_int > \l_regex_max_state_int + { + \tex_toks:D \l_regex_tmpb_int = \tex_toks:D \l_regex_tmpa_int + \int_incr:N \l_regex_tmpa_int + \int_incr:N \l_regex_tmpb_int } } -\cs_new_protected_nopar:cpn { regex_build_group_nn?: } #1#2 - { - \regex_build_group_shift:N \regex_action_repeat_move:n +\cs_new_protected_nopar:Npn \regex_build_group_n: #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} \regex_build_transition_aux:NN + \regex_action_free:n \l_regex_right_state_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int + } +\cs_new_eq:cN { regex_build_group_n?: } \regex_build_group_n: +\cs_new_protected_nopar:cpn { regex_build_group_n*: } #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} + \regex_build_transitions_aux:NNNN \regex_action_free:n \l_regex_tmpa_int - \use:x - { - \tex_toks:D \l_regex_tmpa_int - { - \s_regex_toks - \exp_not:N \if_num:w #1 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \else: - \regex_action_no_repeat_copy:n - { \int_use:N \l_regex_right_state_int } - \exp_not:N \if_num:w #2 > \l_regex_repetition_int - \tex_the:D \tex_toks:D \l_regex_tmpa_int - \exp_not:N \fi: - \exp_not:N \fi: - } - } + \regex_action_free:n \l_regex_right_state_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int } -\cs_new_protected:Npn \regex_if_state_free:nT #1 - { - \if_num:w \tex_dimen:D #1 = \l_regex_unique_step_int - \exp_after:wN \use_none:n - \else: - \exp_after:wN \use:n - \fi: +\cs_new_protected_nopar:cpn { regex_build_group_n*?: } #1 + { % ^^A todo: catch case #1 <= 0. + \regex_build_group_n_aux:n {#1} + \regex_build_transitions_aux:NNNN + \regex_action_free:n \l_regex_right_state_int + \regex_action_free:n \l_regex_tmpa_int + \regex_build_group_submatches:NN + \l_regex_tmpa_int \l_regex_left_state_int + } +\cs_new_protected_nopar:Npn \regex_build_group_nn: #1#2 + { % ^^A Not Implemented Yet! + \msg_expandable_error:n { Quantifier~{m,n}~not~implemented~yet } + \use:c { regex_build_group_n*: } {#1} + } +\cs_new_protected_nopar:cpn { regex_build_group_nn?: } #1#2 + { % ^^A Not Implemented Yet! + \msg_expandable_error:n { Quantifier~{m,n}~not~implemented~yet } + \use:c { regex_build_group_n*?: } {#1} } \cs_new_protected:Npn \regex_store_state:n #1 { @@ -1023,23 +1078,24 @@ \tex_skip:D \l_regex_max_index_int #1 sp \scan_stop: \regex_store_submatches:n {#1} } -\cs_new_protected_nopar:Npn \regex_state_use_submatches: +\cs_new_protected_nopar:Npn \regex_state_use_with_submatches: { \regex_state_use_aux:n { } } \cs_new_protected_nopar:Npn \regex_state_use: { \regex_state_use_aux:n { \exp_after:wN \regex_state_use_aux_ii:w } } -\cs_new:Npn \regex_state_use_aux_ii:w #1 \s_regex_toks { } -\cs_new_protected:Npn \regex_state_use_aux:n #1 - { - \regex_if_state_free:nT { \l_regex_current_state_int } - { - \tex_dimen:D \l_regex_current_state_int - = \l_regex_unique_step_int sp \scan_stop: - #1 \tex_the:D \tex_toks:D \l_regex_current_state_int \scan_stop: - } +\cs_new_nopar:Npn \regex_state_use_aux_ii:w #1 \s_regex_toks { } +\cs_new_protected_nopar:Npn \regex_state_use_aux:n #1 + { + \if_num:w \tex_dimen:D \l_regex_current_state_int + < \l_regex_unique_step_int + \tex_dimen:D \l_regex_current_state_int + = \l_regex_unique_step_int sp \scan_stop: + #1 \tex_the:D \tex_toks:D \exp_after:wN \l_regex_current_state_int + \fi: + \scan_stop: } \cs_new_protected_nopar:Npn \regex_disable_submatches: { - \cs_set_eq:NN \regex_state_use_submatches: \regex_state_use: + \cs_set_eq:NN \regex_state_use_with_submatches: \regex_state_use: \cs_set_eq:NN \regex_store_submatches:n \regex_protected_use_none:n \cs_set_eq:NN \regex_action_submatches:n @@ -1048,55 +1104,73 @@ \cs_new_protected:Npn \regex_protected_use_none:n #1 { } \cs_new_protected:Npn \regex_store_submatches:n #1 { - \exp_after:wN \regex_store_submatches_aux:Nw - \exp_after:wN \l_regex_current_submatches_prop - \tex_the:D \tex_toks:D #1 \scan_stop: \q_stop - { #1 } + \tex_toks:D #1 \exp_after:wN + { + \tex_romannumeral:D + \exp_after:wN \regex_store_submatches_aux:w + \tex_the:D \tex_toks:D #1 + } } -\cs_new_protected:Npn \regex_store_submatches_aux:Nw #1 #2 \s_regex_toks +\cs_new_protected:Npn \regex_store_submatches_aux:w #1 \s_regex_toks { - \exp_args:No \regex_store_submatches_aux_ii:wnnwwn { #1 } - #2 - \regex_state_submatches:nn { \c_minus_one } { \q_prop } + \regex_store_submatches_aux_ii:Nnnw + #1 + \regex_state_submatches:nn \c_minus_one \q_prop \s_regex_toks } -\cs_new_protected:Npn \regex_store_submatches_aux_ii:wnnwwn - #1 \regex_state_submatches:nn #2#3 #4 \s_regex_toks #5 \q_stop #6 +\cs_new_protected:Npn \regex_store_submatches_aux_ii:Nnnw + \regex_state_submatches:nn #1 #2 #3 \s_regex_toks { - \tex_toks:D #6 \exp_after:wN + \exp_after:wN \c_zero + \exp_after:wN \regex_state_submatches:nn \exp_after:wN { - \exp_after:wN \regex_state_submatches:nn \exp_after:wN - { \int_value:w \int_eval:w \l_regex_unique_step_int + \c_one } - { #1 } - \regex_state_submatches:nn {#2} {#3} - \s_regex_toks - #5 + \int_value:w \int_eval:w + \l_regex_unique_step_int + \c_one + \exp_after:wN } + \exp_after:wN { \l_regex_current_submatches_prop } + \regex_state_submatches:nn {#1} {#2} + \s_regex_toks } \cs_new_protected:Npn \regex_state_submatches:nn #1#2 { \if_num:w #1 = \l_regex_unique_step_int - \tl_set:Nn \l_regex_current_submatches_prop {#2} + \tl_set:Nn \l_regex_current_submatches_prop { #2 } \fi: } \cs_new_protected:Npn \regex_match:n #1 { - \tl_set:Nx \l_regex_query_str { \tl_to_other_str:n {#1} } + \tl_set:Nx \l_regex_query_other_str { \tl_to_other_str:n {#1} } \regex_match_initial_setup: \regex_match_once: } \cs_new_protected_nopar:Npn \regex_match_once: { \regex_match_setup: - \exp_after:wN \regex_match_once_aux: \l_regex_query_str + \exp_after:wN \regex_match_once_aux: \l_regex_query_other_str \q_recursion_tail \q_recursion_stop \bool_if:NT \l_regex_success_bool { \l_regex_every_match_tl } } \cs_new_protected_nopar:Npn \regex_match_once_aux: - { \str_skip_do:nn { \l_regex_start_step_int } { \regex_match_loop:N } } + { + \int_compare:nNnTF \l_regex_start_step_int = \c_zero + { + \int_set_eq:NN \l_regex_current_char_int \c_minus_one + \regex_match_loop:N + } + { + \str_skip_do:nn + { \l_regex_start_step_int - \c_one } + { \regex_match_once_aux_ii:N } + } + } +\cs_new_protected_nopar:Npn \regex_match_once_aux_ii:N #1 + { + \int_set:Nn \l_regex_current_char_int { `#1 } + \regex_match_loop:N + } \cs_new_protected_nopar:Npn \regex_match_initial_setup: { - \tl_clear:N \l_regex_look_behind_str \prg_stepwise_inline:nnnn {1} {1} { \l_regex_max_state_int } { \tex_dimen:D ##1 \c_minus_one sp \scan_stop: } \int_set_eq:NN \l_regex_unique_step_int \c_minus_one @@ -1118,20 +1192,11 @@ \int_zero:N \l_regex_max_index_int \regex_store_state:n {1} } -\cs_new_protected_nopar:Npn \regex_match_loop_setup: - { - \int_incr:N \l_regex_current_step_int - \int_incr:N \l_regex_unique_step_int - \bool_set_false:N \l_regex_fresh_thread_bool - } \cs_new_eq:NN \s_regex_step \scan_stop: \cs_new:Npn \regex_break_step:w #1 \s_regex_step { } \cs_new_protected_nopar:Npn \regex_match_loop:N #1 { - \regex_match_loop_setup: - \token_if_eq_meaning:NNTF #1 \q_recursion_tail - { \int_set_eq:NN \l_regex_current_char_int \c_minus_one } - { \int_set:Nn \l_regex_current_char_int {`#1} } + \regex_match_loop_setup:N #1 \cs_set_nopar:Npx \regex_tmp:w { \int_zero:N \l_regex_max_index_int @@ -1145,19 +1210,49 @@ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: \quark_if_recursion_tail_stop:N #1 - \bool_if:NT \l_regex_look_behind_bool - { \tl_put_left:Nx \l_regex_look_behind_str {#1} } \regex_match_loop:N } \cs_new_nopar:Npn \regex_match_one_index:n #1 { - \regex_match_one_index_aux:n { \int_value:w \tex_skip:D #1 } + \regex_match_one_index_aux:n + { \int_value:w \tex_skip:D #1 } } \cs_new_protected_nopar:Npn \regex_match_one_index_aux:n #1 { \int_set:Nn \l_regex_current_state_int {#1} \prop_clear:N \l_regex_current_submatches_prop - \regex_state_use_submatches: + \regex_state_use_with_submatches: + } +\cs_new_protected_nopar:Npn \regex_match_loop_setup:N #1 + { + \int_incr:N \l_regex_current_step_int + \int_incr:N \l_regex_unique_step_int + \bool_set_false:N \l_regex_fresh_thread_bool + \int_set_eq:NN \l_regex_last_char_int \l_regex_current_char_int + \if_meaning:w #1 \q_recursion_tail + \int_set_eq:NN \l_regex_current_char_int \c_minus_one + \else: + \int_set:Nn \l_regex_current_char_int {`#1} + \fi: + \regex_match_loop_case_hook: + } +\cs_new_protected_nopar:Npn \regex_match_loop_case_hook: { } +\cs_new_protected_nopar:Npn \regex_match_loop_caseless_hook: + { + \int_set_eq:NN \l_regex_case_changed_char_int \l_regex_current_char_int + \if_num:w \l_regex_current_char_int < \c_ninety_one + \if_num:w \l_regex_current_char_int < \c_sixty_five + \else: + \int_add:Nn \l_regex_case_changed_char_int { \c_thirty_two } + \fi: + \else: + \if_num:w \l_regex_current_char_int < \c_one_hundred_twenty_three + \if_num:w \l_regex_current_char_int < \c_ninety_seven + \else: + \int_sub:Nn \l_regex_case_changed_char_int { \c_thirty_two } + \fi: + \fi: + \fi: } \cs_new_protected_nopar:Npn \regex_action_start_wildcard:nn #1#2 { @@ -1167,7 +1262,10 @@ \regex_action_cost:n {#1} } \cs_new_protected_nopar:Npn \regex_action_cost:n #1 - { \regex_store_state:n {#1} } + { + \exp_args:Nf \regex_store_state:n %^^A optimize! + { \int_eval:n { \l_regex_current_state_int + #1 } } + } \cs_new_protected_nopar:Npn \regex_action_success: { \regex_last_match_empty:F @@ -1184,30 +1282,22 @@ } \cs_new_protected_nopar:Npn \regex_action_free:n #1 { - \regex_if_state_free:nT {#1} + \cs_set_nopar:Npx \regex_tmp:w { - \use:x - { - \int_set:Nn \l_regex_current_state_int {#1} - \regex_store_submatches:n { \l_regex_current_state_int } - \regex_state_use: - \int_set:Nn \l_regex_current_state_int - { \int_use:N \l_regex_current_state_int } - \tl_set:Nn \exp_not:N \l_regex_current_submatches_prop - { \exp_not:o \l_regex_current_submatches_prop } - } + \int_add:Nn \l_regex_current_state_int {#1} + \regex_state_use: + \int_set:Nn \l_regex_current_state_int + { \int_use:N \l_regex_current_state_int } + \tl_set:Nn \exp_not:N \l_regex_current_submatches_prop + { \exp_not:o \l_regex_current_submatches_prop } } + \regex_tmp:w } \cs_new_protected_nopar:Npn \regex_action_submatch:n #1 { \prop_put:Nno \l_regex_current_submatches_prop {#1} { \int_use:N \l_regex_current_step_int } - \regex_store_submatches:n { \l_regex_current_state_int } } -\cs_new_protected_nopar:Npn \regex_action_repeat_copy:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_repeat_move:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_no_repeat_copy:n { \ERROR } -\cs_new_protected_nopar:Npn \regex_action_no_repeat_move:n { \ERROR } \cs_new_protected_nopar:Npn \regex_extract: { \seq_gclear:N \g_regex_submatches_seq @@ -1217,11 +1307,7 @@ \regex_extract_aux:nTF { ##1 } { \seq_gput_right:Nx \g_regex_submatches_seq - { - \str_from_to:Nnn \l_regex_query_str - { \l_regex_tmpa_tl } - { \l_regex_tmpb_tl } - } + { \regex_query_substr:NN \l_regex_tmpa_tl \l_regex_tmpb_tl } } { \seq_gput_right:Nn \g_regex_submatches_seq { } } } @@ -1253,9 +1339,13 @@ = \int_use:N \l_regex_max_state_int \l_regex_capturing_group_int = \int_use:N \l_regex_capturing_group_int - \bool_if:NTF \l_regex_look_behind_bool - { \bool_set_true:N \l_regex_look_behind_bool } - { \bool_set_false:N \l_regex_look_behind_bool } + \token_if_eq_meaning:NNT + \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + { + \cs_set_eq:NN \regex_match_loop_case_hook: + \regex_match_loop_caseless_hook: + } \prg_stepwise_function:nnnN {1} {1} {\l_regex_max_state_int} \regex_set_aux:n @@ -1269,7 +1359,7 @@ \cs_new:Npn \regex_nfa:Nw #1 #2 \regex_nfa_end: { \msg_expandable_error:n { Automaton~#1 used~incorrectly. } } \cs_new_eq:NN \regex_nfa_end: \scan_stop: -\prg_new_protected_conditional:Npnn \regex_check_nfa:N #1 { TF } +\prg_new_protected_conditional:Npnn \regex_check_nfa:N #1 { T , TF } { \exp_after:wN \regex_check_nfa_aux:Nw #1 \q_stop } \cs_new:Npn \regex_check_nfa_aux:Nw #1 #2 \q_stop { @@ -1280,11 +1370,6 @@ \prg_return_false: \fi: } -\msg_new:nnn { regex } { not-nfa } - { - I~was~expecting~a~regular~expression~variable.\\ - Instead,~I~got~#1. - } \cs_new_protected_nopar:Npn \regex_use:N #1 { \exp_after:wN \use_none:nn #1 } \cs_new_protected:Npn \regex_user_aux:n #1 @@ -1296,7 +1381,7 @@ } \cs_new_protected_nopar:Npn \regex_return_after_group: { - \if_bool:N \l_regex_success_bool + \if_meaning:w \c_true_bool \l_regex_success_bool \group_insert_after:N \prg_return_true: \else: \group_insert_after:N \prg_return_false: @@ -1304,7 +1389,7 @@ } \cs_new_protected_nopar:Npn \regex_extract_after_group:N #1 { - \if_bool:N \l_regex_success_bool + \if_meaning:w \c_true_bool \l_regex_success_bool \regex_extract: \group_insert_after:N \seq_set_eq:NN \group_insert_after:N #1 @@ -1359,7 +1444,7 @@ } \cs_new_protected:Npn \regex_count:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1375,9 +1460,8 @@ \regex_count_after_group:N #3 } } - { } } -\cs_new_protected:Npn \regex_extract:nnN #1#2#3 +\cs_new_protected:Npn \regex_extract_once:nnN #1#2#3 { \regex_user_aux:n { @@ -1386,7 +1470,8 @@ \regex_extract_after_group:N #3 } } -\prg_new_protected_conditional:Npnn \regex_extract:nnN #1#2#3 { T , F , TF } +\prg_new_protected_conditional:Npnn \regex_extract_once:nnN #1#2#3 + { T , F , TF } { \regex_user_aux:n { @@ -1396,9 +1481,9 @@ \regex_return_after_group: } } -\cs_new_protected:Npn \regex_extract:NnN #1#2#3 +\cs_new_protected:Npn \regex_extract_once:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1407,9 +1492,9 @@ \regex_extract_after_group:N #3 } } - { } } -\prg_new_protected_conditional:Npnn \regex_extract:NnN #1#2#3 { T , F , TF } +\prg_new_protected_conditional:Npnn \regex_extract_once:NnN #1#2#3 + { T , F , TF } { \regex_check_nfa:NTF #1 { @@ -1423,6 +1508,48 @@ } { \prg_return_false: } } +\cs_new_protected:Npn \regex_extract_all:nnN #1#2#3 + { + \regex_user_aux:n + { + \seq_gclear:N \g_regex_extract_all_seq + \tl_set:Nn \l_regex_every_match_tl { \regex_extract_all_aux: } + \regex_build:n {#1} + \regex_match:n {#2} + \regex_extract_all_after_group:N #3 + } + } +\cs_new_protected:Npn \regex_extract_all:NnN #1#2#3 + { + \regex_check_nfa:NT #1 + { + \regex_user_aux:n + { + \seq_gclear:N \g_regex_extract_all_seq + \tl_set:Nn \l_regex_every_match_tl { \regex_extract_all_aux: } + \regex_use:N #1 + \regex_match:n {#2} + \regex_extract_all_after_group:N #3 + } + } + } +\cs_new_protected_nopar:Npn \regex_extract_all_aux: + { + \regex_extract: + \seq_gconcat:NNN \g_regex_extract_all_seq + \g_regex_extract_all_seq \g_regex_submatches_seq + \regex_match_once: + } +\cs_new_protected_nopar:Npn \regex_extract_all_after_group:N #1 + { + \seq_if_empty:NF \g_regex_extract_all_seq + { + \regex_extract: + \group_insert_after:N \seq_set_eq:NN + \group_insert_after:N #1 + \group_insert_after:N \g_regex_extract_all_seq + } + } \cs_new_protected:Npn \regex_split:nnN #1#2#3 { \regex_user_aux:n @@ -1436,7 +1563,7 @@ } \cs_new_protected:Npn \regex_split:NnN #1#2#3 { - \regex_check_nfa:NTF #1 + \regex_check_nfa:NT #1 { \regex_user_aux:n { @@ -1447,7 +1574,6 @@ \regex_split_after_group:N #3 } } - { } } \cs_new_protected_nopar:Npn \regex_split_aux: { @@ -1459,9 +1585,8 @@ { \seq_gput_left:Nx \g_regex_submatches_seq { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \l_regex_tmpa_tl } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_tmpa_tl } } { \msg_error:nn { regex } { internal } } @@ -1480,9 +1605,8 @@ { \seq_gput_right:Nx \g_regex_split_seq { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \int_use:N \l_regex_current_step_int } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_current_step_int } } \group_insert_after:N \seq_set_eq:NN @@ -1494,40 +1618,57 @@ \str_aux_escape:NNNn \prg_do_nothing: \regex_replacement_escaped:N - \regex_replacement_raw:N + \prg_do_nothing: {#1} \tl_set_eq:NN \l_regex_replacement_tl \g_str_result_tl \tl_set:Nx \l_regex_replacement_tl { \l_regex_replacement_tl \prg_do_nothing: } } -\cs_new_nopar:Npn \regex_replacement_raw:N { \exp_not:N \prg_do_nothing: } \cs_new_nopar:Npn \regex_replacement_escaped:N #1 { - \if_num:w 9 < 1 #1 \exp_stop_f: - \exp_not:N \regex_replacement_escaped_ii:nN {#1} - \else: - #1 - \fi: + \regex_token_if_other_digit:NTF #1 + { + \exp_not:n + { \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } } {#1} + } + { + \token_if_eq_charcode:NNTF g #1 + { \exp_not:N \regex_replacement_submatch:w } + { #1 } + } } -\cs_new_nopar:Npn \regex_replacement_escaped_ii:nN #1#2 +\cs_new_nopar:Npn \regex_replacement_submatch:w #1 { - \regex_token_if_other_digit:NTF #2 - { \regex_replacement_escaped_ii:nN {#1#2} } - { \exp_not:N \seq_item:Nn \exp_not:N \g_regex_submatches_seq {#1} #2 } + \exp_after:wN \token_if_eq_meaning:NNTF \c_lbrace_str #1 + { \regex_replacement_submatch_aux:nN { } } + { + \regex_token_if_other_digit:NTF #1 + { \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } } + { \msg_expandable_error:n { \g misused~in~replacement~text. } } + #1 + } } -\prg_new_conditional:Npnn \regex_token_if_other_digit:N #1 { TF } +\cs_new_nopar:Npn \regex_replacement_submatch_aux:nN #1 #2 { - \if_num:w 9 < 1 \exp_not:N #1 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \regex_token_if_other_digit:NTF #2 + { \regex_replacement_submatch_aux:nN {#1#2} } + { + \exp_not:n { \seq_item:Nn \g_regex_submatches_seq } {#1} + \exp_after:wN \token_if_eq_meaning:NNF \c_rbrace_str #2 + { + \msg_expandable_error:n { \g misused~in~replacement~text. } + #2 + } + } } \cs_new_protected_nopar:Npn \regex_replace_after_group:N #1 { - \group_insert_after:N \tl_set_eq:NN + \group_insert_after:N \tl_set:Nx \group_insert_after:N #1 - \group_insert_after:N \g_regex_replaced_str + \group_insert_after:N { + \group_insert_after:N \tl_to_str:N + \group_insert_after:N \g_regex_replaced_str + \group_insert_after:N } } \cs_new_protected:Npn \regex_replace_once_aux:Nn #1#2 { @@ -1539,15 +1680,16 @@ \regex_extract: \regex_extract_aux:nTF {0} { + \cs_set_nopar:Npn \regex_tmp:w + { \str_skip_do:nn { \l_regex_tmpb_tl } { } } \tl_gset:Nx \g_regex_replaced_str { - \str_from_to:Nnn \l_regex_query_str {0} { \l_regex_tmpa_tl } + \regex_query_substr:NN \c_zero \l_regex_tmpa_tl \l_regex_replacement_tl - \str_from_to:Nnn \l_regex_query_str - { \l_regex_tmpb_tl } { \c_max_int } + \exp_after:wN \regex_tmp:w \l_regex_query_other_str } } - { \tl_gset_eq:NN \g_regex_replaced_str \l_regex_query_str } + { \tl_gset_eq:NN \g_regex_replaced_str \l_regex_query_other_str } \group_end: } \cs_new_protected:Npn \regex_replace_once:nnN #1#2#3 @@ -1592,12 +1734,10 @@ \tl_gclear:N \g_regex_replaced_str #2 \exp_args:No \regex_match:n {#1} + \cs_set_nopar:Npn \regex_tmp:w + { \str_skip_do:nn { \l_regex_start_step_int } { } } \tl_gput_right:Nx \g_regex_replaced_str - { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \c_max_int } - } + { \exp_after:wN \regex_tmp:w \l_regex_query_other_str } \group_end: } \cs_new_protected_nopar:Npn \regex_replace_all_aux: @@ -1607,9 +1747,8 @@ { \tl_gput_right:Nx \g_regex_replaced_str { - \str_from_to:Nnn \l_regex_query_str - { \int_use:N \l_regex_start_step_int } - { \l_regex_tmpa_tl } + \regex_query_substr:NN + \l_regex_start_step_int \l_regex_tmpa_tl \l_regex_replacement_tl } } @@ -1632,6 +1771,26 @@ \regex_replacement:n {#2} } } +\msg_new:nnn { regex } { -998 } { Unsupported~construct } +\msg_new:nnn { regex } { -997 } + { The~regular~expression~is~too~large~(32768~states). } +\msg_new:nnn { regex } { 1 } { \iow_char:N\\~at~end~of~pattern } +\msg_new:nnn { regex } { 4 } + { Numbers~out~of~order~in~\iow_char:N\{\iow_char\}~quantifier. } +\msg_new:nnn { regex } { 6 } + { Missing~terminating~\iow_char:N\]~for~character~class } +\msg_new:nnn { regex } { 7 } + { Invalid~escape~sequence~in~character~class } +\msg_new:nnn { regex } { 8 } + { Range~out~of~order~in~character~class } +\msg_new:nnn { regex } { 22 } { Mismatched~parentheses } +\msg_new:nnn { regex } { 34 } + { Character~value~in~\iow_char:N\\x{...}~sequence~is~too~large } +\msg_new:nnn { regex } { not-nfa } + { + LaTeX~was~expecting~a~regular~expression~variable.\\ + Instead,~LaTeX~found~'#1'. + } %% %% %% End of file `l3regex.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty index 9a69d0da0a6..c705f6366b3 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str.sty @@ -46,30 +46,27 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{expl3} -\GetIdInfo$Id: l3str.dtx 2895 2011-10-09 15:58:19Z joseph $ +\GetIdInfo$Id: l3str.dtx 2921 2011-10-17 13:23:36Z bruno $ {L3 Experimental Strings} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\cs_if_exist:NF \cs_if_exist_use:cF - { - \cs_new:Npn \cs_if_exist_use:cF #1 - { \cs_if_exist:cTF {#1} { \use:c {#1} } } - } \cs_if_exist:NF \use_i:nnnnnnnn { \cs_new:Npn \use_i:nnnnnnnn #1#2#3#4#5#6#7#8 {#1} } -\cs_set:Npn \str_tmp:w #1 - { - \cs_new_protected:cpx { str_#1:Nn } ##1##2 - { \exp_not:c { tl_#1:Nx } ##1 { \exp_not:N \tl_to_str:n {##2} } } - \exp_args:Nc \cs_generate_variant:Nn { str_#1:Nn } { Nx , cn , cx } - } -\str_tmp:w {set} -\str_tmp:w {gset} -\str_tmp:w {put_left} -\str_tmp:w {gput_left} -\str_tmp:w {put_right} -\str_tmp:w {gput_right} -\cs_set_protected_nopar:Npn \str_tmp:w { } +\group_begin: + \cs_set_protected_nopar:Npn \str_tmp:w #1 + { + \cs_new_protected:cpx { str_ #1 :Nn } ##1##2 + { \exp_not:c { tl_ #1 :Nx } ##1 { \exp_not:N \tl_to_str:n {##2} } } + \exp_args:Nc \cs_generate_variant:Nn { str_ #1 :Nn } { Nx , cn , cx } + } + \str_tmp:w { set } + \str_tmp:w { gset } + \str_tmp:w { put_left } + \str_tmp:w { gput_left } + \str_tmp:w { put_right } + \str_tmp:w { gput_right } +\group_end: +\cs_new_protected_nopar:Npn \str_tmp:w { } \tl_new:N \g_str_tmpa_tl \tl_new:N \g_str_result_tl \int_new:N \l_str_char_int @@ -80,34 +77,31 @@ \tl_const:Nx \c_hash_str { \cs_to_str:N \# } \tl_const:Nx \c_percent_str { \cs_to_str:N \% } \group_begin: -\char_set_lccode:nn {`\*}{`\ } -\char_set_lccode:nn {`\A}{`\A} -\tl_to_lowercase:n { - \group_end: - \cs_new:Npn \tl_to_other_str:n #1 - { - \exp_after:wN \tl_to_other_str_loop:w \tl_to_str:n {#1} ~ % - A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop - } - \cs_new_nopar:Npn \tl_to_other_str_loop:w +\char_set_lccode:nn { `\* } { `\ } +\char_set_lccode:nn { `\A } { `\A } +\tl_to_lowercase:n + { + \group_end: + \cs_new:Npn \tl_to_other_str:n #1 + { + \exp_after:wN \tl_to_other_str_loop:w \tl_to_str:n {#1} ~ % + A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ \q_mark \q_stop + } + \cs_new_nopar:Npn \tl_to_other_str_loop:w #1 ~ #2 ~ #3 ~ #4 ~ #5 ~ #6 ~ #7 ~ #8 ~ #9 \q_stop - { - \if_meaning:w A #8 - \tl_to_other_str_end:w - \fi: - \tl_to_other_str_loop:w - #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop - } - \cs_new_nopar:Npn \tl_to_other_str_end:w \fi: #1 \q_mark #2 * A #3 \q_stop - { \fi: #2 } -} -\cs_new_nopar:Npn \tl_to_other_str:N - { \exp_args:No \tl_to_other_str:n } -\cs_new:Npn \str_sanitize_args:Nn #1 #2 - { - \exp_args:Nf #1 - { \tl_to_other_str:n {#2} } + { + \if_meaning:w A #8 + \tl_to_other_str_end:w + \fi: + \tl_to_other_str_loop:w + #9 #1 * #2 * #3 * #4 * #5 * #6 * #7 * #8 * \q_stop + } + \cs_new_nopar:Npn \tl_to_other_str_end:w \fi: #1 \q_mark #2 * A #3 \q_stop + { \fi: #2 } } +\cs_new_nopar:Npn \tl_to_other_str:N { \exp_args:No \tl_to_other_str:n } +\cs_new:Npn \str_sanitize_args:Nn #1#2 + { \exp_args:Nf #1 { \tl_to_other_str:n {#2} } } \cs_new:Npn \str_sanitize_args:Nnn #1#2#3 { \exp_args:Nff #1 @@ -141,15 +135,15 @@ \fi: \c_nine + \str_length_loop:NNNNNNNNN } -\cs_set_nopar:Npn \str_head:N { \exp_args:No \str_head:n } +\cs_new_nopar:Npn \str_head:N { \exp_args:No \str_head:n } \cs_set:Npn \str_head:n #1 { \exp_after:wN \str_head_aux:w \tl_to_str:n {#1} { { } } ~ \q_stop } -\cs_set_nopar:Npx \str_head_aux:w #1 ~ % - { \exp_not:N \use_i_delimit_by_q_stop:nw #1 { ~ } } +\cs_set_nopar:Npn \str_head_aux:w #1 ~ % + { \use_i_delimit_by_q_stop:nw #1 { ~ } } \cs_new:Npn \str_head_ignore_spaces:n #1 { \exp_after:wN \use_i_delimit_by_q_stop:nw \tl_to_str:n {#1} { } \q_stop } \cs_new_nopar:Npn \str_head_unsafe:n #1 @@ -169,15 +163,17 @@ } \cs_new_nopar:Npn \str_tail_unsafe:n #1 { \str_tail_aux_ii:w #1 X { } X \q_stop } -\cs_set_nopar:Npn \str_tail_aux_ii:w #1 #2 X #3 \q_stop { #2 } +\cs_new_nopar:Npn \str_tail_aux_ii:w #1 #2 X #3 \q_stop { #2 } \cs_new:Npn \str_skip_do:nn #1 { - \int_compare:nNnTF {#1} > \c_seven - { \str_skip_aux:nnnnnnnnn } - { \str_skip_end:n } + \if_num:w \int_eval:w #1 > \c_seven + \exp_after:wN \str_skip_aux:nnnnnnnnn + \else: + \exp_after:wN \str_skip_end:n + \fi: {#1} } -\cs_new:Npn \str_skip_aux:nnnnnnnnn #1#2 #3#4#5#6#7#8#9 +\cs_new:Npn \str_skip_aux:nnnnnnnnn #1#2#3#4#5#6#7#8#9 { \exp_args:Nf \str_skip_do:nn { \int_eval:n { #1 - \c_seven } } {#2} } \cs_new:Npn \str_skip_end:n #1 { @@ -193,7 +189,7 @@ \else: \str_skip_end_ii:nwn { XXXXXXX } \fi: } -\cs_new:Npn \str_skip_end_ii:nwn #1 #2 \fi: #3 +\cs_new:Npn \str_skip_end_ii:nwn #1#2 \fi: #3 { \fi: \use_i:nnnnnnnn {#3} #1 } \cs_new:Npn \str_collect_do:nn #1#2 { \str_collect_aux:n {#1} { \str_collect_end_iii:nwNNNNNNN {#2} } } @@ -213,18 +209,18 @@ \cs_new:Npn \str_collect_end:n #1 { \if_case:w \int_eval:w #1 \int_eval_end: - \str_collect_end_ii:nwn { {}{}{}{}{}{}{} } - \or: \str_collect_end_ii:nwn { {}{}{}{}{}{} } - \or: \str_collect_end_ii:nwn { {}{}{}{}{} } - \or: \str_collect_end_ii:nwn { {}{}{}{} } - \or: \str_collect_end_ii:nwn { {}{}{} } - \or: \str_collect_end_ii:nwn { {}{} } - \or: \str_collect_end_ii:nwn { {} } + \str_collect_end_ii:nwn { { } { } { } { } { } { } { } } + \or: \str_collect_end_ii:nwn { { } { } { } { } { } { } } + \or: \str_collect_end_ii:nwn { { } { } { } { } { } } + \or: \str_collect_end_ii:nwn { { } { } { } { } } + \or: \str_collect_end_ii:nwn { { } { } { } } + \or: \str_collect_end_ii:nwn { { } { } } + \or: \str_collect_end_ii:nwn { { } } \or: \str_collect_end_ii:nwn { } - \else: \str_collect_end_ii:nwn { {}{}{}{}{}{}{} } + \else: \str_collect_end_ii:nwn { { } { } { } { } { } { } { } } \fi: } -\cs_new:Npn \str_collect_end_ii:nwn #1 #2 \fi: #3 +\cs_new:Npn \str_collect_end_ii:nwn #1#2 \fi: #3 { \fi: #3 \q_stop #1 } \cs_new:Npn \str_collect_end_iii:nwNNNNNNN #1 #2 \q_stop #3#4#5#6#7#8#9 { #1 {#2#3#4#5#6#7#8#9} } @@ -264,30 +260,30 @@ { \use_none_delimit_by_q_stop:w } } } -\cs_new_nopar:Npn \str_from_to:Nnn { \exp_args:No \str_from_to:nnn } -\cs_new:Npn \str_from_to:nnn #1#2#3 +\cs_new_nopar:Npn \str_substr:Nnn { \exp_args:No \str_substr:nnn } +\cs_new:Npn \str_substr:nnn #1#2#3 { \exp_args:Nf \tl_to_str:n - { \str_sanitize_args:Nn \str_from_to_unsafe:nnn {#1}{#2}{#3} } + { \str_sanitize_args:Nn \str_substr_unsafe:nnn {#1} {#2} {#3} } } -\cs_new:Npn \str_from_to_ignore_spaces:nnn #1 - { \exp_args:No \str_from_to_unsafe:nnn { \tl_to_str:n {#1} } } -\cs_new:Npn \str_from_to_unsafe:nnn #1#2#3 % <string> <from> <to> +\cs_new:Npn \str_substr_ignore_spaces:nnn #1 + { \exp_args:No \str_substr_unsafe:nnn { \tl_to_str:n {#1} } } +\cs_new:Npn \str_substr_unsafe:nnn #1#2#3 { - \str_aux_eval_args:Nnnn \str_from_to_aux:nnnw + \str_aux_eval_args:Nnnn \str_substr_aux:nnnw { \str_length_unsafe:n {#1} } {#2} {#3} #1 \q_stop } -\cs_new:Npn \str_from_to_aux:nnnw #1#2#3 % <len> <from> <to> +\cs_new:Npn \str_substr_aux:nnnw #1#2#3 { - \exp_args:Nf \str_from_to_aux_ii:nnw + \exp_args:Nf \str_substr_aux_ii:nnw { \str_aux_normalize_range:nn {#2} {#1} } { \str_aux_normalize_range:nn {#3} {#1} } } -\cs_new:Npn \str_from_to_aux_ii:nnw #1#2 +\cs_new:Npn \str_substr_aux_ii:nnw #1#2 { \str_skip_do:nn {#1} { @@ -376,7 +372,7 @@ } \prg_new_protected_conditional:Npnn \str_aux_hexadecimal_test:N #1 { TF } { - \tl_if_in:onTF { \tl_to_str:n {abcdef} } {#1} + \tl_if_in:onTF { \tl_to_str:n { abcdef } } {#1} { \int_set:Nn \l_str_char_int { \c_sixteen * \l_str_char_int + `#1 - 87 } @@ -423,7 +419,7 @@ \cs_set_nopar:Npn \str_aux_escape_unescaped:N { #1 } \cs_set_nopar:Npn \str_aux_escape_escaped:N { #2 } \cs_set_nopar:Npn \str_aux_escape_raw:N { #3 } - \int_set:Nn \tex_escapechar:D {92} + \int_set:Nn \tex_escapechar:D { 92 } \tl_gset:Nx \g_str_result_tl { \tl_to_other_str:n {#4} } \tl_gset:Nx \g_str_result_tl { @@ -531,28 +527,22 @@ } } \group_end: -\msg_new:nnn { str } { x-missing-brace } - { - You~wrote~something~like~ - `\iow_char:N\\x\{ \int_to_hexadecimal:n { \l_str_char_int }'.~ - The~closing~brace~is~missing. - } \group_begin: - \char_set_catcode_other:n {`\^^@} + \char_set_catcode_other:n { `\^^@ } \cs_new_protected_nopar:Npn \str_aux_convert_store: { - \char_set_lccode:nn {\c_zero} {\l_str_char_int} + \char_set_lccode:nn { \c_zero } { \l_str_char_int } \tl_to_lowercase:n { \tl_gput_right:Nx \g_str_result_tl {^^@} } } \cs_new_protected_nopar:Npn \str_aux_convert_store:NNn #1#2#3 { - \char_set_lccode:nn {\c_zero} {#3} + \char_set_lccode:nn { \c_zero } {#3} \tl_to_lowercase:n { #1 #2 {^^@} } } \group_end: \cs_new_nopar:Npn \str_aux_byte_to_hexadecimal:N #1 { - \int_compare:nNnTF {`#1} < {256} + \int_compare:nNnTF {`#1} < { 256 } { \int_to_letter:n { \int_div_truncate:nn {`#1} \c_sixteen } \int_to_letter:n { \int_mod:nn {`#1} \c_sixteen } @@ -561,14 +551,14 @@ } \cs_new_nopar:Npn \str_aux_byte_to_octal:N #1 { - \int_compare:nNnTF {`#1} < {64} + \int_compare:nNnTF {`#1} < { 64 } { 0 \int_to_letter:n { \int_div_truncate:nn {`#1} \c_eight } \int_to_letter:n { \int_mod:nn {`#1} \c_eight } } { - \int_compare:nNnTF {`#1} < {256} + \int_compare:nNnTF {`#1} < { 256 } { \int_to_octal:n {`#1} } { \msg_expandable_error:n { Invalid~byte~`#1'. } } } @@ -579,7 +569,7 @@ { \str_map_tokens:Nn #2 \str_aux_byte_to_hexadecimal:N } } \tl_const:Nx \c_str_bytes_escape_name_str - { \c_hash_str \c_percent_str \c_lbrace_str \c_rbrace_str () /<>[] } + { \c_hash_str \c_percent_str \c_lbrace_str \c_rbrace_str ()/<>[] } \cs_new_protected_nopar:Npn \str_bytes_escape_name:NN #1#2 { \str_set:Nx #1 @@ -587,10 +577,10 @@ } \cs_new_nopar:Npn \str_bytes_escape_name_aux:N #1 { - \int_compare:nNnTF {`#1} < {"21} + \int_compare:nNnTF {`#1} < { "21 } { \c_hash_str \str_aux_byte_to_hexadecimal:N #1 } { - \int_compare:nNnTF {`#1} > {"7E} + \int_compare:nNnTF {`#1} > { "7E } { \c_hash_str \str_aux_byte_to_hexadecimal:N #1 } { \str_if_contains_char:NNTF \c_str_bytes_escape_name_str #1 @@ -607,10 +597,10 @@ } \cs_new_nopar:Npn \str_bytes_escape_string_aux:N #1 { - \int_compare:nNnTF {`#1} < {"21} + \int_compare:nNnTF {`#1} < { "21 } { \c_backslash_str \str_aux_byte_to_octal:N #1 } { - \int_compare:nNnTF {`#1} > {"7E} + \int_compare:nNnTF {`#1} > { "7E } { \c_backslash_str \str_aux_byte_to_octal:N #1 } { \str_if_contains_char:NNT \c_str_bytes_escape_string_str #1 @@ -719,16 +709,16 @@ { \prg_case_str:xxn {#2} { - {n} {10} - {r} {13} - {t} {9} - {b} {8} - {f} {12} - {(} {40} - {)} {41} - {\c_backslash_str} {92} - {^^J} {-1} - {^^M} {-1} + { n } { 10 } + { r } { 13 } + { t } { 9 } + { b } { 8 } + { f } { 12 } + { ( } { 40 } + { ) } { 41 } + { \c_backslash_str } { 92 } + { ^^J } { -1 } + { ^^M } { -1 } } {`#2} } @@ -768,14 +758,14 @@ } \cs_new_nopar:Npn \str_bytes_percent_encode_aux:N #1 { - \int_compare:nNnTF {`#1} < {"41} + \int_compare:nNnTF {`#1} < { "41 } { \str_if_contains_char:NNTF \c_str_bytes_percent_encode_not_str #1 { #1 } { \c_percent_str \str_aux_byte_to_hexadecimal:N #1 } } { - \int_compare:nNnTF {`#1} > {"7E} + \int_compare:nNnTF {`#1} > { "7E } { \c_percent_str \str_aux_byte_to_hexadecimal:N #1 } { \str_if_contains_char:NNTF \c_str_bytes_percent_encode_str #1 @@ -837,19 +827,18 @@ \cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_i:N #1 { \quark_if_recursion_tail_stop:N #1 - \int_set:Nn \l_str_char_int { `#1 } - \str_native_from_UTF_viii_aux_ii:nN {128} \c_one - \str_native_from_UTF_viii_aux_ii:nN {64} \c_zero - \str_native_from_UTF_viii_aux_ii:nN {32} \c_two - \str_native_from_UTF_viii_aux_ii:nN {16} \c_three - \str_native_from_UTF_viii_aux_ii:nN {8} \c_four + \int_set:Nn \l_str_char_int {`#1} + \str_native_from_UTF_viii_aux_ii:nN { 128 } \c_one + \str_native_from_UTF_viii_aux_ii:nN { 64 } \c_zero + \str_native_from_UTF_viii_aux_ii:nN { 32 } \c_two + \str_native_from_UTF_viii_aux_ii:nN { 16 } \c_three + \str_native_from_UTF_viii_aux_ii:nN { 8 } \c_four \msg_error:nnx { str } { utf8-invalid-byte } {#1} \use_i:nnn \str_native_from_UTF_viii_aux_i:N \q_stop \str_native_from_UTF_viii_aux_iii:N } -\cs_new_protected_nopar:Npn - \str_native_from_UTF_viii_aux_ii:nN #1#2 +\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_ii:nN #1#2 { \int_compare:nNnTF \l_str_char_int < {#1} { @@ -858,8 +847,7 @@ } { \int_sub:Nn \l_str_char_int {#1} } } -\cs_new_protected_nopar:Npn - \str_native_from_UTF_viii_aux_iii:N #1 +\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_iii:N #1 { \int_compare:nNnTF \l_str_bytes_int < \c_two { \str_native_from_UTF_viii_aux_iv: #1 } @@ -869,11 +857,11 @@ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: \quark_if_recursion_tail_stop:N #1 - \tex_multiply:D \l_str_char_int by 64 \scan_stop: % no interface?? + \tex_multiply:D \l_str_char_int by 64 \scan_stop: \int_decr:N \l_str_bytes_int - \int_compare:nNnTF {`#1} < {128} + \int_compare:nNnTF {`#1} < { 128 } { \use_ii:nn } - { \int_compare:nNnTF {`#1} < {192} } + { \int_compare:nNnTF {`#1} < { 192 } } { \int_add:Nn \l_str_char_int { `#1 - 128 } \str_native_from_UTF_viii_aux_iii:N @@ -884,47 +872,32 @@ } } } -\cs_new_protected_nopar:Npn - \str_native_from_UTF_viii_aux_iv: +\cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_iv: { \int_compare:nNnTF \l_str_bytes_int = \c_zero { \msg_error:nnx { str } { utf8-extra-byte } { \int_eval:n { \l_str_char_int + 128 } } } + { \str_native_from_UTF_viii_aux_v: } + \str_native_from_UTF_viii_aux_i:N + } +\pdftex_if_engine:TF + { + \cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_v: { - \pdftex_if_engine:TF + \int_compare:nNnTF { \l_str_char_int } < { 256 } + { \str_aux_convert_store: } { - \int_compare:nNnTF { \l_str_char_int } < { 256 } - { \str_aux_convert_store: } - { - \msg_error:nnx { str } { utf8-pdftex-overflow } - { \int_use:N \l_str_char_int } - } + \msg_error:nnx { str } { utf8-pdftex-overflow } + { \int_use:N \l_str_char_int } } - { \str_aux_convert_store: } } - \str_native_from_UTF_viii_aux_i:N } -\msg_new:nnn { str } { utf8-invalid-byte } { - \int_compare:nNnTF {`#1} < {256} - { Byte~number~\int_eval:n {`#1}~invalid~in~utf-8~encoding. } - { The~character~number~\int_eval:n {`#1}~is~not~a~byte. } + \cs_new_protected_nopar:Npn \str_native_from_UTF_viii_aux_v: + { \str_aux_convert_store: } } -\msg_new:nnn { str } { utf8-missing-byte } - { The~byte~number~\int_eval:n {`#1}~is~not~a~valid~continuation~byte. } -\msg_new:nnn { str } { utf8-extra-byte } - { The~byte~number~\int_eval:n {`#1}~is~only~valid~as~a~continuation~byte. } -\msg_new:nnnn { str } { utf8-premature-end } - { Incomplete~last~utf8~character. } - { - The~sequence~of~byte~that~I~need~to~convert~to~utf8 \ - ended~before~the~last~character~was~complete.~Perhaps \ - it~was~mistakenly~truncated? - } -\msg_new:nnn { str } { utf8-pdftex-overflow } - { The~character~number~#1~is~too~big~for~pdfTeX. } \cs_new_protected_nopar:Npn \str_UTF_viii_from_native:NN #1#2 { \group_begin: @@ -936,14 +909,14 @@ \cs_new_protected_nopar:Npn \str_UTF_viii_from_native_aux_i:N #1 { \int_set:Nn \l_str_char_int {`#1} - \int_compare:nNnTF \l_str_char_int < {128} + \int_compare:nNnTF \l_str_char_int < { 128 } { \tl_gput_right:Nx \g_str_result_tl {#1} } { \tl_gclear:N \g_str_tmpa_tl \int_set:Nn \l_str_bytes_int { 64 } - \str_UTF_viii_from_native_aux_ii:n {32} - \str_UTF_viii_from_native_aux_ii:n {16} - \str_UTF_viii_from_native_aux_ii:n {8} + \str_UTF_viii_from_native_aux_ii:n { 32 } + \str_UTF_viii_from_native_aux_ii:n { 16 } + \str_UTF_viii_from_native_aux_ii:n { 8 } \ERROR % somehow the unicode char was > "1FFFFF > "10FFFF \tl_gclear:N \g_str_tmpa_tl \use_none:n \q_stop @@ -956,15 +929,41 @@ { \str_aux_convert_store:NNn \tl_gput_left:Nx \g_str_tmpa_tl - { 128 + \int_mod:nn { \l_str_char_int } {64} } - \tex_divide:D \l_str_char_int by 64 \scan_stop: % no interface?? + { 128 + \int_mod:nn { \l_str_char_int } { 64 } } + \tex_divide:D \l_str_char_int by 64 \scan_stop: \int_add:Nn \l_str_bytes_int {#1} \int_compare:nNnT \l_str_char_int < {#1} { \use_none_delimit_by_q_stop:w } } -\cs_gset:Npn \str_length_skip_spaces:N +\msg_new:nnnn { str } { x-missing-brace } + { Missing~closing~brace~in~ \token_to_str:N \x ~byte~sequence. } + { + You~wrote~something~like~ + `\iow_char:N\\x\{ \int_to_hexadecimal:n { \l_str_char_int }'.~ + The~closing~brace~is~missing. + } +\msg_new:nnn { str } { utf8-invalid-byte } + { + \int_compare:nNnTF {`#1} < { 256 } + { Byte~number~ \int_eval:n {`#1} ~invalid~in~utf-8~encoding. } + { The~character~number~ \int_eval:n {`#1} ~is~not~a~byte. } + } +\msg_new:nnn { str } { utf8-missing-byte } + { The~byte~number~ \int_eval:n {`#1} ~is~not~a~valid~continuation~byte. } +\msg_new:nnn { str } { utf8-extra-byte } + { The~byte~number~ \int_eval:n {`#1} ~is~only~valid~as~a~continuation~byte. } +\msg_new:nnnn { str } { utf8-premature-end } + { Incomplete~last~UTF8~character. } + { + The~sequence~of~byte~that~to~be~converted~to~UTF8~ + ended~before~the~last~character~was~complete.~Perhaps~ + it~was~mistakenly~truncated? + } +\msg_new:nnn { str } { utf8-pdftex-overflow } + { The~character~number~#1~is~too~big~for~pdfTeX. } +\cs_set:Npn \str_length_skip_spaces:N { \exp_args:No \str_length_skip_spaces:n } -\cs_gset_eq:NN \str_length_skip_spaces:n \str_length_ignore_spaces:n +\cs_set_eq:NN \str_length_skip_spaces:n \str_length_ignore_spaces:n %% %% %% End of file `l3str.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty b/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty index 79490432742..9d4a42407e3 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty @@ -47,7 +47,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{xparse} -\GetIdInfo$Id: xcoffins.dtx 2895 2011-10-09 15:58:19Z joseph $ +\GetIdInfo$Id: xcoffins.dtx 2963 2011-11-15 22:06:41Z joseph $ {L3 Experimental design-level coffins} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -146,6 +146,14 @@ { \coffin_resize:Nnn #1 {#2} {#3} } \NewDocumentCommand \ScaleCoffin { m m m } { \coffin_scale:Nnn #1 {#2} {#3} } +\NewDocumentCommand \CoffinDepth { m } + { \coffin_dp:N #1 } +\NewDocumentCommand \CoffinHeight { m } + { \coffin_ht:N #1 } +\NewDocumentCommand \CoffinTotalHeight { m } + { \dim_eval:w \coffin_ht:N #1 + \coffin_dp:N #1 \dim_eval_end: } +\NewDocumentCommand \CoffinWidth { m } + { \coffin_wd:N #1 } \NewDocumentCommand \DisplayCoffinHandles { m m } { \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } diff --git a/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty b/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty index b626f072d30..e8a3345204f 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty @@ -48,11 +48,14 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3names} -\GetIdInfo$Id: l3galley.dtx 2899 2011-10-09 21:22:06Z joseph $ +\GetIdInfo$Id: l3galley.dtx 2938 2011-10-25 18:41:20Z joseph $ {L3 Experimental galley code} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \package_check_loaded_expl: +\cs_new_protected:Npn \scan_marker_new:N #1 + { \cs_new_eq:NN #1 \scan_stop: } +\cs_generate_variant:Nn \scan_marker_new:N { c } \cs_new_protected_nopar:Npn \galley_leave_vmode: { \tex_unhbox:D \c_empty_box } \clist_new:N \l_galley_parshape_left_indent_clist @@ -69,7 +72,6 @@ \cs_new_eq:NN \l_galley_width_dim \tex_hsize:D \bool_new:N \g_galley_begin_level_bool \bool_new:N \l_galley_begin_level_bool -\bool_gset_true:N \g_galley_begin_level_bool \bool_new:N \g_galley_omit_next_indent_bool \bool_new:N \l_galley_omit_next_indent_bool \bool_new:N \g_galley_parshape_set_bool @@ -107,9 +109,10 @@ \bool_gset_false:N \g_galley_parshape_set_bool \int_gzero:N \g_galley_previous_par_lines_int \tl_gclear:N \g_galley_restore_running_tl - \tl_gclear:N \g_galley_whatsits_previous_tl - \tl_gclear:N \g_galley_whatsits_next_tl + \tl_gclear:N \g_galley_whatsit_previous_tl + \tl_gclear:N \g_galley_whatsit_next_tl } +\galley_initialise_variables: \cs_new_protected_nopar:Npn \galley_initialise_settings: { \dim_set_eq:NN \l_galley_text_width_dim \l_galley_width_dim @@ -142,10 +145,10 @@ \g_galley_previous_par_lines_int \tl_set_eq:NN \l_galley_restore_running_tl \g_galley_restore_running_tl - \tl_set_eq:NN \l_galley_whatsits_previous_tl - \g_galley_whatsits_previous_tl - \tl_set_eq:NN \l_galley_whatsits_next_tl - \g_galley_whatsits_next_tl + \tl_set_eq:NN \l_galley_whatsit_previous_tl + \g_galley_whatsit_previous_tl + \tl_set_eq:NN \l_galley_whatsit_next_tl + \g_galley_whatsit_next_tl } \cs_new_protected_nopar:Npn \galley_restore_parameters: { @@ -171,10 +174,10 @@ \l_galley_previous_par_lines_int \tl_gset_eq:NN \g_galley_restore_running_tl \l_galley_restore_running_tl - \tl_gset_eq:NN \g_galley_whatsits_previous_tl - \l_galley_whatsits_previous_tl - \tl_gset_eq:NN \g_galley_whatsits_next_tl - \l_galley_whatsits_next_tl + \tl_gset_eq:NN \g_galley_whatsit_previous_tl + \l_galley_whatsit_previous_tl + \tl_gset_eq:NN \g_galley_whatsit_next_tl + \l_galley_whatsit_next_tl } \cs_new_protected_nopar:Npn \galley_level: { @@ -190,8 +193,28 @@ \galley_restore_parameters: \group_end: } +\scan_marker_new:N \s_par_omit \cs_new_protected_nopar:Npn \galley_std_par: { + \s_par_omit + \exp_after:wN \galley_std_par_aux_i: \tex_romannumeral:D - `0 + } +\cs_new_protected:Npn \galley_std_par_aux_i: + { + \peek_meaning:NTF \s_par_omit + { \galley_std_par_aux:N } + { \galley_std_par_aux_ii: } + } +\cs_new_protected:Npn \galley_std_par_aux:N #1 + { + \str_if_eq:xxF {#1} { \s_par_omit } + { + \galley_std_par_aux_ii: + #1 + } + } +\cs_new_protected_nopar:Npn \galley_std_par_aux_ii: + { \mode_if_vertical:TF { \tex_par:D } { @@ -206,6 +229,15 @@ \tl_gclear:N \g_galley_par_after_hook_tl \tex_penalty:D \c_ten_thousand } +\cs_new_protected:Npn \galley_end_par:n #1 + { + \s_par_omit + \bool_if:nF \g_galley_begin_level_bool + { + #1 + \galley_std_par: + } + } \cs_set_protected_nopar:Npn \par { \galley_std_par: } \tl_set:Nn \@par { \galley_std_par: } \cs_new_protected_nopar:Npn \galley_display_begin: @@ -354,14 +386,14 @@ { \g_galley_whatsit_next_tl \tl_gclear:N \g_galley_whatsit_next_tl - \bool_if:NT \g_galley_omit_next_indent_bool + \bool_if:NF \g_galley_omit_next_indent_bool { - \box_if_empty:NF \g_galley_last_box + \box_if_empty:NF \g_galley_last_box { \hbox_to_wd:nn \l_galley_par_indent_dim { } } } \skip_horizontal:N \l_galley_par_begin_skip \g_galley_par_begin_hook_tl - \bool_gset_true:N \g_galley_omit_next_indent_bool + \bool_gset_false:N \g_galley_omit_next_indent_bool } \cs_new_protected_nopar:Npn \galley_restore_running_parameters: { @@ -732,6 +764,20 @@ { \int_use:N \etex_widowpenalties:D \int_eval:w #1 \int_eval_end: , } \cs_new_protected_nopar:Npn \galley_interline_penalty: { \int_use:N \etex_interlinepenalties:D \etex_interlinepenalties:D \c_zero } +\cs_set_protected_nopar:Npn \nobreak + { \bool_gset_true:N \g_galley_no_break_next_bool } +\cs_set_protected_nopar:Npn \noindent + { + \tex_noindent:D + \bool_gset_false:N \g_galley_omit_next_indent_bool + } +\cs_set_protected_nopar:Npn \vspace #1 + { + \@ifstar + { \galley_set_user_vspace:n {#1} } + { \galley_set_user_vspace:n {#1} } + } +\cs_set_eq:NN \@@par \galley_std_par: \cs_set_protected_nopar:Npn \@afterheading { \bool_gset_true:N \g_galley_no_break_next_bool @@ -742,6 +788,8 @@ } \cs_set_protected:Npn \@hangfrom #1 { + \bool_gset_true:N \g_galley_omit_next_indent_bool + \leavevmode \setbox \@tempboxa = \hbox { {#1} } \galley_parshape_single_par:nnnN \c_one @@ -749,16 +797,9 @@ \c_zero_dim \c_false_bool \bool_gset_true:N \g_galley_no_break_next_bool - \bool_gset_true:N \galley_omit_next_indent_bool + \bool_gset_true:N \g_galley_omit_next_indent_bool \box \@tempboxa } -\cs_set_protected:Npn \@makefntext #1 - { - \UseTemplate { justification } { std } { indent-width = 1 em } - \bool_gset_true:N \galley_omit_next_indent_bool - \galley_leave_vmode: - \hb@xt@ 1.8em { \hss \@makefnmark } #1 - } %% %% %% End of file `l3galley.sty'. diff --git a/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty b/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty index 160fca57631..5ebe766a12b 100644 --- a/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty +++ b/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty @@ -48,7 +48,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3names} -\GetIdInfo$Id: xgalley.dtx 2895 2011-10-09 15:58:19Z joseph $ +\GetIdInfo$Id: xgalley.dtx 2922 2011-10-17 19:01:04Z joseph $ {L3 Experimental galley} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -606,11 +606,6 @@ { \skip_eval:n { \l_galley_display_end_vspace_tl } } } } -\RenewDocumentCommand \nobreak { } - { \bool_gset_true:N \g_galley_no_break_next_bool } -\RenewDocumentCommand \noindent { } - { \bool_gset_false:N \g_galley_omit_next_indent_bool } -\RenewDocumentCommand \vspace { s m } { \galley_set_vspace_user:n {#2} } %% %% %% End of file `xgalley.sty'. |