% phonenumbers.sty % LaTeX-Paket zur Formatierung von Telefonnummern % LaTeX package for formatting telephone numbers % Autor: K. Wehr % Version: 2.3 % Datum: 20. August 2021 % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. \ProvidesExplPackage {phonenumbers} {2021-08-20} {2.3} {Telephone number package} \RequirePackage{l3keys2e} \RequirePackage{ltxcmds} \clist_const:Nn \c_phone_ziffern_clist {0,1,2,3,4,5,6,7,8,9} \clist_const:Nn \c_phone_gliederungszeichen_clist {(,),[,],/} \tl_const:Nn \c_phone_bindestrich_tl { \kern 1pt - \kern 1pt } \tl_const:Nn \c_phone_schraegstrich_tl { \kern 1pt \slash \kern 1pt } \tl_const:Nn \c_phone_pluszeichen_tl { + \kern 1pt } \str_new:N \l_phone_land_str \str_new:N \l_phone_heimatland_str \str_new:N \l_phone_auslandsvorwahltyp_str \str_new:N \l_phone_vorwahl_str \str_new:N \l_phone_vorwahldarstellung_str \str_new:N \l_phone_vorwahltrennung_str \str_new:N \l_phone_auslandsvorwahltrennung_str \str_new:N \l_phone_heimatvorwahl_str \str_new:N \l_phone_rufnummer_str \str_new:N \l_phone_bereinigte_nummer_str \str_new:N \l_phone_bereinigte_durchwahl_str \str_new:N \l_phone_linktext_str \int_new:N \l_phone_ziffernzahl_int \int_new:N \l_phone_nummerlaenge_int \tl_new:N \l_phone_ausgabetext_tl \tl_new:N \l_phone_formatierte_nummer_tl \bool_new:N \l_phone_vorwahl_gefunden_bool \bool_new:N \l_phone_zeilenumbruch_bool \bool_new:N \l_phone_eingabe_leer_bool \bool_new:N \l_phone_durchwahl_leer_bool \bool_new:N \l_phone_nummer_verlinken_bool \bool_new:N \l_phone_teilnehmerrufnummer_gueltig_bool \cs_generate_variant:Nn \str_if_eq:nnT {xnT} \cs_generate_variant:Nn \str_if_eq:nnF {xnF} \cs_generate_variant:Nn \str_if_eq:nnTF {xnTF} \cs_generate_variant:Nn \str_case:nn {xn} \cs_generate_variant:Nn \str_case:nnT {xnT} \cs_generate_variant:Nn \str_case:nnF {xnF} \cs_generate_variant:Nn \str_case:nnTF {xnTF} \cs_generate_variant:Nn \str_tail:n {x} \cs_generate_variant:Nn \tl_put_right:Nn {Nv} \cs_generate_variant:Nn \msg_warning:nnn {onn} \cs_generate_variant:Nn \msg_warning:nnn {nnV} \msg_new:nnn {phonenumbers} {illegal character} { illegal~character~'#1'~in~phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {empty input} { empty~phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {empty extension} { empty~extension~(Durchwahl)~ \msg_line_context: } \msg_new:nnn {phonenumbers} {illegal extension} { extension~(Durchwahl)~of~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ignored~ \msg_line_context: } \msg_new:nnn {phonenumbers} {odd extension} { \phone_landesadjektiv:V \l_phone_land_str \c_space_tl non-geographic~number~should~not~contain~an~extension~(Durchwahl)~ \msg_line_context: } \msg_new:nnn {phonenumbers} {subscriber number too short} { subscriber~number~(Teilnehmerrufnummer)~has~less~than~#1~digits~in~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {subscriber number too long} { subscriber~number~(Teilnehmerrufnummer)~has~more~than~#1~digits~in~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {illegal start of subscriber number} { subscriber~number~(Teilnehmerrufnummer)~starts~with~#1~in~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {missing subscriber number} { no~subscriber~number~(Teilnehmerrufnummer)~given~in~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {invalid area code} { unknown~area~code~(Vorwahl)~in~ \phone_landesadjektiv:V \l_phone_land_str \c_space_tl phone~number~ \msg_line_context: } \msg_new:nnn {phonenumbers} {number too short} { \phone_landesadjektiv:V \l_phone_land_str \c_space_tl #1~number~has~less~than~#2~digits~ \msg_line_context: } \msg_new:nnn {phonenumbers} {number too long} { \phone_landesadjektiv:V \l_phone_land_str \c_space_tl #1~number~has~more~than~#2~digits~ \msg_line_context: } \msg_new:nnn {phonenumbers} {home country set} { home~country~set~to~ \l_phone_heimatland_str \c_space_tl \msg_line_context: } \msg_new:nnn {phonenumbers} {home country cleared} { home~country~ \l_phone_heimatland_str \c_space_tl has~been~deleted~ \msg_line_context: } \msg_new:nnn {phonenumbers} {home area code set} { Your~home~is~in~ \tl_use:c {c_phone_\l_phone_heimatland_str _ortsname_#1_tl} \c_space_tl (area~code~#1)~according~to~line~ \msg_line_number:. } \msg_new:nnn {phonenumbers} {home area code cleared} { home~area~code~ \l_phone_heimatvorwahl_str \c_space_tl has~been~deleted~\msg_line_context: } \msg_new:nnn {phonenumbers} {invalid home area code} { #1~unknown~as~ \phone_landesadjektiv:V \l_phone_heimatland_str \c_space_tl geographic~area~code~(Ortsvorwahl)~ \msg_line_context: } \msg_new:nnn {phonenumbers} {invalid country code} { illegal~country~code~ \msg_line_context: } \msg_new:nnn {phonenumbers} {country code only} { phone~number~consists~of~a~country~code~only~ \msg_line_context: } \cs_new:Npn \phone_landesadjektiv:n #1 { \str_case:nnF {#1} { {DE} {German} {AT} {Austrian} {FR} {French} {UK} {British} {US} {North~American} } { unsupported } } \cs_generate_variant:Nn \phone_landesadjektiv:n {V} \keys_define:nn {phonenumbers} { country .choices:nn = {DE,AT,FR,UK,US} { \str_set_eq:NN \l_phone_land_str \l_keys_choice_tl }, country .initial:n = DE, country .value_required:n = true } \keys_define:nn {phonenumbers} { home-country .choices:nn = {DE,AT,FR,UK,US,none} { \str_if_eq:VnTF \l_keys_choice_tl {none} { \str_if_empty:NF \l_phone_heimatland_str { \msg_info:nn {phonenumbers} {home country cleared} \str_clear:N \l_phone_heimatland_str } } { \str_set_eq:NN \l_phone_heimatland_str \l_keys_choice_tl \msg_info:nn {phonenumbers} {home country set} } \str_if_empty:NF \l_phone_heimatvorwahl_str { \msg_info:nn {phonenumbers} {home area code cleared} \str_clear:N \l_phone_heimatvorwahl_str } }, home-country .initial:n = none, home-country .value_required:n = true } \keys_define:nn {phonenumbers} { foreign .choices:nn = {off,european,american,international} { \str_set_eq:NN \l_phone_auslandsvorwahltyp_str \l_keys_choice_tl }, foreign .initial:n = off, foreign .default:n = international } \keys_define:nn {phonenumbers} { area-code .choices:nn = {number,place,place-and-number} { \str_set_eq:NN \l_phone_vorwahldarstellung_str \l_keys_choice_tl }, area-code .initial:n = number, area-code .value_required:n = true } \keys_define:nn {phonenumbers} { area-code-sep .choices:nn = {space,slash,brackets,hyphen} { \str_set_eq:NN \l_phone_vorwahltrennung_str \l_keys_choice_tl }, area-code-sep .initial:n = slash, area-code-sep .value_required:n = true } \keys_define:nn {phonenumbers} { foreign-area-code-sep .choices:nn = {space,brackets} { \str_set_eq:NN \l_phone_auslandsvorwahltrennung_str \l_keys_choice_tl }, foreign-area-code-sep .initial:n = space, foreign-area-code-sep .value_required:n = true } \keys_define:nn {phonenumbers} { link .choices:nn = {on,off} { \str_if_eq:VnTF \l_keys_choice_tl {on} { \bool_set_true:N \l_phone_nummer_verlinken_bool } { \bool_set_false:N \l_phone_nummer_verlinken_bool } }, link .initial:n = on, link .value_required:n = true } \keys_define:nn {phonenumbers} { home-area-code .code:n = { \str_if_eq:nnTF {#1}{none} { \str_if_empty:NF \l_phone_heimatvorwahl_str { \msg_info:nn {phonenumbers} {home area code cleared} \str_clear:N \l_phone_heimatvorwahl_str } } { \str_if_empty:NT \l_phone_heimatland_str { \str_set_eq:NN \l_phone_heimatland_str \l_phone_land_str \msg_info:nn {phonenumbers} {home country set} } \phone_heimatvorwahl_erlaubt:nT {#1} { % Auslassen der Vorwahl möglich, Heimatvorwahl setzen: \str_set:Nn \l_phone_heimatvorwahl_str {#1} \msg_info:nnn {phonenumbers} {home area code set} {#1} } } }, home-area-code .initial:n = none, home-area-code .value_required:n = true } % Prüfe, ob eine Vorwahl als Heimatvorwahl zulässig ist. % #1: Heimatvorwahl \prg_new_protected_conditional:Npnn \phone_heimatvorwahl_erlaubt:n #1 {T} { \clist_if_in:cnTF {c_phone_\l_phone_heimatland_str _ortsvorwahlen_clist} {#1} { \str_case:VnF \l_phone_heimatland_str { % alle deutschen Ortsvorwahlen können Heimatvorwahl sein {DE} { \prg_return_true: } % alle österreichischen Ortsvorwahlen können Heimatvorwahl sein {AT} { \prg_return_true: } % in Frankreich kann nur 0508 Heimatvorwahl sein {FR} { \str_if_eq:nnTF {#1} {0508} { \prg_return_true: } { \msg_warning:nnn {phonenumbers} {FR/illegal home area code} {#1} \prg_return_false: } } } { % Name der Liste mit den obligatorischen Ortsvorwahlen \str_set:Nx \l_tmpa_str {c_phone_\l_phone_heimatland_str _obligatorische_ortsvorwahlen_clist} % in anderen Ländern können nur nicht obligatorische Ortsvorwahlen Heimatvorwahl sein \clist_if_exist:cTF {\l_tmpa_str} { \clist_if_in:cnTF {\l_tmpa_str} {#1} { \msg_warning:onn {phonenumbers} {\l_phone_heimatland_str/illegal home area code} {#1} \prg_return_false: } { \prg_return_true: } } { \prg_return_true: } } } { \msg_warning:nnn {phonenumbers} {invalid home area code} {#1} \prg_return_false: } } \cs_new_protected:Npn \phone_von_vorne_gruppiert_schreiben:n #1 { \int_set:Nn \l_phone_ziffernzahl_int { \tl_count:n {#1} } \tl_clear:N \l_phone_formatierte_nummer_tl \int_step_inline:nn {\l_phone_ziffernzahl_int} { \tl_put_right:Nx \l_phone_formatierte_nummer_tl { \tl_item:nn {#1} {##1} } \int_if_even:nT {##1} { \int_compare:nNnT {##1} < {\l_phone_ziffernzahl_int} { \tl_put_right:Nn \l_phone_formatierte_nummer_tl {\,} } } } \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_formatierte_nummer_tl } \cs_generate_variant:Nn \phone_von_vorne_gruppiert_schreiben:n {x,V} \cs_new_protected:Npn \phone_von_hinten_gruppiert_schreiben:n #1 { \int_set:Nn \l_phone_ziffernzahl_int { \tl_count:n {#1} } \tl_clear:N \l_phone_formatierte_nummer_tl \int_step_inline:nnnn {\l_phone_ziffernzahl_int} {-1} {1} { \tl_put_left:Nx \l_phone_formatierte_nummer_tl { \tl_item:nn {#1} {##1} } \int_if_even:nT { \l_phone_ziffernzahl_int + 1 - ##1 } { \int_compare:nNnT {##1} > {1} { \tl_put_left:Nn \l_phone_formatierte_nummer_tl {\,} } } } \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_formatierte_nummer_tl } \cs_generate_variant:Nn \phone_von_hinten_gruppiert_schreiben:n {x,V} % #1: Landeskennzahl \cs_new_protected:Npn \phone_auslandsvorwahl_schreiben:n #1 { \str_case:VnTF \l_phone_land_str { {DE} { } {AT} { } {FR} { } } { \str_case:Vn \l_phone_auslandsvorwahltyp_str { {international} { \tl_put_right:Nn \l_phone_ausgabetext_tl { \c_phone_pluszeichen_tl #1 } } {european} { \phone_von_hinten_gruppiert_schreiben:n {00#1} } {american} { \phone_von_hinten_gruppiert_schreiben:n {011#1} } } } { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_case:VnF \l_phone_auslandsvorwahltyp_str { {european} {00 #1} {american} {011 #1} } { \c_phone_pluszeichen_tl #1 } } } } \cs_generate_variant:Nn \phone_auslandsvorwahl_schreiben:n {x,V} \bool_new:N \l_phone_erstes_zeichen_bool \bool_new:N \l_phone_zweites_zeichen_bool \bool_new:N \l_phone_auslandsnummer_bool \bool_new:N \l_phone_null_am_anfang_bool \int_new:N \l_phone_bindestrichposition_int % #1: eingebene Nummer \cs_new_protected:Npn \phone_nummer_ueberpruefen:n #1 { \tl_if_blank:nTF {#1} { \msg_warning:nn {phonenumbers} {empty input} \bool_set_true:N \l_phone_eingabe_leer_bool } { \bool_set_false:N \l_phone_eingabe_leer_bool } \str_clear:N \l_phone_bereinigte_nummer_str \bool_set_true:N \l_phone_erstes_zeichen_bool \bool_set_false:N \l_phone_zweites_zeichen_bool \bool_set_false:N \l_phone_auslandsnummer_bool \bool_set_false:N \l_phone_null_am_anfang_bool \tl_map_inline:nn {#1} { \clist_if_in:NnTF \c_phone_ziffern_clist {##1} { % Ziffer eingelesen \str_put_right:Nn \l_phone_bereinigte_nummer_str {##1} \bool_lazy_and:nnT {\l_phone_erstes_zeichen_bool} { \str_if_eq_p:nn {##1} {0} } { \bool_set_true:N \l_phone_null_am_anfang_bool } \bool_if:NT \l_phone_zweites_zeichen_bool { \bool_set_false:N \l_phone_zweites_zeichen_bool \bool_lazy_and:nnT {\l_phone_null_am_anfang_bool} { \str_if_eq_p:nn {##1} {0} } { \bool_set_true:N \l_phone_auslandsnummer_bool \str_clear:N \l_phone_bereinigte_nummer_str } } \bool_if:NT \l_phone_erstes_zeichen_bool { \bool_set_false:N \l_phone_erstes_zeichen_bool \bool_set_true:N \l_phone_zweites_zeichen_bool } } { % keine Ziffer eingelesen \bool_lazy_and:nnTF {\l_phone_erstes_zeichen_bool} { \str_if_eq_p:nn {##1} {+} } { % führendes + eingelesen \bool_set_true:N \l_phone_auslandsnummer_bool \bool_set_false:N \l_phone_erstes_zeichen_bool } { \clist_if_in:NnF \c_phone_gliederungszeichen_clist {##1} { \str_if_eq:nnTF {##1} {-} { % Bindestrich eingelesen \str_put_right:Nn \l_phone_bereinigte_nummer_str {-} } { % unerlaubtes Zeichen (z. B. Buchstaben) eingelesen \msg_warning:nnx {phonenumbers} {illegal character} {##1} } } } } } \bool_if:NT \l_phone_auslandsnummer_bool { \int_set:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_nummer_str } \int_compare:nNnTF {\l_tmpa_int} > {1} { \str_if_eq:xnTF { \str_head:N \l_phone_bereinigte_nummer_str } {1} { \str_set:Nn \l_phone_land_str {US} \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {2} {-1} } } { \int_compare:nNnTF {\l_tmpa_int} > {2} { \str_case:xnTF { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {2} } { {33} { \str_set:Nn \l_phone_land_str {FR} } {43} { \str_set:Nn \l_phone_land_str {AT} } {44} { \str_set:Nn \l_phone_land_str {UK} } {49} { \str_set:Nn \l_phone_land_str {DE} } } { \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {3} {-1} } \str_put_left:Nn \l_phone_bereinigte_nummer_str {0} } { \int_compare:nNnTF {\l_tmpa_int} > {3} { \str_case:xnTF { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {3} } { {262} { \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {-1} } } {508} { } % Saint-Pierre-et-Miquelon {590} { \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {-1} } } {594} { \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {-1} } } {596} { \str_set:Nx \l_phone_bereinigte_nummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {-1} } } } { \str_set:Nn \l_phone_land_str {FR} \str_put_left:Nn \l_phone_bereinigte_nummer_str {0} } { \str_clear:N \l_phone_land_str % Länge größer 3, nicht mit 262, 508, 590, 594 oder 596 beginnend } } { \str_clear:N \l_phone_land_str % Länge 3, nicht mit 49 oder 33 beginnend } } } { \str_clear:N \l_phone_land_str % Länge 2, nicht mit 1 beginnend } } } { \str_clear:N \l_phone_land_str % Länge kleiner oder gleich 1 } } \bool_lazy_and:nnT { \bool_lazy_or_p:nn { \str_if_eq_p:Vn \l_phone_land_str {DE} } { \str_if_eq_p:Vn \l_phone_land_str {AT} } } { \str_if_empty_p:N \l_phone_bereinigte_durchwahl_str } { % deutsche oder österreichische Nummer ohne explizite Durchwahl \int_set:Nn \l_phone_bindestrichposition_int {-1} \int_step_inline:nnnn { \str_count:N \l_phone_bereinigte_nummer_str } {-1} {1} { \int_compare:nNnT {\l_phone_bindestrichposition_int} = {-1} { \str_if_eq:xnT { \str_item:Nn \l_phone_bereinigte_nummer_str {##1} } {-} { \int_set:Nn \l_phone_bindestrichposition_int {##1} } } } \int_compare:nNnF {\l_phone_bindestrichposition_int} = {-1} { % Nummer enthält einen Bindestrich \str_set:Nx \l_tmpa_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} { \l_phone_bindestrichposition_int - 1 } } \tl_remove_all:Nn \l_tmpa_str {-} \phone_enthaelt_vorwahl:NT \l_tmpa_str { \int_compare:nNnT { \str_count:N \l_phone_vorwahl_str } < { \str_count:N \l_tmpa_str } { % dem Bindestrich geht eine Vorwahl voran und der Teil vor dem Bindestrich ist länger als die bloße Vorwahl \bool_set_true:N \l_tmpa_bool } } \str_if_eq:xnF { \str_head:N \l_tmpa_str } {0} { \bool_set_true:N \l_tmpa_bool % Nummer beginnt nicht mit 0 (ist also eine reine Teilnehmerrufnummer) } \bool_if:NT \l_tmpa_bool { % Teil nach dem Bindestrich als Durchwahl abtrennen \phone_durchwahl_ueberpruefen:x { \str_range:Nnn \l_phone_bereinigte_nummer_str { \l_phone_bindestrichposition_int + 1 } {-1} } \str_set_eq:NN \l_phone_bereinigte_nummer_str \l_tmpa_str } } } \tl_remove_all:Nn \l_phone_bereinigte_nummer_str {-} } \cs_generate_variant:Nn \phone_nummer_ueberpruefen:n {x} % #1: eingebene Durchwahl \cs_new_protected:Npn \phone_durchwahl_ueberpruefen:n #1 { \tl_if_blank:nTF {#1} { \msg_warning:nn {phonenumbers} {empty extension} \bool_set_true:N \l_phone_durchwahl_leer_bool } { \bool_set_false:N \l_phone_durchwahl_leer_bool } \str_clear:N \l_phone_bereinigte_durchwahl_str \tl_map_inline:nn {#1} { \clist_if_in:NnTF \c_phone_ziffern_clist {##1} { \str_put_right:Nn \l_phone_bereinigte_durchwahl_str {##1} } { \msg_warning:nnx {phonenumbers} {illegal character} {##1} } } } \cs_generate_variant:Nn \phone_durchwahl_ueberpruefen:n {x} \cs_new_protected:Npn \phone_nummer_ausgeben: { \bool_if:NF \l_phone_eingabe_leer_bool { \str_case:VnF \l_phone_land_str { {DE} {\phone_DE_AT_nummer_schreiben:} {AT} {\phone_DE_AT_nummer_schreiben:} {FR} {\phone_FR_nummer_schreiben:} {UK} {\phone_UK_nummer_schreiben:} {US} {\phone_US_nummer_schreiben:} } { \phone_SONST_nummer_schreiben: } } \bool_lazy_and:nnTF {\l_phone_nummer_verlinken_bool} { ! \str_if_empty_p:N \l_phone_linktext_str } { \ltx@ifpackageloaded {hyperref} { \href { tel \c_colon_str \l_phone_linktext_str } {\l_phone_ausgabetext_tl} } { \l_phone_ausgabetext_tl } } { \l_phone_ausgabetext_tl } } \cs_new_protected:Npn \phone_vorwahlliste_ausgeben:n #1 { \begin{tabbing} \str_case:VnF \l_phone_land_str { {US} { \hspace {3em} } } { \hspace {4em} } \= \kill \bool_set_false:N \l_phone_zeilenumbruch_bool \clist_map_inline:cn {c_phone_\l_phone_land_str _#1_clist} { \bool_if:NTF \l_phone_zeilenumbruch_bool { \\ } { \bool_gset_true:N \l_phone_zeilenumbruch_bool } \str_case:VnTF \l_phone_land_str { {DE} { } {AT} { } {UK} { } } { \phone_gruppierte_vorwahl_schreiben:nN {##1} \c_true_bool \tl_use:N \l_phone_ausgabetext_tl } { \bool_if:nTF { \str_if_eq_p:Vn \l_phone_land_str {FR} } { \phone_von_vorne_gruppiert_schreiben:n {##1} \tl_use:N \l_phone_ausgabetext_tl } { ##1 } } \> \tl_if_exist:cTF {c_phone_\l_phone_land_str _ortsname_##1_tl} { \tl_use:c {c_phone_\l_phone_land_str _ortsname_##1_tl} } { UNKNOWN~PLACE } } \end{tabbing} } \NewDocumentCommand \setphonenumbers {m} { \keys_set:no {phonenumbers} {#1} } \NewDocumentCommand \phonenumber {omo} { \group_begin: \IfValueT {#1} { \keys_set:no {phonenumbers} {#1} } \IfValueT {#3} { \phone_durchwahl_ueberpruefen:x {#3} } \phone_nummer_ueberpruefen:x {#2} \IfValueT {#3} { \bool_lazy_or:nnF { \str_if_eq_p:Vn \l_phone_land_str {DE} } { \str_if_eq_p:Vn \l_phone_land_str {AT} } { \bool_if:NF \l_phone_durchwahl_leer_bool { \msg_warning:nn {phonenumbers} {illegal extension} } } } \phone_nummer_ausgeben: \group_end: } \NewDocumentCommand \AreaCodesGeographic {o} { \group_begin: \IfValueT {#1} { \keys_set:no {phonenumbers} {#1} } \phone_vorwahlliste_ausgeben:n {ortsvorwahlen} \group_end: } \NewDocumentCommand \AreaCodesNonGeographic {o} { \group_begin: \IfValueT {#1} { \keys_set:no {phonenumbers} {#1} } \phone_vorwahlliste_ausgeben:n {sondervorwahlen} \group_end: } \file_input:n {phn-Landeskennzahlen} \NewDocumentCommand \CountryCodes { } { \bool_set_false:N \l_phone_zeilenumbruch_bool \clist_map_inline:Nn \c_phone_landeskennzahlen_clist { \bool_if:NTF \l_phone_zeilenumbruch_bool { \\ } { \bool_set_true:N \l_phone_zeilenumbruch_bool } ##1 } } \int_new:N \l_phone_pruefnummerlaenge_int % #1: Nummer, die auf Enthaltensein einer Vorwahl überprüft wird \prg_new_protected_conditional:Npnn \phone_enthaelt_vorwahl:N #1 {TF,T} { \bool_set_false:N \l_phone_vorwahl_gefunden_bool \int_set:Nn \l_phone_pruefnummerlaenge_int { \str_count:N #1 } \int_step_inline:nnnn {6} {-1} {2} { \bool_if:NF \l_phone_vorwahl_gefunden_bool { \int_compare:nT { \l_phone_pruefnummerlaenge_int >= ##1 } { \str_set:Nx \l_phone_vorwahl_str { \str_range:Nnn #1 {1} {##1} } \clist_if_in:cVT {c_phone_\l_phone_land_str _vorwahlen_clist} \l_phone_vorwahl_str { \bool_set_true:N \l_phone_vorwahl_gefunden_bool } } } } \bool_if:NTF \l_phone_vorwahl_gefunden_bool { \prg_return_true: } { \prg_return_false: } } % #1: Vorwahl, #2: Soll die führende null ausgegeben werden? \cs_new_protected:Npn \phone_gruppierte_vorwahl_schreiben:nN #1#2 { \str_if_eq:VnTF \l_phone_land_str {UK} { % britische Vorwahl \int_compare:nNnTF { \str_count:n {#1} } = {6} { % sechsstellige britische Vorwahl: Gliederung vor der zweitletzten Ziffer \bool_if:NTF #2 { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_range:nnn {#1} {1} {4} } } { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_tail:x { \str_range:nnn {#1} {1} {4} } } } \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_range:nnn {#1} {5} {6} } } { % nicht sechsstellige britische Vorwahl \bool_if:NTF #2 { \tl_put_right:Nn \l_phone_ausgabetext_tl {#1} } { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_tail:n {#1} } } } } { % nichtbritische Vorwahl \bool_lazy_and:nnTF { \str_if_eq_p:Vn \l_phone_land_str {DE} } { \int_compare_p:nNn { \str_count:n {#1} } = {5} } { % fünfstellige deutsche Vorwahl \str_set:Nx \l_tmpa_str { \str_range:nnn {#1} {1} {4} } \str_set:Nx \l_tmpb_str { \str_range:nnn {#1} {5} {5} } \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_tmpa_str {0137} } { \str_if_eq_p:Vn \l_tmpa_str {0180} } { % fünfstellige deutsche Vorwahl mit Tarifkennung: letzte Ziffer steht allein \bool_if:NTF #2 { \phone_von_hinten_gruppiert_schreiben:V \l_tmpa_str } { \phone_von_hinten_gruppiert_schreiben:x { \str_tail:N \l_tmpa_str } } \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} \tl_put_right:NV \l_phone_ausgabetext_tl \l_tmpb_str } { % fünfstellige deutsche Vorwahl ohne Tarifkennung \bool_if:NTF #2 { \phone_von_hinten_gruppiert_schreiben:n {#1} } { \phone_von_hinten_gruppiert_schreiben:x { \str_tail:n {#1} } } } } { % sonstige Vorwahl \bool_if:NTF #2 { \phone_von_hinten_gruppiert_schreiben:n {#1} } { \phone_von_hinten_gruppiert_schreiben:x { \str_tail:n {#1} } } } } } % #1: Vorwahl, #2: Soll die führende null ausgegeben werden? \cs_new_protected:Npn \phone_geklammerte_vorwahl_schreiben:nN #1#2 { % Klammern werden nur bei Ortsvorwahlen gesetzt \clist_if_in:cnTF {c_phone_\l_phone_land_str _ortsvorwahlen_clist} {#1} { \tl_put_right:Nn \l_phone_ausgabetext_tl {(} \phone_gruppierte_vorwahl_schreiben:nN {#1} #2 \tl_put_right:Nn \l_phone_ausgabetext_tl {)} } { \phone_gruppierte_vorwahl_schreiben:nN {#1} #2 } } % #1: Nummer, #2: Mindestlänge, #3: Höchstlänge, #4: Nummernart \cs_new_protected:Npn \phone_nummernlaenge_ueberpruefen:nnnn #1#2#3#4 { \int_set:Nn \l_tmpa_int { \str_count:n {#1} } \int_compare:nNnTF {\l_tmpa_int} < {#2} { \msg_warning:nnnn {phonenumbers} {number too short} {#4} {#2} } { \int_compare:nNnTF {\l_tmpa_int} > {#3} { \msg_warning:nnnn {phonenumbers} {number too long} {#4} {#3} } { \bool_set_true:N \l_phone_teilnehmerrufnummer_gueltig_bool } } } \cs_generate_variant:Nn \phone_nummernlaenge_ueberpruefen:nnnn {V,o} %%%%%%%%%%%%%%%%%%%% DEUTSCHLAND %%%%%%%%%%%%%%%%%%%% \file_input:n {phn-DE_Vorwahlen} \file_input:n {phn-DE_Ortsnamen} \clist_new:N \c_phone_DE_vorwahlen_clist \clist_concat:NNN \c_phone_DE_vorwahlen_clist \c_phone_DE_ortsvorwahlen_clist \c_phone_DE_sondervorwahlen_clist % #1: Vorwahl, #2: Folgt eine Rufnummer? \cs_new_protected:Npn \phone_DE_AT_vorwahl_schreiben:nn #1 #2 { \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:NN \l_phone_heimatland_str \l_phone_land_str } { \clist_if_in:cnT {c_phone_\l_phone_land_str _sondervorwahlen_clist} {#1} { \str_if_eq:VnT \l_phone_vorwahldarstellung_str {place} { \str_set:Nn \l_phone_vorwahldarstellung_str {number} } } \bool_lazy_and:nnF { \str_if_eq_p:NN \l_phone_heimatland_str \l_phone_land_str } { \str_if_eq_p:Vn \l_phone_heimatvorwahl_str {#1} } { \str_case:Vn \l_phone_vorwahldarstellung_str { {number} { \bool_if:nTF {#2} { \str_if_eq:VnTF \l_phone_vorwahltrennung_str {brackets} { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_true_bool \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_case:VnF \l_phone_vorwahltrennung_str { {space} {\c_space_tl} {hyphen} {\c_phone_bindestrich_tl} } { \c_phone_schraegstrich_tl } } } } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } } {place} { \bool_if:nTF {#2} { \str_if_eq:VnT \l_phone_vorwahltrennung_str {brackets} { \tl_put_right:Nn \l_phone_ausgabetext_tl {(} } \tl_if_exist:cTF {c_phone_\l_phone_land_str _ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_\l_phone_land_str _ortsname_#1_tl} } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} {) \c_space_tl} {space} {\c_space_tl} {hyphen} {\c_phone_bindestrich_tl} } { \c_phone_schraegstrich_tl } } } { \tl_if_exist:cTF {c_phone_\l_phone_land_str _ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_\l_phone_land_str _ortsname_#1_tl} } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } } } {place-and-number} { \tl_if_exist:cT {c_phone_\l_phone_land_str _ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_\l_phone_land_str _ortsname_#1_tl} \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } \str_if_eq:VnTF \l_phone_vorwahltrennung_str {brackets} { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_true_bool \bool_if:nT {#2} { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool \bool_if:nT {#2} { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_case:VnF \l_phone_vorwahltrennung_str { {space} {\c_space_tl} {hyphen} {\c_phone_bindestrich_tl} } { \c_phone_schraegstrich_tl } } } } } } } } { \str_if_eq:VnTF \l_phone_land_str {DE} { \phone_auslandsvorwahl_schreiben:n {49} } { \phone_auslandsvorwahl_schreiben:n {43} } \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl \str_if_eq:VnTF \l_phone_auslandsvorwahltrennung_str {brackets} { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_false_bool } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_false_bool } \bool_if:nT {#2} { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } % Linktext schreiben, falls eine Rufnummer folgt \bool_if:nT {#2} { \str_put_right:Nx \l_phone_linktext_str { \str_if_eq:VnTF \l_phone_land_str {DE} {+49} {+43} } \str_put_right:Nx \l_phone_linktext_str { \str_tail:n {#1} } } } \cs_generate_variant:Nn \phone_DE_AT_vorwahl_schreiben:nn {Vx} % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_DE_festnetzteilnehmerrufnummernlaenge_ueberpruefen:Nn #1#2 { \int_set:Nn \l_tmpa_int { \str_count:N #1 } \int_add:Nn \l_tmpa_int { \str_count:n {#2} } \int_add:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_durchwahl_str } \int_compare:nNnTF {\l_tmpa_int} > {13} { % Gesamtnummer hat mehr als 13 Stellen \msg_warning:nnnn {phonenumbers} {number too long} {landline} {13} } { \int_set:Nn \l_tmpa_int { \str_count:n {#2} } \int_add:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_durchwahl_str } \int_compare:nNnTF {\l_tmpa_int} < {3} { % Teilnehmerrufnummer hat weniger als 3 Stellen \msg_warning:nnn {phonenumbers} {subscriber number too short} {3} } { \bool_set_true:N \l_phone_teilnehmerrufnummer_gueltig_bool } } } % #1: Nummer \cs_new_protected:Npn \phone_DE_MABEZnummernlaenge_ueberpruefen:N #1 { \int_set:Nn \l_tmpa_int { \str_count:N #1 } \int_add:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_durchwahl_str } \int_compare:nNnTF {\l_tmpa_int} > {11} { % Gesamtnummer hat mehr als 11 Stellen \msg_warning:nnnn {phonenumbers} {number too long} {0137~(MABEZ)} {11} } { \int_compare:nNnTF {\l_tmpa_int} < {11} { % Gesamtnummer hat weniger als 11 Stellen \msg_warning:nnnn {phonenumbers} {number too short} {0137~(MABEZ)} {11} } { \bool_set_true:N \l_phone_teilnehmerrufnummer_gueltig_bool } } } % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_DE_teilnehmerrufnummer_schreiben:Nn #1 #2 { % Überprüfen der Nummernlänge \str_if_empty:NTF #1 { % Festnetznummer ohne Vorwahl \bool_if:NF \l_phone_eingabe_leer_bool { \phone_DE_festnetzteilnehmerrufnummernlaenge_ueberpruefen:Nn #1 {#2} } } { \clist_if_in:NVTF \c_phone_DE_ortsvorwahlen_clist #1 { % Festnetznummer \str_if_eq:xnTF { \str_head:n {#2} } {0} { \msg_warning:nnn {phonenumbers} {illegal start of subscriber number} {0} } { \phone_DE_festnetzteilnehmerrufnummernlaenge_ueberpruefen:Nn #1 {#2} } } { % Mobilfunk-/Sondernummer \str_set_eq:NN \l_tmpa_str #1 \str_put_right:Nn \l_tmpa_str {#2} \str_if_eq:xnTF { \str_range:Nnn #1 {1} {5} } {09009} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {12} {12} {09009} } { \str_case:xnF { \str_range:Nnn #1 {1} {4} } { {0137} { \phone_DE_MABEZnummernlaenge_ueberpruefen:N \l_tmpa_str } {0160} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {12} {mobile~phone} } {0162} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {12} {mobile~phone} } {0163} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {12} {mobile~phone} } {0164} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {14} {0164} } % Funkruf {0168} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {15} {0168} } % Funkruf {0169} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {15} {0169} } % Funkruf {0180} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {11} {0180} } {0181} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {8} {15} {0181} } {0191} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {14} {0191} } {0192} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {14} {0192} } {0193} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {5} {14} {0193} } {0194} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {7} {14} {0194} } {0700} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {12} {12} {0700} } {0800} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {14} {freephone} } {0900} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {11} {premium~service} } } { \str_case:xn {\str_range:Nnn #1 {1} {3}} { {015} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {12} {12} {mobile~phone} } {017} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {11} {12} {mobile~phone} } {018} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {12} {12} {018} } {032} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {12} {12} {032} } } } } \str_if_empty:NF \l_phone_bereinigte_durchwahl_str { % Mobilfunk- und Sondernummern dürfen keine Durchwahl enthalten (ausgenommen MABEZ-Nummern) \str_if_eq:xnF { \str_range:Nnn #1 {1} {4} } {0137} { \msg_warning:nn {phonenumbers} {odd extension} } } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { % Für gültige Nummern mit Vorwahl Linktext schreiben: \str_put_right:Nn \l_phone_linktext_str {#2} \str_put_right:NV \l_phone_linktext_str \l_phone_bereinigte_durchwahl_str } { % Für ungültige Nummern mit Vorwahl Linktext löschen: \str_clear:N \l_phone_linktext_str } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { \phone_von_hinten_gruppiert_schreiben:n {#2} } { \str_put_right:Nn \l_phone_ausgabetext_tl {#2} } \str_if_empty:NF \l_phone_bereinigte_durchwahl_str { \tl_put_right:NV \l_phone_ausgabetext_tl \c_phone_bindestrich_tl \phone_von_hinten_gruppiert_schreiben:V \l_phone_bereinigte_durchwahl_str } } \cs_generate_variant:Nn \phone_DE_teilnehmerrufnummer_schreiben:Nn {Nx,NV} \int_new:N \l_phone_DE_AT_hauptnummerlaenge_int \int_new:N \l_phone_DE_AT_vorwahllaenge_int \cs_new_protected:Npn \phone_DE_AT_nummer_schreiben: { \str_if_eq:xnTF { \str_head:N \l_phone_bereinigte_nummer_str } {0} { \phone_enthaelt_vorwahl:NTF \l_phone_bereinigte_nummer_str { \int_set:Nn \l_phone_DE_AT_hauptnummerlaenge_int { \str_count:N \l_phone_bereinigte_nummer_str } \int_set:Nn \l_phone_DE_AT_vorwahllaenge_int { \str_count:N \l_phone_vorwahl_str } \phone_DE_AT_vorwahl_schreiben:Vx \l_phone_vorwahl_str { \int_compare_p:nNn {\l_phone_DE_AT_vorwahllaenge_int} < {\l_phone_DE_AT_hauptnummerlaenge_int} } \int_compare:nNnTF {\l_phone_DE_AT_vorwahllaenge_int} = {\l_phone_DE_AT_hauptnummerlaenge_int} { \msg_warning:nn {phonenumbers} {missing subscriber number} } { \use:c {phone_\l_phone_land_str _teilnehmerrufnummer_schreiben:Nx} \l_phone_vorwahl_str { \str_range:Nnn \l_phone_bereinigte_nummer_str { \l_phone_DE_AT_vorwahllaenge_int + 1 } {-1} } } } { \msg_warning:nn {phonenumbers} {invalid area code} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_durchwahl_str } } { \use:c {phone_\l_phone_land_str _teilnehmerrufnummer_schreiben:NV} \c_empty_tl \l_phone_bereinigte_nummer_str } } %%%%%%%%%%%%%%%%%%%% ÖSTERREICH %%%%%%%%%%%%%%%%%%%% \file_input:n {phn-AT_Vorwahlen} \file_input:n {phn-AT_Ortsnamen} \clist_new:N \c_phone_AT_vorwahlen_clist \clist_concat:NNN \c_phone_AT_vorwahlen_clist \c_phone_AT_ortsvorwahlen_clist \c_phone_AT_sondervorwahlen_clist % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_AT_festnetzteilnehmerrufnummernlaenge_ueberpruefen:Nn #1#2 { \int_set:Nn \l_tmpa_int { \str_count:N #1 } \int_add:Nn \l_tmpa_int { \str_count:n {#2} } \int_add:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_durchwahl_str } \int_compare:nNnTF {\l_tmpa_int} > {13} { % Gesamtnummer hat mehr als 13 Stellen \msg_warning:nnnn {phonenumbers} {number too long} {landline} {13} } { \int_set:Nn \l_tmpa_int { \str_count:n {#2} } \int_add:Nn \l_tmpa_int { \str_count:N \l_phone_bereinigte_durchwahl_str } \int_compare:nNnTF {\l_tmpa_int} < {5} { % Teilnehmerrufnummer hat weniger als 5 Stellen \msg_warning:nnn {phonenumbers} {subscriber number too short} {5} } { \bool_lazy_and:nnTF { \str_if_eq_p:Vn #1 {01} } { \int_compare_p:nNn {\l_tmpa_int} < {7} } { % Wiener Teilnehmerrufnummer hat weniger als 7 Stellen \msg_warning:nnn {phonenumbers} {subscriber number too short} {7} } { \bool_lazy_and:nnTF { \bool_lazy_any_p:n { { \str_if_eq_p:Vn #1 {02236} } { \str_if_eq_p:Vn #1 {02252} } { \str_if_eq_p:Vn #1 {0316} } { \str_if_eq_p:Vn #1 {0463} } { \str_if_eq_p:Vn #1 {0512} } { \str_if_eq_p:Vn #1 {05572} } { \str_if_eq_p:Vn #1 {0662} } { \str_if_eq_p:Vn #1 {07242} } { \str_if_eq_p:Vn #1 {0732} } } } { \int_compare_p:nNn {\l_tmpa_int} < {6} } { % Teilnehmerrufnummer in bestimmten Ortsnetzen hat weniger als 6 Stellen \msg_warning:nnn {phonenumbers} {subscriber number too short} {6} } { \int_compare:nNnTF {\l_tmpa_int} > {9} { % Teilnehmerrufnummer hat mehr als 9 Stellen \msg_warning:nnn {phonenumbers} {subscriber number too long} {9} } { \bool_set_true:N \l_phone_teilnehmerrufnummer_gueltig_bool } } } } } } % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_AT_festnetzteilnehmerrufnummer_ueberpruefen:Nn #1#2 { \str_set:Nx \l_tmpa_str { \str_head:n {#2} } \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_tmpa_str {0} } { \str_if_eq_p:Vn \l_tmpa_str {1} } { \msg_warning:nnV {phonenumbers} {illegal start of subscriber number} \l_tmpa_str } { \phone_AT_festnetzteilnehmerrufnummernlaenge_ueberpruefen:Nn #1 {#2} } } % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_AT_teilnehmerrufnummer_schreiben:Nn #1 #2 { \str_if_empty:NTF #1 { % Festnetznummer ohne Vorwahl \bool_if:NF \l_phone_eingabe_leer_bool { \phone_AT_festnetzteilnehmerrufnummer_ueberpruefen:Nn #1 {#2} } } { \clist_if_in:NVTF \c_phone_AT_ortsvorwahlen_clist #1 { % Festnetznummer mit Vorwahl \phone_AT_festnetzteilnehmerrufnummer_ueberpruefen:Nn #1 {#2} } { % Mobilfunk-/Sondernummer \str_set_eq:NN \l_tmpa_str #1 \str_put_right:Nn \l_tmpa_str {#2} \str_case:VnF #1 { {0517} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {VPN} } {0718} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {dial~up} } {0720} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {location~independant} } {0780} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {convergent~service} } {0800} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {freephone} } {0804} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {dial~up} } {0810} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {service} } {0820} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {service} } {0821} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {service} } {0828} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {service} } {0900} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {premium~service} } {0901} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {premium~service} } {0930} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {premium~service} } {0931} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {premium~service} } {0939} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {10} {13} {premium~service} } } { \str_case:xn { \str_range:Nnn #1 {1} {3} } { {050} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {VPN} } {057} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {VPN} } {059} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {VPN} } {065} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {mobile~phone} } {066} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {mobile~phone} } {067} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {mobile~phone} } {068} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {mobile~phone} } {069} { \phone_nummernlaenge_ueberpruefen:Vnnn \l_tmpa_str {9} {13} {mobile~phone} } } } \str_if_empty:NF \l_phone_bereinigte_durchwahl_str { \msg_warning:nn {phonenumbers} {odd extension} } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { % Für gültige Nummern mit Vorwahl Linktext schreiben: \str_put_right:Nn \l_phone_linktext_str {#2} \str_put_right:NV \l_phone_linktext_str \l_phone_bereinigte_durchwahl_str } { % Für ungültige Nummern mit Vorwahl Linktext löschen: \str_clear:N \l_phone_linktext_str } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { \phone_von_hinten_gruppiert_schreiben:n {#2} } { \str_put_right:Nn \l_phone_ausgabetext_tl {#2} } \str_if_empty:NF \l_phone_bereinigte_durchwahl_str { \tl_put_right:NV \l_phone_ausgabetext_tl \c_phone_bindestrich_tl \phone_von_hinten_gruppiert_schreiben:V \l_phone_bereinigte_durchwahl_str } } \cs_generate_variant:Nn \phone_AT_teilnehmerrufnummer_schreiben:Nn {Nx,NV} %%%%%%%%%%%%%%%%%%%% FRANKREICH %%%%%%%%%%%%%%%%%%%% \file_input:n {phn-FR_Vorwahlen} \file_input:n {phn-FR_Ortsnamen} \clist_new:N \c_phone_FR_vorwahlen_clist \clist_concat:NNN \c_phone_FR_vorwahlen_clist \c_phone_FR_ortsvorwahlen_clist \c_phone_FR_sondervorwahlen_clist \msg_new:nnn {phonenumbers} {FR/illegal home area code} { The~only~legal~home~area~code~in~France~is~0508~(Saint-Pierre-et-Miquelon).~#1~cannot~be~set~as~home~area~code~\msg_line_context:. } \msg_new:nnn {phonenumbers} {FR/missing zero} { French~phone~number~has~no~zero~in~the~beginning~\msg_line_context: } % #1: Vorwahl \cs_new:Npn \phone_FR_ermittle_landeskennzahl:n #1 { \str_case:nnF {#1} { {0262} {262} {026200} {262} {0263} {262} {0269} {262} {0508} {508} {0590} {590} {0594} {594} {0596} {596} {0639} {262} {0690} {590} {0691} {590} {0692} {262} {0693} {262} {0694} {594} {0696} {596} {0697} {596} {07005} {590} {07006} {594} {07007} {596} {07008} {262} {07009} {262} {09475} {590} {09476} {594} {09477} {596} {09478} {262} {09479} {262} {09760} {590} {09761} {590} {09762} {262} {09763} {262} {09764} {594} {09765} {594} {09766} {596} {09767} {596} {09768} {590} {09769} {262} } { 33 } } % #1: Vorwahl, #2: Rufnummer \cs_new_protected:Npn \phone_FR_vorwahl_schreiben:nn #1#2 { \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:Vn \l_phone_heimatland_str {FR} } { \clist_if_in:NnT \c_phone_FR_sondervorwahlen_clist {#1} { \str_if_eq:VnT \l_phone_vorwahldarstellung_str {place} { \str_set:Nn \l_phone_vorwahldarstellung_str {number} } } \bool_lazy_and:nnF { \str_if_eq_p:Vn \l_phone_heimatland_str {FR} } { \str_if_eq_p:Vn \l_phone_heimatvorwahl_str {#1} } { \str_case:Vn \l_phone_vorwahldarstellung_str { {number} { \phone_von_vorne_gruppiert_schreiben:n {#1} \int_if_even:nT { \str_count:n {#1} } { \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} } } {place} { \tl_if_exist:cTF {c_phone_FR_ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_FR_ortsname_#1_tl} \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } { \phone_von_vorne_gruppiert_schreiben:n {#1} \int_if_even:nT { \str_count:n {#1} } { \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} } } } {place-and-number} { \tl_if_exist:cT {c_phone_FR_ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_FR_ortsname_#1_tl} \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } \phone_von_vorne_gruppiert_schreiben:n {#1} \int_if_even:nT { \str_count:n {#1} } { \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} } } } } } { \phone_auslandsvorwahl_schreiben:x { \phone_FR_ermittle_landeskennzahl:n {#1} } \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl \str_if_eq:nnF {#1} {0508} % in Saint-Pierre-et-Miquelon entfällt die Ortsvorwahl { \int_if_even:nTF { \str_count:n {#2} } { % Rufnummer hat gerade Stellenanzahl \phone_von_hinten_gruppiert_schreiben:x { \str_tail:n {#1} } \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} } { \int_if_even:nTF { \str_count:n {#1} } { % Rufnummer hat ungerade Stellenanzahl, die Vorwahl ohne die 0 auch \phone_von_vorne_gruppiert_schreiben:x { \str_tail:n {#1} } } { % Rufnummer hat ungerade Stellenanzahl, die Vorwahl ohne die 0 hat gerade Stellenanzahl \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_item:nn {#1} {2} \, } \phone_von_vorne_gruppiert_schreiben:x { \str_range:nnn {#1} {3} {-1} } } } } } \str_put_right:Nx \l_phone_linktext_str { + \phone_FR_ermittle_landeskennzahl:n {#1} } \str_if_eq:nnF {#1} {0508} % in Saint-Pierre-et-Miquelon entfällt die Ortsvorwahl { \str_put_right:Nx \l_phone_linktext_str { \str_tail:n {#1} } } } \cs_generate_variant:Nn \phone_FR_vorwahl_schreiben:nn {VV,xV} \cs_new_protected:Npn \phone_FR_nummer_schreiben: { \int_set:Nn \l_phone_nummerlaenge_int { \str_count:N \l_phone_bereinigte_nummer_str } \int_compare:nNnTF {\l_phone_nummerlaenge_int} < {10} { \str_if_eq:xnTF { \str_head:N \l_phone_bereinigte_nummer_str } {3} { \int_compare:nNnTF {\l_phone_nummerlaenge_int} < {4} { \msg_warning:nnnn {phonenumbers} {number too short} {short} {4} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } { \int_compare:nNnTF {\l_phone_nummerlaenge_int} > {4} { \msg_warning:nnnn {phonenumbers} {number too long} {short} {4} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } { \phone_von_vorne_gruppiert_schreiben:V \l_phone_bereinigte_nummer_str \str_put_right:NV \l_phone_linktext_str \l_phone_bereinigte_nummer_str } } } { \msg_warning:nnnn {phonenumbers} {number too short} {phone} {10} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } { \int_compare:nNnTF {\l_phone_nummerlaenge_int} > {10} { \str_if_eq:xnTF { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {4} } {0700} { \int_compare:nNnTF { \str_item:Nn \l_phone_bereinigte_nummer_str {5} } < {5} { % überlange Mobilfunknummer (machine to machine) im Mutterland (14 Stellen) \str_set:Nx \l_phone_rufnummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {5} {-1} } \phone_FR_vorwahl_schreiben:xV { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {4} } \l_phone_rufnummer_str \phone_nummernlaenge_ueberpruefen:Vnnn \l_phone_bereinigte_nummer_str {14} {14} {machine~to~machine} \bool_if:NT \l_phone_teilnehmerrufnummer_gueltig_bool { \phone_von_vorne_gruppiert_schreiben:V \l_phone_rufnummer_str } } { % überlange Mobilfunknummer (machine to machine) in den Überseegebieten (13 Stellen) \str_set:Nx \l_phone_rufnummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {6} {-1} } \phone_FR_vorwahl_schreiben:xV { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {5} } \l_phone_rufnummer_str \phone_nummernlaenge_ueberpruefen:Vnnn \l_phone_bereinigte_nummer_str {13} {13} {machine~to~machine} \bool_if:NT \l_phone_teilnehmerrufnummer_gueltig_bool { \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:Vn \l_phone_heimatland_str {FR} } { % ohne Auslandsvorwahl steht am Ende eine Einzelziffer \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_head:N \l_phone_rufnummer_str \, } \phone_von_vorne_gruppiert_schreiben:x { \str_tail:N \l_phone_rufnummer_str } } { % mit Auslandsvorwahl ergeben sich durchgehend Zweiergruppen \phone_von_vorne_gruppiert_schreiben:V \l_phone_rufnummer_str } } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { % Für gültige Nummern Linktext schreiben: \str_put_right:NV \l_phone_linktext_str \l_phone_rufnummer_str } { % Für ungültige Nummern Linktext löschen und ungruppierte Nummer schreiben: \str_clear:N \l_phone_linktext_str \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_rufnummer_str } } { \msg_warning:nnnn {phonenumbers} {number too long} {phone} {10} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } { \str_if_eq:xnTF { \str_head:N \l_phone_bereinigte_nummer_str } {0} { \bool_set_false:N \l_phone_vorwahl_gefunden_bool \int_step_inline:nnnn {6} {-1} {2} { \bool_if:NF \l_phone_vorwahl_gefunden_bool { \int_compare:nT { \l_phone_nummerlaenge_int >= ##1 } { \str_set:Nx \l_tmpa_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {##1} } \clist_if_in:NVT \c_phone_FR_vorwahlen_clist \l_tmpa_str { \bool_set_true:N \l_phone_vorwahl_gefunden_bool \str_set:Nx \l_phone_rufnummer_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {##1 + 1} {-1} } \phone_FR_vorwahl_schreiben:VV \l_tmpa_str \l_phone_rufnummer_str \phone_von_hinten_gruppiert_schreiben:V \l_phone_rufnummer_str \str_put_right:NV \l_phone_linktext_str \l_phone_rufnummer_str } } } } \bool_if:NF \l_phone_vorwahl_gefunden_bool { \msg_warning:nn {phonenumbers} {invalid area code} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } { \msg_warning:nn {phonenumbers} {FR/missing zero} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } } } %%%%%%%%%%%%%%%%%%%% GROSSBRITANNIEN %%%%%%%%%%%%%%%%%%%% \file_input:n {phn-UK_Vorwahlen} \file_input:n {phn-UK_Ortsnamen} \clist_new:N \c_phone_UK_vorwahlen_clist \clist_concat:NNN \c_phone_UK_vorwahlen_clist \c_phone_UK_ortsvorwahlen_clist \c_phone_UK_sondervorwahlen_clist \msg_new:nnn {phonenumbers} {UK/illegal home area code} { National~dialling~is~required~in~\tl_use:c {c_phone_UK_ortsname_#1_tl}.~#1~cannot~be~set~as~home~area~code~\msg_line_context:. } \msg_new:nnn {phonenumbers} {UK/national dialling required} { British~subscriber~number~starting~with~0~or~1~requires~an~area~code~\msg_line_context: } % #1: Vorwahl, #2: Folgt eine Rufnummer? \cs_new_protected:Npn \phone_UK_vorwahl_schreiben:nn #1 #2 { \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:Vn \l_phone_heimatland_str {UK} } { \clist_if_in:NnT \c_phone_UK_sondervorwahlen_clist {#1} { \str_if_eq:VnT \l_phone_vorwahldarstellung_str {place} { \str_set:Nn \l_phone_vorwahldarstellung_str {number} } } \bool_lazy_and:nnF { \str_if_eq_p:Vn \l_phone_heimatland_str {UK} } { \str_if_eq_p:Vn \l_phone_heimatvorwahl_str {#1} } { \str_case:Vn \l_phone_vorwahldarstellung_str { {number} { \bool_if:nTF {#2} { \str_if_eq:VnTF \l_phone_vorwahltrennung_str {space} { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_true_bool } \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } } {place} { \bool_if:nTF {#2} { \str_if_eq:VnF \l_phone_vorwahltrennung_str {space} { \tl_put_right:Nn \l_phone_ausgabetext_tl {(} } \tl_if_exist:cTF {c_phone_UK_ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_UK_ortsname_#1_tl} } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } \str_if_eq:VnF \l_phone_vorwahltrennung_str {space} { \tl_put_right:Nn \l_phone_ausgabetext_tl {)} } \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } { \tl_if_exist:cTF {c_phone_UK_ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_UK_ortsname_#1_tl} } { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } } } {place-and-number} { \tl_if_exist:cT {c_phone_UK_ortsname_#1_tl} { \tl_put_right:Nv \l_phone_ausgabetext_tl {c_phone_UK_ortsname_#1_tl} \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } \str_if_eq:VnTF \l_phone_vorwahltrennung_str {space} { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_true_bool } { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_true_bool } \bool_if:nT {#2} { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } } } } { \phone_auslandsvorwahl_schreiben:n {44} \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl \str_if_eq:VnTF \l_phone_auslandsvorwahltrennung_str {space} { \phone_gruppierte_vorwahl_schreiben:nN {#1} \c_false_bool } { \phone_geklammerte_vorwahl_schreiben:nN {#1} \c_false_bool } \bool_if:nT {#2} { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } % Linktext schreiben, falls eine Rufnummer folgt \bool_if:nT {#2} { \str_put_right:Nn \l_phone_linktext_str {+44} \str_put_right:Nx \l_phone_linktext_str { \str_tail:n {#1} } } } \cs_generate_variant:Nn \phone_UK_vorwahl_schreiben:nn {Vx} % #1: Vorwahl, #2: Teilnehmerrufnummer \cs_new_protected:Npn \phone_UK_teilnehmerrufnummer_schreiben:Nn #1 #2 { % Überprüfen der Nummernlänge \str_if_empty:NTF #1 { % Festnetznummer ohne Vorwahl (kann zwischen 4 und 8 Ziffern haben) \phone_nummernlaenge_ueberpruefen:nnnn {#2} {4} {8} {landline} % Nummern, die mit 0 oder 1 beginnen, erfordern das Wählen der Vorwahl \str_case:xnT { \str_head:n {#2} } { {0} { } {1} { } } { \msg_warning:nn {phonenumbers} {UK/national dialling required} } } { \clist_if_in:NVTF \c_phone_UK_ortsvorwahlen_clist #1 { % Festnetznummer, muss in der Regel 11 Ziffern umfassen % Ausnahme: Bei den Vorwahlen 01XXX und 016977 sind auch 10 Ziffern möglich. \bool_lazy_or:nnTF { \str_if_eq_p:Vn #1 {016977} } { \int_compare_p:nNn { \str_count:N #1 } = {5} } { \phone_nummernlaenge_ueberpruefen:onnn {#1#2} {10} {11} {landline} } { \phone_nummernlaenge_ueberpruefen:onnn {#1#2} {11} {11} {landline} } } { % Mobilfunk-/Sondernummer \str_if_eq:xnTF { \str_range:Nnn #1 {1} {4} } {0800} { % 0800er-Nummern haben 10 oder 11 Ziffern; Ausnahme: 0800 1111 \str_if_eq:nnTF {#2} {1111} { \bool_set_true:N \l_phone_teilnehmerrufnummer_gueltig_bool } { \phone_nummernlaenge_ueberpruefen:onnn {#1#2} {10} {11} {freephone} } } { % alle anderen Sondernummern haben 11 Ziffern \phone_nummernlaenge_ueberpruefen:onnn {#1#2} {11} {11} {non-geographic} } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { % Für gültige Nummern mit Vorwahl Linktext schreiben: \str_put_right:Nn \l_phone_linktext_str {#2} } { % Für ungültige Nummern mit Vorwahl Linktext löschen: \str_clear:N \l_phone_linktext_str } } \bool_if:NTF \l_phone_teilnehmerrufnummer_gueltig_bool { \int_compare:nNnTF { \str_count:n {#2} } > {6} { % Nummern mit mehr als 6 Ziffern werden in Vierergruppen gegliedert \str_put_right:Nx \l_phone_ausgabetext_tl { \str_range:nnn {#2} {1} {-5} } \tl_put_right:Nn \l_phone_ausgabetext_tl {\,} \str_put_right:Nx \l_phone_ausgabetext_tl { \str_range:nnn {#2} {-4} {-1} } } { \str_put_right:Nn \l_phone_ausgabetext_tl {#2} } } { \str_put_right:Nn \l_phone_ausgabetext_tl {#2} } } \cs_generate_variant:Nn \phone_UK_teilnehmerrufnummer_schreiben:Nn {Nx,NV} \cs_new_protected:Npn \phone_UK_nummer_schreiben: { \int_set:Nn \l_phone_nummerlaenge_int { \str_count:N \l_phone_bereinigte_nummer_str } \str_if_eq:xnTF { \str_head:N \l_phone_bereinigte_nummer_str } {0} { \bool_set_false:N \l_phone_vorwahl_gefunden_bool \int_step_inline:nnnn {6} {-1} {3} { \bool_if:NF \l_phone_vorwahl_gefunden_bool { \int_compare:nT { \l_phone_nummerlaenge_int >= ##1 } { \str_set:Nx \l_phone_vorwahl_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {##1} } \clist_if_in:NVT \c_phone_UK_vorwahlen_clist \l_phone_vorwahl_str { \bool_set_true:N \l_phone_vorwahl_gefunden_bool \phone_UK_vorwahl_schreiben:Vx \l_phone_vorwahl_str { \int_compare_p:nNn {##1} < {\l_phone_nummerlaenge_int} } \int_compare:nNnTF {##1} = {\l_phone_nummerlaenge_int} { \msg_warning:nn {phonenumbers} {missing subscriber number} } { \phone_UK_teilnehmerrufnummer_schreiben:Nx \l_phone_vorwahl_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {##1 + 1} {-1} } } } } } } \bool_if:NF \l_phone_vorwahl_gefunden_bool { \msg_warning:nn {phonenumbers} {invalid area code} \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } { \phone_UK_teilnehmerrufnummer_schreiben:NV \c_empty_tl \l_phone_bereinigte_nummer_str } } %%%%%%%%%%%%%%%%%%%% NORDAMERIKA %%%%%%%%%%%%%%%%%%%% \file_input:n {phn-US_Vorwahlen} \file_input:n {phn-US_Ortsnamen} \clist_new:N \c_phone_US_vorwahlen_clist \clist_concat:NNN \c_phone_US_vorwahlen_clist \c_phone_US_ortsvorwahlen_clist \c_phone_US_sondervorwahlen_clist \msg_new:nnn {phonenumbers} {US/illegal home area code} { 10-digit~dialling~is~required~in~\tl_use:c {c_phone_US_ortsname_#1_tl}.~#1~cannot~be~set~as~home~area~code~\msg_line_context:. } \msg_new:nnn {phonenumbers} {US/invalid area code} { unknown~area~code~#1~in~North~American~phone~number~\msg_line_context: } \msg_new:nnn {phonenumbers} {US/invalid central office code} { invalid~central~office~code~#1~in~North~American~phone~number~\msg_line_context: } \bool_new:N \l_phone_US_ferngespraechspraefix_bool \keys_define:nn {phonenumbers} { trunk-prefix .choices:nn = {on,off} { \str_if_eq:VnTF \l_keys_choice_tl {on} { \bool_set_true:N \l_phone_US_ferngespraechspraefix_bool } { \bool_set_false:N \l_phone_US_ferngespraechspraefix_bool } }, trunk-prefix .initial:n = off, trunk-prefix .default:n = on } % #1: Vorwahl, #2: Folgt eine Rufnummer? \cs_new_protected:Npn \phone_US_vorwahl_schreiben:nN #1 #2 { \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:Vn \l_phone_heimatland_str {US} } { \bool_lazy_and:nnF { \str_if_eq_p:Vn \l_phone_heimatland_str {US} } { \str_if_eq_p:Vn \l_phone_heimatvorwahl_str {#1} } { \bool_if:NTF \l_phone_US_ferngespraechspraefix_bool { \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_if_eq:VnT \l_phone_vorwahldarstellung_str {place-and-number} { \tl_if_exist:cT {c_phone_US_ortsname_#1_tl} { \tl_use:c {c_phone_US_ortsname_#1_tl} \c_space_tl } } \bool_if:NTF #2 { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} {1 \c_space_tl (#1) \c_space_tl} {space} {1 \c_space_tl #1 \c_space_tl} } { 1 \c_phone_bindestrich_tl #1 \c_phone_bindestrich_tl } } { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} {1 \c_space_tl (#1)} {space} {1 \c_space_tl #1} } { 1 \c_phone_bindestrich_tl #1 } } } } { \str_if_eq:VnT \l_phone_vorwahldarstellung_str {place} { \clist_if_in:NnT \c_phone_US_sondervorwahlen_clist {#1} { \str_set:Nn \l_phone_vorwahldarstellung_str {number} } } \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_case:Vn \l_phone_vorwahldarstellung_str { {number} { \bool_if:NTF #2 { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} {(#1) \c_space_tl} {space} {#1 \c_space_tl} } { #1 \c_phone_bindestrich_tl } } { #1 } } {place} { \bool_if:NTF #2 { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} { ( \tl_if_exist:cTF {c_phone_US_ortsname_#1_tl} { \tl_use:c {c_phone_US_ortsname_#1_tl} } { #1 } ) \c_space_tl } } { \tl_if_exist:cTF {c_phone_US_ortsname_#1_tl} { \tl_use:c {c_phone_US_ortsname_#1_tl} \c_space_tl } { #1 \c_phone_bindestrich_tl } } } { \tl_if_exist:cTF {c_phone_US_ortsname_#1_tl} { \tl_use:c {c_phone_US_ortsname_#1_tl} } { #1 } } } {place-and-number} { \tl_if_exist:cT {c_phone_US_ortsname_#1_tl} { \tl_use:c {c_phone_US_ortsname_#1_tl} \c_space_tl } \bool_if:NTF #2 { \str_case:VnF \l_phone_vorwahltrennung_str { {brackets} {(#1) \c_space_tl} {space} {#1 \c_space_tl} } { #1 \c_phone_bindestrich_tl } } { \str_if_eq:VnTF \l_phone_vorwahltrennung_str {brackets} { (#1) } { #1 } } } } } } } } { \phone_auslandsvorwahl_schreiben:n {1} \tl_put_right:Nn \l_phone_ausgabetext_tl {\c_space_tl} \str_if_eq:VnTF \l_phone_auslandsvorwahltrennung_str {brackets} { \tl_put_right:Nn \l_phone_ausgabetext_tl {(#1)} } { \tl_put_right:Nn \l_phone_ausgabetext_tl {#1} } \bool_if:NT #2 { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } % Linktext schreiben, falls eine Rufnummer folgt \bool_if:NT #2 { \str_put_right:Nn \l_phone_linktext_str {+1 #1} } } \cs_generate_variant:Nn \phone_US_vorwahl_schreiben:nN {VN} % #1: Ortsvorwahl, #2: Vermittlungsstellennummer \cs_new_protected:Npn \phone_US_vermittlungsstellennummer_schreiben:nn #1 #2 { \str_case:xnTF { \str_head:n {#2} } { {0} { } {1} { } } { \msg_warning:nnn {phonenumbers} {US/invalid central office code} {#2} } { \bool_set_false:N \l_tmpa_bool % Regionalnummer? \tl_if_empty:nTF {#1} { \bool_set_true:N \l_tmpa_bool } { \clist_if_in:NnT \c_phone_US_ortsvorwahlen_clist {#1} { \bool_set_true:N \l_tmpa_bool } } \bool_if:NTF \l_tmpa_bool { \str_if_eq:xnT { \str_range:nnn {#2} {2} {3} } {11} { \msg_warning:nnn {phonenumbers} {US/invalid central office code} {#2} } } { \str_if_eq:nnT {#2} {911} { \msg_warning:nnn {phonenumbers} {US/invalid central office code} {#2} } } } \tl_put_right:Nn \l_phone_ausgabetext_tl {#2} \bool_lazy_or:nnTF { \str_if_eq_p:Vn \l_phone_auslandsvorwahltyp_str {off} } { \str_if_eq_p:Vn \l_phone_heimatland_str {US} } { \tl_put_right:NV \l_phone_ausgabetext_tl \c_phone_bindestrich_tl } { \tl_if_empty:nTF {#1} { \tl_put_right:NV \l_phone_ausgabetext_tl \c_phone_bindestrich_tl } { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl } } % Linktext schreiben, falls eine Vorwahl vorangeht \tl_if_empty:nF {#1} { \str_put_right:Nn \l_phone_linktext_str {#2} } } \cs_generate_variant:Nn \phone_US_vermittlungsstellennummer_schreiben:nn {Vx} \cs_new_protected:Npn \phone_US_nummer_schreiben: { \int_case:nnF { \str_count:N \l_phone_bereinigte_nummer_str } { {3} { \clist_if_in:NVTF \c_phone_US_vorwahlen_clist \l_phone_bereinigte_nummer_str { \msg_warning:nn {phonenumbers} {missing subscriber number} } { \msg_warning:nnV {phonenumbers} {US/invalid area code} \l_phone_bereinigte_nummer_str } \phone_US_vorwahl_schreiben:VN \l_phone_bereinigte_nummer_str \c_false_bool } {7} { \phone_US_vermittlungsstellennummer_schreiben:Vx \c_empty_tl { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {3} } \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {7} } } {10} { \str_set:Nx \l_tmpa_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {3} } \clist_if_in:NVF \c_phone_US_vorwahlen_clist \l_tmpa_str { \msg_warning:nnx {phonenumbers} {US/invalid area code} {\l_tmpa_str} } \phone_US_vorwahl_schreiben:VN \l_tmpa_str \c_true_bool \phone_US_vermittlungsstellennummer_schreiben:Vx \l_tmpa_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {4} {6} } \tl_put_right:Nx \l_phone_ausgabetext_tl { \str_range:Nnn \l_phone_bereinigte_nummer_str {7} {10} } \str_put_right:Nx \l_phone_linktext_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {7} {10} } } } { \int_compare:nNnTF { \str_count:N \l_phone_bereinigte_nummer_str } < {10} { \msg_warning:nnnn {phonenumbers} {number too short} {phone} {10} } { \msg_warning:nnnn {phonenumbers} {number too long} {phone} {10} } \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } %%%%%%%%%%%%%%%%%%%% SONSTIGE LÄNDER %%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn \phone_SONST_nummer_schreiben: { \int_set:Nn \l_phone_nummerlaenge_int { \str_count:N \l_phone_bereinigte_nummer_str } \bool_set_false:N \l_phone_vorwahl_gefunden_bool \int_step_inline:nnnn {3} {-1} {1} { \bool_if:NF \l_phone_vorwahl_gefunden_bool { \int_compare:nT { \l_phone_nummerlaenge_int >= ##1 } { \str_set:Nx \l_tmpa_str { \str_range:Nnn \l_phone_bereinigte_nummer_str {1} {##1} } \clist_if_in:NVT \c_phone_landeskennzahlen_clist \l_tmpa_str { \bool_set_true:N \l_phone_vorwahl_gefunden_bool \phone_auslandsvorwahl_schreiben:V \l_tmpa_str \int_compare:nNnTF {##1} = {\l_phone_nummerlaenge_int} { \msg_warning:nn {phonenumbers} {country code only} } { \tl_put_right:NV \l_phone_ausgabetext_tl \c_space_tl \phone_von_hinten_gruppiert_schreiben:x { \str_range:Nnn \l_phone_bereinigte_nummer_str {##1 + 1} {-1} } \str_put_right:Nn \l_phone_linktext_str {+} \str_put_right:NV \l_phone_linktext_str \l_phone_bereinigte_nummer_str } } } } } \bool_if:NF \l_phone_vorwahl_gefunden_bool { \msg_warning:nnn {phonenumbers} {invalid country code} \tl_put_right:NV \l_phone_ausgabetext_tl \c_phone_pluszeichen_tl \tl_put_right:NV \l_phone_ausgabetext_tl \l_phone_bereinigte_nummer_str } } \ProcessKeysPackageOptions {phonenumbers}