Überarbeitungsverlauf[Zurück]
Klicke auf Einblenden/Ausblenden von Überarbeitungen 5
mini änderung

09 Apr '17, 15:32

cgnieder's gravatar image

cgnieder
22.1k253463

Du hast in beiden Definitionen kleine aber wesentliche Fehler. In der Tokenlist-Definition hast Du folgende Zeile: \tl_set:Nn \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} Wenn Du die damit definierte Tokenlist mit `\tl_show:N \l_zeichen_tl` inspizierst, zeigt es Dir z.B. > \l_zeichen_tl=\str_item_ignore_spaces:nn {12ab}{1} Ändere die Zeile in \tl_set:Nx \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} und daraus wird > \l_zeichen_tl=1 Das reicht aber noch nicht. `\tl_case:Nn` testet gegen den Inhalt von Variablen, nicht gegen einzelne Token. Du musst also passende Testvariablen definieren \tl_const:Nn \c_zeichen_case_a_tl {0} \tl_const:Nn \c_zeichen_case_b_tl {1} \tl_const:Nn \c_zeichen_case_c_tl {a} \tl_const:Nn \c_zeichen_case_d_tl {b} und verwenden: \tl_case:NnF \l_zeichen_tl { \c_zeichen_case_a_tl {} \c_zeichen_case_b_tl {} \c_zeichen_case_c_tl {} \c_zeichen_case_d_tl {} } {...} Das reicht immer noch nicht: in Tokenlists hängt ein Match auch vom Kategoriecode der Zeichen ab. Mit \tl_set:Nx \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} ensteht eine Tokenliste, in der alle Zeichen Kategoriecode 12 haben. In den Testvariablen haben sie das mit obiger Definition nicht. Darum ändern wir noch mal: \tl_set:Nx \l_zeichen_tl {\tl_item:nn {#1} {##1}} Und jetzt klappt der Test. ---------- In der String-Variante hast Du ähnliche Fehler: \str_set:Nn \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} Ändere das in \str_set:Nx \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} Außerdem hast Du \str_case:nnF {\l_zeichen_str} ... Das vergleicht aber *nicht* den Inhalt der Variablen `\l_zeichen_str` mit den verschiedenen Fällen, sondern den String `\ l _ z e i c h e n _ s t r` (ohne Leerzeichen). Du brauchst die Variante \str_case:VnF \l_zeichen_str ... die Du am besten mit \cs_generate_variant:Nn \str_case:nnF {V} bereitstellst. ---------- Mit diesen Korrekturen funktioniert Dein Code: \documentclass{article} \usepackage[check-declarations]{expl3} \usepackage{xparse} \ExplSyntaxOn \int_new:N \l_zeichenzahl_int \tl_new:N \l_zeichen_tl \str_new:N \l_zeichen_str \tl_const:Nn \c_zeichen_case_a_tl {0} \tl_const:Nn \c_zeichen_case_b_tl {1} \tl_const:Nn \c_zeichen_case_c_tl {a} \tl_const:Nn \c_zeichen_case_d_tl {b} \cs_new_protected:Npn \test_mit_tl:n #1 { \int_set:Nn \l_zeichenzahl_int {\str_count_ignore_spaces:n {#1}} \cs_set:Npn \zeichen_pruefen:n ##1 { \tl_set:Nx \l_zeichen_tl {\tl_item:nn {#1} {##1}} \tl_case:NnF \l_zeichen_tl { \c_zeichen_case_a_tl {} \c_zeichen_case_b_tl {} \c_zeichen_case_c_tl {} \c_zeichen_case_d_tl {} } {\PackageWarning{noname}{Falsches~Zeichen~(tl):~\l_zeichen_tl}} } \int_step_function:nnnN {1} {1} {\l_zeichenzahl_int} \zeichen_pruefen:n } \cs_new_protected:Npn \test_mit_str:n #1 { \int_set:Nn \l_zeichenzahl_int {\str_count_ignore_spaces:n {#1}} \cs_set:Npn \zeichen_pruefen:n ##1 { \str_set:Nx \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} \str_case:VnF {\l_zeichen_str} { {0} {} {1} {} {a} {} {b} {} } {\PackageWarning{noname}{Falsches~Zeichen~(str):~\l_zeichen_str}} } \int_step_function:nnnN {1} {1} {\l_zeichenzahl_int} \zeichen_pruefen:n } \cs_generate_variant:Nn \str_case:nnF {V} \NewDocumentCommand \Befehl {m} { \test_mit_tl:n {#1} \test_mit_str:n {#1} } \ExplSyntaxOff \begin{document} \Befehl{12ab} \Befehl{12 ab} \end{document} Im Log: Package noname Warning: Falsches Zeichen (tl): 2 on input line 63. Package noname Warning: Falsches Zeichen (str): 2 on input line 63. Package noname Warning: Falsches Zeichen (tl): 2 on input line 65. Package noname Warning: Falsches Zeichen (str): 2 on input line 65. ---------- Das ganze geht aber auch erheblich leichter: \documentclass{article} \usepackage{expl3,xparse} \ExplSyntaxOn \tl_new:N \l_check_input_allowed_tl \tl_set:Nn \l_check_input_allowed_tl {01ab} \seq_new:N \l_check_input_wrong_seq \cs_new_protected:Npn \check_input:n #1 { \seq_clear:N \l_check_input_wrong_seq \tl_map_inline:nn {#1} { \tl_if_in:NnF \l_check_input_allowed_tl {##1} { \PackageWarning {noname} {Falsche~ Zeichen:~ `##1'} } } } \NewDocumentCommand \checkinput {m} { \check_input:n {#1} } \ExplSyntaxOff \begin{document} \checkinput{} \checkinput{foo} \checkinput{ab10} \checkinput{a1b0} \checkinput{a1c0} \checkinput{ab 10} \end{document} Im Log: Package noname Warning: Falsche Zeichen: `f' on input line 26. Package noname Warning: Falsche Zeichen: `o' on input line 26. Package noname Warning: Falsche Zeichen: `o' on input line 26. Package noname Warning: Falsche Zeichen: `c' on input line 29.
Klicke auf Einblenden/Ausblenden von Überarbeitungen 4

26 Mai '16, 12:12

cgnieder's gravatar image

cgnieder
22.1k253463

Du hast in beiden Definitionen kleine aber wesentliche Fehler. In der Tokenlist-Definition hast Du folgende Zeile: \tl_set:Nn \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} Wenn Du die damit definierte Tokenlist mit `\tl_show:N \l_zeichen_tl` inspizierst, zeigt es Dir z.B. > \l_zeichen_tl=\str_item_ignore_spaces:nn {12ab}{1} Ändere die Zeile in \tl_set:Nx \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} und daraus wird > \l_zeichen_tl=1 Das reicht aber noch nicht. `\tl_case:Nn` testet gegen den Inhalt von Variablen, nicht gegen einzelne Token. Du musst also passende Testvariablen definieren \tl_const:Nn \c_zeichen_case_a_tl {0} \tl_const:Nn \c_zeichen_case_b_tl {1} \tl_const:Nn \c_zeichen_case_c_tl {a} \tl_const:Nn \c_zeichen_case_d_tl {b} und verwenden: \tl_case:NnF \l_zeichen_tl { \c_zeichen_case_a_tl {} \c_zeichen_case_b_tl {} \c_zeichen_case_c_tl {} \c_zeichen_case_d_tl {} } {...} Das reicht immer noch nicht: in Tokenlists hängt ein Match auch vom Kategoriecode der Zeichen ab. Mit \tl_set:Nx \l_zeichen_tl {\str_item_ignore_spaces:nn {#1} {##1}} ensteht eine Tokenliste, in der alle Zeichen Kategoriecode 12 haben. In den Testvariablen haben sie das mit obiger Definition nicht. Darum ändern wir noch mal: \tl_set:Nx \l_zeichen_tl {\tl_item:nn {#1} {##1}} Und jetzt klappt der Test. ---------- In der String-Variante hast Du ähnliche Fehler: \str_set:Nn \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} Ändere das in \str_set:Nx \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} Außerdem hast Du \str_case:nnF {\l_zeichen_str} ... Das vergleicht aber *nicht* den Inhalt der Variablen `\l_zeichen_str` mit den verschiedenen Fällen, sondern den String `\ l _ z e i c h e n _ s t r` (ohne Leerzeichen). Du brauchst die Variante \str_case:VnF \l_zeichen_str ... die Du am besten mit \cs_generate_variant:Nn \str_case:nnF {V} bereitstellst. ---------- Mit diesen Korrekturen funktioniert Dein Code: \documentclass{article} \usepackage[check-declarations]{expl3} \usepackage{xparse} \ExplSyntaxOn \int_new:N \l_zeichenzahl_int \tl_new:N \l_zeichen_tl \str_new:N \l_zeichen_str \tl_const:Nn \c_zeichen_case_a_tl {0} \tl_const:Nn \c_zeichen_case_b_tl {1} \tl_const:Nn \c_zeichen_case_c_tl {a} \tl_const:Nn \c_zeichen_case_d_tl {b} \cs_new_protected:Npn \test_mit_tl:n #1 { \int_set:Nn \l_zeichenzahl_int {\str_count_ignore_spaces:n {#1}} \cs_set:Npn \zeichen_pruefen:n ##1 { \tl_set:Nx \l_zeichen_tl {\tl_item:nn {#1} {##1}} \tl_case:NnF \l_zeichen_tl { \c_zeichen_case_a_tl {} \c_zeichen_case_b_tl {} \c_zeichen_case_c_tl {} \c_zeichen_case_d_tl {} } {\PackageWarning{noname}{Falsches~Zeichen~(tl):~\l_zeichen_tl}} } \int_step_function:nnnN {1} {1} {\l_zeichenzahl_int} \zeichen_pruefen:n } \cs_new_protected:Npn \test_mit_str:n #1 { \int_set:Nn \l_zeichenzahl_int {\str_count_ignore_spaces:n {#1}} \cs_set:Npn \zeichen_pruefen:n ##1 { \str_set:Nx \l_zeichen_str {\str_item_ignore_spaces:nn {#1} {##1}} \str_case:VnF {\l_zeichen_str} { {0} {} {1} {} {a} {} {b} {} } {\PackageWarning{noname}{Falsches~Zeichen~(str):~\l_zeichen_str}} } \int_step_function:nnnN {1} {1} {\l_zeichenzahl_int} \zeichen_pruefen:n } \cs_generate_variant:Nn \str_case:nnF {V} \NewDocumentCommand \Befehl {m} { \test_mit_tl:n {#1} \test_mit_str:n {#1} } \ExplSyntaxOff \begin{document} \Befehl{12ab} \Befehl{12 ab} \end{document} Im Log: Package noname Warning: Falsches Zeichen (tl): 2 on input line 63. Package noname Warning: Falsches Zeichen (str): 2 on input line 63. Package noname Warning: Falsches Zeichen (tl): 2 on input line 65. Package noname Warning: Falsches Zeichen (str): 2 on input line 65. ---------- Das ganze geht aber auch erheblich leichter: \documentclass{article} \usepackage{expl3,xparse} \ExplSyntaxOn \tl_new:N \l_check_input_allowed_tl \tl_set:Nn \l_check_input_allowed_tl {01ab} \seq_new:N \l_check_input_wrong_seq \cs_new_protected:Npn \check_input:n #1 { \seq_clear:N \l_check_input_wrong_seq \tl_map_inline:nn {#1} { \tl_if_in:NnF \l_check_input_allowed_tl {##1} { \seq_put_right:Nn \l_check_input_wrong_seq {##1} } } \seq_map_inline:Nn \l_check_input_wrong_seq { \PackageWarning {noname} {Falsche~ Zeichen:~ `##1'} } } } \NewDocumentCommand \checkinput {m} { \check_input:n {#1} } \ExplSyntaxOff \begin{document} \checkinput{} \checkinput{foo} \checkinput{ab10} \checkinput{a1b0} \checkinput{a1c0} \checkinput{ab 10} \end{document} Im Log: Package noname Warning: Falsche Zeichen: `f' on input line 28. 26. Package noname Warning: Falsche Zeichen: `o' on input line 28. 26. Package noname Warning: Falsche Zeichen: `o' on input line 28. 26. Package noname Warning: Falsche Zeichen: `c' on input line 31.29.
Klicke auf Einblenden/Ausblenden von Überarbeitungen 3

24 Mai '16, 13:28

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 2

24 Mai '16, 13:25

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 1

24 Mai '16, 13:20

cgnieder's gravatar image

cgnieder
22.1k253463