[quote]Esercizio: perché, con la mia definizione, \makeup{abc\ddt xyz} non dà errore a \ddt ma a \@nil, mentre con la tua lo dà a \ddt?
Ciao
EnricoPerché nella mia definizione \@nil è un token di delimitazione che non verrà mai espanso e quindi l’errore verrà provocato dall’espansione di \ddt.
Nel tuo codice invece, tutto dipende dal condizionale \ifx:
se \ifx si trova un carattere ed un token command sequence da confrontare darà come risultato falso senza espandere \@nil.
Se invece deve operare su due cs come quando incontra \ifx\ddt\@nil allora deve indagarne il significato cominciando ad espandere il secondo che quindi solleverà l’errore.
Giusto?
Sbagliato. 🙂 La risposta riguardo la tua definizione è corretta. Con l’altro metodo a un certo punto TeX incontra \ifx\ddt\@nil e confronta i due token senza espanderli; ma li considera uguali perché entrambi sono indefiniti e quindi la ricorsione termina. Quando poi TeX trova il \@nil che è rimasto emette il messaggio di errore di “Undefined control sequence”.
Se hai timore che nell’argomento di \makeup possano intrufolarsi token non definiti, è meglio usare come sentinella un token definito e inconsueto, per esempio \uchyph.
Ciao
Enrico[/quote]
Spiegazione completa a questo punto… grazie.
Quello che manca è raccontare come è andata a finire la questione.
Intanto ho adottato la soluzione di parsing a singolo carattere anche solo per aumentare l’efficienza (motivo del perché vorrei abbandonare la soluzione attuale basata su pstricks).
Ecco come funziona il codice:
ho creato 43 macro diverse ognuna per i 43 simboli che possono essere rappresentati da code39. Queste macro sono state nominate con \barchar@
Per esempio il carattere A è reso dalla macro \barchar@A, quindi quando la macro di parsing passa un singolo carattere costruisco la command sequence relativa per le cifre da 0 a 9 e per le 26 lettere.
Se tale token non è vuoto (come nella maggioranza dei casi), allora produco il disegno corrispondente delle barre, altrimenti verifico che non sia uno dei simboli speciali, e se non sono in uno di questi casi emetto un messaggio d’errore. Ecco il codice:
`
% user interface macro
\newcommand{\barcode}[1]{%
\ifx#1\empty
% package warning
\else
\barcode@Start
\expandafter\uppercase\expandafter{\expandafter\barcode@parsechar#1\@nil}
\barcode@Stop
\fi
}
%
\def\barcode@parsechar#1{%
\ifx#1\@nil\else
\def\tempsymb{*}
\ifx#1\tempsymb
% package error
\fi
% command sequence of the char
\expandafter\let\expandafter\tempchar\csname barchar@#1\endcsname
\ifx\tempchar\relax
\ifx#1\space
\barchar@space
\barstep@interchar
\else
\def\tempsymb{-}
\ifx#1\tempsymb
\barchar@bar
\barstep@interchar
\else
\def\tempsymb{.}
\ifx#1\tempsymb
\barchar@dot
\barstep@interchar
\else
\def\tempsymb{/}
\ifx#1\tempsymb
\barchar@slash
\barstep@interchar
\else
\def\tempsymb{+}
\ifx#1\tempsymb
\barchar@plus
\barstep@interchar
\else
\def\tempsymb{\%}
\ifx#\tempsymb
\barchar@percent
\barstep@interchar
\else
\def\tempsymb{\$}
\ifx#1\tempsymb
\barchar@dollar
\barstep@interchar
\else
% package error
\fi
\fi
\fi
\fi
\fi
\fi
\fi
\else
\tempchar
\barstep@interchar
\fi
\expandafter\barcode@parsechar
\fi
}`
La serie annidata di test condizionali è un po’ poco leggibile ma riguarda solo i simboli mentre con l’idea di \tempchar mi evito un problema maggiore mantenendo l’efficienza di esecuzione.
Se passo il codice da renderizzare a \barcode con una macro semplice funziona.
Grazie di nuovo.
R.