Ciao a tutti,
in una classe che sto scrivendo è da molto tempo che ho definito
i comandi (copiandoli non ricordo da dove):
`\providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
\providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
`Solo ora mi sono accorto che le mie definizioni introducono a numeratore uno spazio in più, molto brutto da vedere secondo me.
Il problema è chiaramente dovuto al fatto che manca l’esponente.
`\documentclass{minimal}
\providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
\providecommand*{\pder}[3][]{\frac{\partial^{#1}#2}{\partial #3^{#1}}}
\begin{document}
\[
\der{f}{t}\quad\frac{df}{dt}\quad\pder{f}{t}\quad\frac{\partial f}{\partial t}
\]
\end{document}`Ora l’idea è quella di controllare se l’argomento opzionale è vuoto o meno.
Leggendo la sezione 3.5 degli “Appunti di programmazione in LaTeX e TeX” di Enrico
mi sono un po’ perso e alla fine non ho capito nel mio caso cosa mi conviene usare.
Per ora ho fatto così:
`\makeatletter
\providecommand*{\der}[3][]{\frac{d\if#1\@empty ^{#1}\else\relax\fi#2}{d #3\if#1\@empty ^{#1}\else\relax\fi}}
\providecommand*{\pder}[3][]{\frac{\partial\if#1\@empty ^{#1}\else\relax\fi#2}{\partial #3\if#1\@empty ^{#1}\else\relax\fi}}
\makeatother`
e sembra tutto funzionare.Vorrei sapere se questo codice può creare dei pasticci, soprattutto considerando che magari una persona può mettere anche roba strana a esponente, non solo numeri.
Altroché se può creare pasticci. Suppongo che tu non abbia davvero provato, perché \der[2]{f}{x} e \der{f}{x} danno esattamente lo stesso risultato. 😯
Vediamo perché. Quando chiami \der[2]{f}{x}, hai #1=2, #2=f, #3=x, quindi la lista di token del numeratore è
`d\if2\@empty ^{2}\else\relax\fi f`
Il condizionale \if espande ciò che segue fino a trovare due token non espandibili che, in questo caso sono “2” e “^”; quindi il testo per la parte `vero’ è “{2}” quello per la parte `falso’ è “\relax”. Viene scelto `falso’ perché “2” e “^” sono token diversi.
Se invece chiami \der{f}{x}, la lista di token nel numeratore è
`d\if\@empty ^{}\else\relax\fi f`
che risulta falso perché il confronto è fatto tra “^” e “{“. Il condizionale \if è una brutta bestia. 🙂
Se sei certo che nell’argomento opzionale i tuoi utenti non mettano comandi espandibili che facciano cose strane, il modo più semplice è di riscrivere il condizionale come
`\if?#1?\else^{#1}\fi`
Se #1 è vuoto, il test risulta vero perché ? è uguale a ?. Se #1 non è vuoto, il primo token che lo forma non sarà “?” (nessuno mette ? a esponente, direi). Quindi il test risulta falso e tutto ciò che compare fino a \else viene ignorato. Al posto di ? si può mettere qualsiasi token non espandibile (anche \relax, se vuoi, oppure uno totalmente fuori posto come &).
Se invece temi che a esponente possano andare cose pericolose come \sqrt{2} o costruzioni bizzarre, il modo più veloce è
`\newcommand*{\der}[3][]{\def\@temp{#1}
\frac{d\ifx\@temp\@empty\else^{#1}\fi #2}{d#3 \ifx\@temp\@empty\else^{#1}\fi}}`
Non mi pare che quella costruzione risulti fra quelle esposte nell’Introduzione. O mi sbaglio? 😉
Ciao
Enrico