Re: Macro per continued fractions

#65016
Up
0
Down
::


Vediamo di dare qualche spiegazione.

`\toksdef\cf@toksa=0
\toksdef\cf@toksb=2`

Assegno nomi simbolici a due registri token, solo per facilitare l’uso di \expandafter più avanti

`\newrobustcmd{\contfrac}[1]{\@contfracstart#1\@nil}`
Dichiaro \contfrac come robusto, che risolve il problema delle chiamate annidate. Il suo compito è di avviare il riconoscimento della parte intera.

`\def\@contfracstart#1;#2\@nil{%
\if\relax\detokenize{#1}\relax
\@contfrac{\noexpand\@gobble,#2}%
\else
\@contfrac{#1,#2}%
\fi}`

L’argomento è del tipo {1;2,3,4} oppure {;2,3,4} e \@confracstart riconosce se non c’è nulla prima del punto e virgola; nei due casi chiamerà \@contfrac{1,2,3,4} e \@contfrac{\noexpand\@gobble,2,3,4}

`\def\@contfrac#1{\cf@toksa={}\cf@toksb={}%
\@for\next:=#1\do
{\cf@toksa=\expandafter{\the\expandafter\cf@toksa\expandafter\cf@start\expandafter{\next}}%
\cf@toksb=\expandafter{\the\cf@toksb\cf@end}}
\edef\cf@final{\the\cf@toksa\the\cf@toksb}%
\edef\cf@final{\cf@final}\expandafter\@gobblethree\cf@final}`

Inizializziamo i due registri token. Poi avviamo un ciclo sulla lista data come argomento; nel caso di \contfrac{1;2,3,4} \next assumerà i valori 1 2 3 4 nei quattro cicli eseguiti. La prima istruzione del ciclo è

`\cf@toksa=\expandafter{\the\expandafter\cf@toksa\expandafter\cf@start\expandafter{\next}}`
Con \expandafter faccio in modo che sia espanso \next prima che l’assegnazione abbia luogo; nel primo ciclo \cf@toksa conterrà “\cf@start{1}”, nel secondo “\cf@start{1}\cf@start{2}” e così via accumulando. Allo stesso tempo al registro \cf@toksb viene aggiunto un token \cf@end.

Con \edef\cf@final{\the\cf@toksa\the\cf@toksb} otterremo, nei due casi, il seguente valore per \cf@final:
`\cf@start{1}\cf@start{2}\cf@start{3}\cf@start{4}\cf@end\cf@end\cf@end\cf@end
\cf@start{\noexpand\@gobble}\cf@start{2}\cf@start{3}\cf@start{4}\cf@end\cf@end\cf@end\cf@end`

Rimandiamo a dopo i due ultimi passi e vediamo come sono definite \cf@start e \cf@end.

`\def\cf@start#1{+\noexpand\cfrac{1}\iftrue{\else}\fi\unexpanded{#1}}`

\cf@start ha un argomento e si espande a qualcosa che contiene condizionali; nel caso di \cf@start{1} avremo

`+\noexpand\cfrac{1}\iftrue{\else}\fi\unexpanded{1}`

che, quando sarà passato per una \edef diventerà

`+\cfrac{1}{1`

(\unexpanded serve perché il passaggio attraverso \edef non espanda #1, non ci serve e sarebbe sbagliato se #1 fosse qualcosa di più complicato di un numero)

`\def\cf@end{\iffalse{\else}\fi}`
L’espansione di \cf@end fornisce la graffa di chiusura, quando si passa nella \edef.

Torniamo alle istruzioni che avevamo lasciato da parte:

`\edef\cf@final{\cf@final}`

Ridefinisco \cf@final come la sua espansione (per risparmiare su un nome); nel caso di \contfrac{1;2,3,4} avremo, come espansione finale di \cf@final

`+\cfrac{1}{1+\cfrac{1}{2+\cfrac{1}{3+\cfrac{1}{4}}}}`

Rimane l’ultimo passaggio:

`\expandafter\@gobblethree\cf@final`

\@gobblethree (che mangia i tre argomenti che seguono) si trova davanti l’espansione di \cf@final e così rimane solo

`{1+\cfrac{1}{2+\cfrac{1}{3+\cfrac{1}{4}}}}`

Nel caso di \contfrac{;2,3,4} alla fine si avrebbe

`{\@gobble+\cfrac{1}{2+\cfrac{1}{3+\cfrac{1}{4}}}}`

che fa sparire il +

Ciao
Enrico

Go to top