%% %% This is file `l3tl-analysis.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% l3tl-analysis.dtx (with options: `package') %% %% EXPERIMENTAL CODE %% %% Do not distribute this file without also distributing the %% source files specified above. %% %% Do not distribute a modified version of this file. %% %% File: l3tl-analysis.dtx Copyright (C) 2011-2012 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3experimental bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX3 Project. %% %% ----------------------------------------------------------------------- \RequirePackage{expl3} \GetIdInfo$Id: l3tl-analysis.dtx 3039 2011-12-08 09:22:35Z bruno $ {L3 Experimental token lists analysis} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \RequirePackage{l3str} \__scan_new:N \s__tl \tl_new:N \l__tl_analysis_internal_tl \cs_new_eq:NN \l__tl_analysis_token ? \cs_new_eq:NN \l__tl_analysis_char_token ? \int_new:N \l__tl_analysis_normal_int \int_new:N \l__tl_analysis_index_int \int_new:N \l__tl_analysis_nesting_int \int_new:N \l__tl_analysis_type_int \tl_new:N \g__tl_analysis_result_tl \cs_new_nopar:Npn \__tl_analysis_extract_charcode: { \exp_after:wN \__tl_analysis_extract_charcode_aux:w \token_to_meaning:N \l__tl_analysis_token } \cs_new:Npn \__tl_analysis_extract_charcode_aux:w #1 ~ #2 ~ { ` } \cs_new:Npn \__tl_analysis_cs_space_count:NN #1 #2 { \exp_after:wN #1 \__int_value:w \__int_eval:w \c_zero \exp_after:wN \__tl_analysis_cs_space_count:w \token_to_str:N #2 \fi: \__tl_analysis_cs_space_count_end:w ; ~ ! } \cs_new:Npn \__tl_analysis_cs_space_count:w #1 ~ { \if_false: #1 #1 \fi: + \c_one \__tl_analysis_cs_space_count:w } \cs_new:Npn \__tl_analysis_cs_space_count_end:w ; #1 \fi: #2 ! { \exp_after:wN ; \__int_value:w \str_count_ignore_spaces:n {#1} ; } \cs_new_protected:Npn \__tl_analysis:n #1 { \group_begin: \group_align_safe_begin: \__tl_analysis_setup:n {#1} \__tl_analysis_a:n {#1} \__tl_analysis_b:n {#1} \group_align_safe_end: \group_end: } \cs_new_protected:Npn \__tl_analysis_setup:n #1 { \int_set_eq:NN \tex_escapechar:D \c_minus_one \exp_after:wN \__tl_analysis_disable_loop:N \tl_to_str:n {#1} { ~ } { ? ~ \__prg_break: } \__prg_break_point: } \group_begin: \char_set_catcode_active:N \^^@ \cs_new_protected:Npn \__tl_analysis_disable_loop:N #1 { \tex_lccode:D \c_zero `#1 ~ \tl_to_lowercase:n { \tex_let:D ^^@ } \c_undefined:D \__tl_analysis_disable_loop:N } \group_end: \cs_new_protected:Npn \__tl_analysis_a:n #1 { \int_set:Nn \tex_escapechar:D { 92 } \int_zero:N \l__tl_analysis_normal_int \int_zero:N \l__tl_analysis_index_int \int_zero:N \l__tl_analysis_nesting_int \if_false: { \fi: \__tl_analysis_a_loop:w #1 } \int_decr:N \l__tl_analysis_index_int } \cs_new_protected_nopar:Npn \__tl_analysis_a_loop:w { \tex_futurelet:D \l__tl_analysis_token \__tl_analysis_a_type:w } \cs_new_protected_nopar:Npn \__tl_analysis_a_type:w { \l__tl_analysis_type_int = \if_meaning:w \l__tl_analysis_token \c_space_token \c_zero \else: \if_catcode:w \exp_not:N \l__tl_analysis_token \c_group_begin_token \c_one \else: \if_catcode:w \exp_not:N \l__tl_analysis_token \c_group_end_token \c_minus_one \else: \c_two \fi: \fi: \fi: \if_case:w \l__tl_analysis_type_int \exp_after:wN \__tl_analysis_a_space:w \or: \exp_after:wN \__tl_analysis_a_bgroup:w \or: \exp_after:wN \__tl_analysis_a_safe:N \else: \exp_after:wN \__tl_analysis_a_egroup:w \fi: } \cs_new_protected_nopar:Npn \__tl_analysis_a_space:w { \tex_afterassignment:D \__tl_analysis_a_space_test:w \exp_after:wN \cs_set_eq:NN \exp_after:wN \l__tl_analysis_char_token \token_to_str:N } \cs_new_protected_nopar:Npn \__tl_analysis_a_space_test:w { \if_meaning:w \l__tl_analysis_char_token \c_space_token \tex_toks:D \l__tl_analysis_index_int { \exp_not:n { ~ } } \__tl_analysis_a_store: \else: \int_incr:N \l__tl_analysis_normal_int \fi: \__tl_analysis_a_loop:w } \group_begin: \char_set_catcode_group_begin:N \^^@ \char_set_catcode_group_end:N \^^E \cs_new_protected_nopar:Npn \__tl_analysis_a_bgroup:w { \__tl_analysis_a_group:nw { \exp_after:wN ^^@ \if_false: ^^E \fi: } } \char_set_catcode_group_begin:N \^^B \char_set_catcode_group_end:N \^^@ \cs_new_protected_nopar:Npn \__tl_analysis_a_egroup:w { \__tl_analysis_a_group:nw { \if_false: ^^B \fi: ^^@ } } \group_end: \cs_new_protected:Npn \__tl_analysis_a_group:nw #1 { \tex_lccode:D \c_zero = \__tl_analysis_extract_charcode: \scan_stop: \tl_to_lowercase:n { \tex_toks:D \l__tl_analysis_index_int {#1} } \if_int_compare:w \tex_lccode:D \c_zero = \tex_escapechar:D \int_set:Nn \tex_escapechar:D { 139 - \tex_escapechar:D } \fi: \tex_afterassignment:D \__tl_analysis_a_group_test:w \exp_after:wN \cs_set_eq:NN \exp_after:wN \l__tl_analysis_char_token \token_to_str:N } \cs_new_protected_nopar:Npn \__tl_analysis_a_group_test:w { \if_charcode:w \l__tl_analysis_token \l__tl_analysis_char_token \__tl_analysis_a_store: \else: \int_incr:N \l__tl_analysis_normal_int \fi: \__tl_analysis_a_loop:w } \cs_new_protected_nopar:Npn \__tl_analysis_a_store: { \tex_advance:D \l__tl_analysis_nesting_int \l__tl_analysis_type_int \if_int_compare:w \tex_lccode:D \c_zero = \c_thirty_two \tex_multiply:D \l__tl_analysis_type_int \c_two \fi: \tex_skip:D \l__tl_analysis_index_int = \l__tl_analysis_normal_int sp plus \l__tl_analysis_type_int sp \scan_stop: \int_incr:N \l__tl_analysis_index_int \int_zero:N \l__tl_analysis_normal_int \if_int_compare:w \l__tl_analysis_nesting_int = \c_minus_one \cs_set_eq:NN \__tl_analysis_a_loop:w \scan_stop: \fi: } \cs_new_protected:Npn \__tl_analysis_a_safe:N #1 { \if_charcode:w \scan_stop: \exp_after:wN \use_none:n \token_to_str:N #1 \prg_do_nothing: \scan_stop: \int_incr:N \l__tl_analysis_normal_int \else: \__tl_analysis_cs_space_count:NN \__tl_analysis_a_cs:ww #1 \fi: \__tl_analysis_a_loop:w } \cs_new_protected:Npn \__tl_analysis_a_cs:ww #1; #2; { \if_int_compare:w #1 > \c_zero \tex_skip:D \l__tl_analysis_index_int = \__int_eval:w \l__tl_analysis_normal_int + \c_one sp \scan_stop: \tex_advance:D \l__tl_analysis_index_int #1 \exp_stop_f: \l__tl_analysis_normal_int #2 \exp_stop_f: \else: \tex_advance:D \l__tl_analysis_normal_int #2 \exp_stop_f: \fi: } \cs_new_protected:Npn \__tl_analysis_b:n #1 { \tl_gset:Nx \g__tl_analysis_result_tl { \__tl_analysis_b_loop:w 0; #1 \__prg_break_point: } } \cs_new:Npn \__tl_analysis_b_loop:w #1; { \exp_after:wN \__tl_analysis_b_normals:ww \__int_value:w \tex_skip:D #1 ; #1 ; } \cs_new:Npn \__tl_analysis_b_normals:ww #1; { \if_int_compare:w #1 = \c_zero \__tl_analysis_b_special:w \fi: \__tl_analysis_b_normal:wwN #1; } \cs_new:Npn \__tl_analysis_b_normal:wwN #1; #2; #3 { \exp_not:n { \exp_not:n { #3 } } \s__tl \if_charcode:w \scan_stop: \exp_after:wN \use_none:n \token_to_str:N #3 \prg_do_nothing: \scan_stop: \exp_after:wN \__tl_analysis_b_char:Nww \else: \exp_after:wN \__tl_analysis_b_cs:Nww \fi: #3 #1; #2; } \group_begin: \char_set_catcode_other:N A \char_set_catcode_other:N B \char_set_catcode_other:N C \char_set_uccode:nn { `? } { `D } \tl_to_uppercase:n { \cs_new:Npn \__tl_analysis_b_char:Nww #1 { \if_meaning:w #1 \c_undefined:D ? \else: \if_catcode:w #1 \c_catcode_other_token C \else: \if_catcode:w #1 \c_catcode_letter_token B \else: \if_catcode:w #1 \c_math_toggle_token 3 \else: \if_catcode:w #1 \c_alignment_token 4 \else: \if_catcode:w #1 \c_math_superscript_token 7 \else: \if_catcode:w #1 \c_math_subscript_token 8 \else: \if_catcode:w #1 \c_space_token A \else: 6 \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \__int_value:w `#1 \s__tl \exp_after:wN \__tl_analysis_b_normals:ww \int_use:N \__int_eval:w \c_minus_one + } } \group_end: \cs_new:Npn \__tl_analysis_b_cs:Nww #1 { 0 -1 \s__tl \__tl_analysis_cs_space_count:NN \__tl_analysis_b_cs_test:ww #1 } \cs_new:Npn \__tl_analysis_b_cs_test:ww #1 ; #2 ; #3 ; #4 ; { \exp_after:wN \__tl_analysis_b_normals:ww \int_use:N \__int_eval:w \if_int_compare:w #1 = \c_zero #3 \else: \tex_skip:D \__int_eval:w #4 + #1 \__int_eval_end: \fi: - #2 \exp_after:wN ; \int_use:N \__int_eval:w #4 + #1 ; } \group_begin: \char_set_catcode_other:N A \cs_new:Npn \__tl_analysis_b_special:w \fi: \__tl_analysis_b_normal:wwN 0 ; #1 ; { \fi: \if_int_compare:w #1 = \l__tl_analysis_index_int \exp_after:wN \__prg_break: \fi: \tex_the:D \tex_toks:D #1 \s__tl \if_case:w \etex_gluestretch:D \tex_skip:D #1 \exp_stop_f: A \or: 1 \or: 1 \else: 2 \fi: \if_int_odd:w \etex_gluestretch:D \tex_skip:D #1 \exp_stop_f: \exp_after:wN \__tl_analysis_b_special_char:wN \int_use:N \else: \exp_after:wN \__tl_analysis_b_special_space:w \int_use:N \fi: \__int_eval:w \c_one + #1 \exp_after:wN ; \token_to_str:N } \group_end: \cs_new:Npn \__tl_analysis_b_special_char:wN #1 ; #2 { \__int_value:w `#2 \s__tl \__tl_analysis_b_loop:w #1 ; } \cs_new:Npn \__tl_analysis_b_special_space:w #1 ; ~ { 32 \s__tl \__tl_analysis_b_loop:w #1 ; } \cs_new_protected:Npn \__tl_analysis_map_inline:nn #1 { \__tl_analysis:n {#1} \int_gincr:N \g__prg_map_int \exp_args:Nc \__tl_analysis_map_inline_aux:Nn { __tl_analysis_map_inline_ \int_use:N \g__prg_map_int :wNw } } \cs_new_protected:Npn \__tl_analysis_map_inline_aux:Nn #1#2 { \cs_gset_protected:Npn #1 ##1 \s__tl ##2 ##3 \s__tl { \use_none:n ##2 #2 #1 } \exp_after:wN #1 \g__tl_analysis_result_tl \s__tl { ? \tl_map_break: } \s__tl \__prg_break_point:Nn \tl_map_break: { \int_gdecr:N \g__prg_map_int } } \cs_new_protected:Npn \tl_show_analysis:N #1 { \exp_args:No \__tl_analysis:n {#1} \__tl_analysis_show:N #1 } \cs_new_protected:Npn \tl_show_analysis:n #1 { \__tl_analysis:n {#1} \tl_set:Nn \l__tl_analysis_internal_tl {#1} \__tl_analysis_show:N \l__tl_analysis_internal_tl } \cs_new_protected:Npn \__tl_analysis_show:N #1 { \group_begin: \use:x { \group_end: \exp_not:n { \__msg_show_variable:Nnn #1 } { tl-analysis } { \exp_after:wN \__tl_analysis_show_loop:wNw \g__tl_analysis_result_tl \s__tl { ? \__prg_break: } \s__tl \__prg_break_point: } } } \cs_new:Npn \__tl_analysis_show_loop:wNw #1 \s__tl #2 #3 \s__tl { \use_none:n #2 \exp_not:n { \\ > \ \ } \if_int_compare:w "#2 = \c_zero \exp_after:wN \__tl_analysis_show_cs:n \else: \if_int_compare:w "#2 = \c_thirteen \exp_after:wN \exp_after:wN \exp_after:wN \__tl_analysis_show_active:n \else: \exp_after:wN \exp_after:wN \exp_after:wN \__tl_analysis_show_normal:n \fi: \fi: {#1} \__tl_analysis_show_loop:wNw } \cs_new:Npn \__tl_analysis_show_normal:n #1 { \exp_after:wN \token_to_str:N #1 ~ ( \exp_after:wN \token_to_meaning:N #1 ) } \cs_new:Npn \__tl_analysis_show_value:N #1 { \token_if_expandable:NF #1 { \token_if_chardef:NTF #1 \__prg_break: { } \token_if_mathchardef:NTF #1 \__prg_break: { } \token_if_dim_register:NTF #1 \__prg_break: { } \token_if_int_register:NTF #1 \__prg_break: { } \token_if_skip_register:NTF #1 \__prg_break: { } \token_if_toks_register:NTF #1 \__prg_break: { } \use_none:nnn \__prg_break_point: \use:n { = \tex_the:D #1 } } } \cs_new:Npn \__tl_analysis_show_cs:n #1 { \exp_args:No \__tl_analysis_show_long:nn {#1} { control~sequence= } } \cs_new:Npn \__tl_analysis_show_active:n #1 { \exp_args:No \__tl_analysis_show_long:nn {#1} { active~character= } } \cs_new:Npn \__tl_analysis_show_long:nn #1 { \__tl_analysis_show_long_aux:oofn { \token_to_str:N #1 } { \token_to_meaning:N #1 } { \__tl_analysis_show_value:N #1 } } \cs_new:Npn \__tl_analysis_show_long_aux:nnnn #1#2#3#4 { \int_compare:nNnTF { \str_count:n { #1 ~ ( #4 #2 #3 ) } } > { \l_iow_line_count_int - \c_three } { \str_substr:nnn { #1 ~ ( #4 #2 #3 ) } \c_one { \l_iow_line_count_int - \c_three - \str_count:N \c__tl_analysis_show_etc_str } \c__tl_analysis_show_etc_str } { #1 ~ ( #4 #2 #3 ) } } \cs_generate_variant:Nn \__tl_analysis_show_long_aux:nnnn { oof } \tl_const:Nx \c__tl_analysis_show_etc_str % ( { \token_to_str:N \ETC.) } \__msg_kernel_new:nnn { kernel } { show-tl-analysis } { The~token~list~ \str_if_eq:nnF {#1} { \l__tl_analysis_internal_tl } { \token_to_str:N #1 ~ } \tl_if_empty:NTF #1 { is~empty } { contains~the~tokens: } } %% %% %% End of file `l3tl-analysis.sty'.