Nuova versione per stare in pari con le modifiche del pacchetto apportate da OldClaudio. 🙂
L’aggiunta è la variante asterisco a \codicefiscaleitaliano che stampa il codice, se corretto. Qualche altra semplificazione, usando la versione espandibile [tt]\prop_get:cn[/tt] (un po’ più lenta di [tt]\prop_get:cnN[/tt], ma con liste non troppo affollate la differenza è poco significativa. Si noti che i messaggi di errore o avviso possono avere fino a quattro argomenti: uso questa possibilità per due versioni distinte del messaggio “errato” per lunghezza o perché il controllo è fallito. Nel primo caso il controllo nemmeno è iniziato, nel secondo viene emesso un comando [tt]\use_none:nnn[/tt] che ingoia [tt]\IfBooleanT{#1}{\CFisc}[/tt].
Un comando con variante asterisco si definisce facilmente con [tt]\NewDocumentCommand[/tt]: basta specificare [tt]s[/tt] nella lista dei tipi di argomento; la presenza dell’asterisco rende vero [tt]\IfBooleanTF{#1}[/tt] che segue il ramo “vero”; si può anche, come qui, usare [tt]\IfBooleanT{#1}[/tt], specificando solo il ramo “vero”; nulla sarà eseguito in mancanza di *.
`\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g_cf_odd_prop
\prop_new:N \g_cf_even_prop
\prop_put:Nnn \g_cf_odd_prop { 0 } { 1 }
\prop_put:Nnn \g_cf_odd_prop { 1 } { 0 }
\prop_put:Nnn \g_cf_odd_prop { 2 } { 5 }
\prop_put:Nnn \g_cf_odd_prop { 3 } { 7 }
\prop_put:Nnn \g_cf_odd_prop { 4 } { 9 }
\prop_put:Nnn \g_cf_odd_prop { 5 } { 13 }
\prop_put:Nnn \g_cf_odd_prop { 6 } { 15 }
\prop_put:Nnn \g_cf_odd_prop { 7 } { 17 }
\prop_put:Nnn \g_cf_odd_prop { 8 } { 19 }
\prop_put:Nnn \g_cf_odd_prop { 9 } { 21 }
\prop_put:Nnn \g_cf_odd_prop { A } { 1 }
\prop_put:Nnn \g_cf_odd_prop { B } { 0 }
\prop_put:Nnn \g_cf_odd_prop { C } { 5 }
\prop_put:Nnn \g_cf_odd_prop { D } { 7 }
\prop_put:Nnn \g_cf_odd_prop { E } { 9 }
\prop_put:Nnn \g_cf_odd_prop { F } { 13 }
\prop_put:Nnn \g_cf_odd_prop { G } { 15 }
\prop_put:Nnn \g_cf_odd_prop { H } { 17 }
\prop_put:Nnn \g_cf_odd_prop { I } { 19 }
\prop_put:Nnn \g_cf_odd_prop { J } { 21 }
\prop_put:Nnn \g_cf_odd_prop { K } { 2 }
\prop_put:Nnn \g_cf_odd_prop { L } { 4 }
\prop_put:Nnn \g_cf_odd_prop { M } { 18 }
\prop_put:Nnn \g_cf_odd_prop { N } { 20 }
\prop_put:Nnn \g_cf_odd_prop { O } { 11 }
\prop_put:Nnn \g_cf_odd_prop { P } { 3 }
\prop_put:Nnn \g_cf_odd_prop { Q } { 6 }
\prop_put:Nnn \g_cf_odd_prop { R } { 8 }
\prop_put:Nnn \g_cf_odd_prop { S } { 12 }
\prop_put:Nnn \g_cf_odd_prop { T } { 14 }
\prop_put:Nnn \g_cf_odd_prop { U } { 16 }
\prop_put:Nnn \g_cf_odd_prop { V } { 10 }
\prop_put:Nnn \g_cf_odd_prop { W } { 22 }
\prop_put:Nnn \g_cf_odd_prop { X } { 25 }
\prop_put:Nnn \g_cf_odd_prop { Y } { 24 }
\prop_put:Nnn \g_cf_odd_prop { Z } { 23 }
\prop_put:Nnn \g_cf_even_prop { 0 } { 0 }
\prop_put:Nnn \g_cf_even_prop { 1 } { 1 }
\prop_put:Nnn \g_cf_even_prop { 2 } { 2 }
\prop_put:Nnn \g_cf_even_prop { 3 } { 3 }
\prop_put:Nnn \g_cf_even_prop { 4 } { 4 }
\prop_put:Nnn \g_cf_even_prop { 5 } { 5 }
\prop_put:Nnn \g_cf_even_prop { 6 } { 6 }
\prop_put:Nnn \g_cf_even_prop { 7 } { 7 }
\prop_put:Nnn \g_cf_even_prop { 8 } { 8 }
\prop_put:Nnn \g_cf_even_prop { 9 } { 9 }
\prop_put:Nnn \g_cf_even_prop { A } { 0 }
\prop_put:Nnn \g_cf_even_prop { B } { 1 }
\prop_put:Nnn \g_cf_even_prop { C } { 2 }
\prop_put:Nnn \g_cf_even_prop { D } { 3 }
\prop_put:Nnn \g_cf_even_prop { E } { 4 }
\prop_put:Nnn \g_cf_even_prop { F } { 5 }
\prop_put:Nnn \g_cf_even_prop { G } { 6 }
\prop_put:Nnn \g_cf_even_prop { H } { 7 }
\prop_put:Nnn \g_cf_even_prop { I } { 8 }
\prop_put:Nnn \g_cf_even_prop { J } { 9 }
\prop_put:Nnn \g_cf_even_prop { K } { 10 }
\prop_put:Nnn \g_cf_even_prop { L } { 11 }
\prop_put:Nnn \g_cf_even_prop { M } { 12 }
\prop_put:Nnn \g_cf_even_prop { N } { 13 }
\prop_put:Nnn \g_cf_even_prop { O } { 14 }
\prop_put:Nnn \g_cf_even_prop { P } { 15 }
\prop_put:Nnn \g_cf_even_prop { Q } { 16 }
\prop_put:Nnn \g_cf_even_prop { R } { 17 }
\prop_put:Nnn \g_cf_even_prop { S } { 18 }
\prop_put:Nnn \g_cf_even_prop { T } { 19 }
\prop_put:Nnn \g_cf_even_prop { U } { 20 }
\prop_put:Nnn \g_cf_even_prop { V } { 21 }
\prop_put:Nnn \g_cf_even_prop { W } { 22 }
\prop_put:Nnn \g_cf_even_prop { X } { 23 }
\prop_put:Nnn \g_cf_even_prop { Y } { 24 }
\prop_put:Nnn \g_cf_even_prop { Z } { 25 }
\seq_new:N \l_cf_codice_seq
\tl_new:N \l_cf_checksum_tl
\int_new:N \l_cf_position_int
\int_new:N \l_cf_checksum_int
\msg_new:nnn { codicefiscale } { corretto }
{
Codice~fiscale~#1:~corretto
}
\msg_new:nnnn { codicefiscale } { errato }
{
Codice~fiscale~#1:~#2!
}
{
Il~codice~#1~deve~essere~controllato\\
Premere~
}
\NewDocumentCommand{\codicefiscaleitaliano}{sm}
{
\seq_set_split:Nnn \l_cf_codice_seq { } { #2 }
\cs_set:Npx \CFisc { \seq_use:N \l_cf_codice_seq }
\int_compare:nTF { \seq_length:N \l_cf_codice_seq == 16 }
{ \cf_compute: \IfBooleanT { #1 }{ \CFisc } }
{ \msg_error:nnxx { codicefiscale } { errato } { \CFisc } { non~ha~16~caratteri } }
}
\cs_new_protected:Npn \cf_compute:
{
\seq_pop_right:NN \l_cf_codice_seq \l_cf_checksum_tl
\int_zero:N \l_cf_position_int
\int_zero:N \l_cf_checksum_int
\seq_map_inline:Nn \l_cf_codice_seq
{
\int_incr:N \l_cf_position_int
\cf_add:n { ##1 }
}
\int_set:Nn \l_cf_checksum_int { \int_mod:nn { \l_cf_checksum_int } { 26 } }
\int_compare:nTF { \l_cf_checksum_int == \prop_get:NV \g_cf_even_prop \l_cf_checksum_tl }
{
\msg_warning:nnx { codicefiscale } { corretto } { \CFisc }
}
{
\msg_error:nnxx { codicefiscale } { errato } { \CFisc } { errato }
\use_none:nnn
}
}
\cs_generate_variant:Nn \prop_get:Nn {NV}
\cs_new_protected:Npn \cf_add:n #1
{
\int_add:Nn \l_cf_checksum_int
{
\prop_get:cn { g_cf_ \int_if_odd:nTF { \l_cf_position_int }{ odd }{ even } _prop } { #1 }
}
}
\ExplSyntaxOff
\begin{document}
\codicefiscaleitaliano{NGL MRA 08M64 L500 N}
\codicefiscaleitaliano*{NGLMRA08M64L500N}
\codicefiscaleitaliano*{NGL MRA 08M64 L500 U}
\codicefiscaleitaliano*{NGL MRA 08M64 L500}
\end{document}`
Ciao
Enrico