- Questo topic ha 10 risposte, 2 partecipanti ed è stato aggiornato l'ultima volta 18 anni, 3 mesi fa da
robitex.
-
CreatoreTopic
-
19 Maggio 2008 alle 22:09 #24286::
Vorrei poter compiere un ciclo \whiledo (pacchetto ifthen) sfornando righe in un ambiente tabular.
Nel codice seguente, il primo loop esegue egregiamente il suo lavoro, pertanto funziona. Ma se lo inseriamo in un ambiente tabular produce una serie di errori di chiusura del ciclo.
Tali errori sono dovuti probabilmente alla formazione di gruppi nel tabular.Mi sapreste indicare una via per produrre una tabella a partire da cicli come questi nell’esempio?
Grazie ed a presto.`\documentclass[a4paper,10pt]{article}
\usepackage{ifthen}\begin{document}
\newcounter{index}\setcounter{index}{1}
\newcounter{final}\setcounter{final}{26}\whiledo{\not\(\value{index}>\value{final}\)}{% OK
\theindex\par\stepcounter{index}}%\setcounter{index}{1}
\begin{tabular}{ll}% non OK
\whiledo{\not\(\value{index}>\value{final}\)}{%
Valore= & \theindex\\\stepcounter{index}%
}%
\end{tabular}\end{document}`
-
CreatoreTopic
-
AutoreRisposte
-
-
20 Maggio 2008 alle 8:25 #24287::
Vorrei poter compiere un ciclo \whiledo (pacchetto ifthen) sfornando righe in un ambiente tabular.
Nel codice seguente, il primo loop esegue egregiamente il suo lavoro, pertanto funziona. Ma se lo inseriamo in un ambiente tabular produce una serie di errori di chiusura del ciclo.
Tali errori sono dovuti probabilmente alla formazione di gruppi nel tabular.Mi sapreste indicare una via per produrre una tabella a partire da cicli come questi nell’esempio?
Grazie ed a presto.`\documentclass[a4paper,10pt]{article}
\usepackage{ifthen}\begin{document}
\newcounter{index}\setcounter{index}{1}
\newcounter{final}\setcounter{final}{26}\whiledo{\not\(\value{index}>\value{final}\)}{% OK
\theindex\par\stepcounter{index}}%\setcounter{index}{1}
\begin{tabular}{ll}% non OK
\whiledo{\not\(\value{index}>\value{final}\)}{%
Valore= & \theindex\\\stepcounter{index}%
}%
\end{tabular}\end{document}`
Avevamo già discusso una cosa simile con Andrea (DMW). Il problema è sempre quello che le celle di una tabella costituiscono un gruppo implicito. Lo si può risolvere con i registri token:
`\setcounter{index}{1}
\toks255={\begin{tabular}{ll}}
\whiledo{\not\(\value{index}>\value{final}\)}
{\toks255=\expandafter{\the\toks255 Valore= & }%
\toks255=\expandafter{\the\toks255\expandafter\space\number\value{index}\\}%
\stepcounter{index}}
\the\toks255
\end{tabular}`
C’è un po’ di lavoro da fare per il valore del contatore index (brutto nome, direi). Con \theindex non funzionerebbe.Il ciclo whiledo aggiunge via via token al registro; ma guardo bene di non cominciare il tabular troppo presto: lo faremo solo al momento di usare il registro (penultima riga).
Il trucco usato alla riga 5 è piuttosto sottile. Esercizio. 😀
Ciao
Enrico
-
20 Maggio 2008 alle 8:44 #24288
-
20 Maggio 2008 alle 9:11 #24289::
Grazie molte.
Speravo ci fosse una soluzione per portare avanti un lavoro per me importante.
Scusate ma un argomento come questo è difficile da rintracciare nel forum.Applicherò questa soluzione dopo essermi documentato un po’.
Trovi qualcosa sugli aurei “appunti” di un noto TeXnico 😉
In sostanza ciò che faccio è di caricare i token che servono in un registro token temporaneo. Un’istruzione come
`\toks255=\expandafter{\the\toks255 …}`
serve per aggiungere qualcosa al registro stesso. Inizialmente il contenuto è “\begin{tabular}{ll}”; alla prima iterazione aggiungo “Valore=&”, poi ho il problema di aggiungere il valore attuale del contatore index (il nome è brutto perché \theindex è una macro importante se devi compilare l’indice analitico, ma per ora teniamolo). Non si può aggiungere \theindex, perché l’espansione di questo è “\@arabic\c@index” e quindi si avrebbe sempre il valore finale del contatore. Ciò che si vuole è invece il valore durante quella iterazione e \number\value{index} fa ciò che si desidera; ma dobbiamo espanderlo al momento di inserirlo nel registro, altrimenti saremmo daccapo.Ecco qui come si può fare:
`\toks255=\expandafter{\the\toks255\expandafter\space\number\value{index}\\}`
Il “\\” finale serve per la tabella e non dà problemi. Il trucco sottile è prima. Andiamo con calma: c’è un \expandafter che espande il \the; \the trova la primitiva \toks che deve avere un argomento numerico. TeX determina questo argomento raccogliendo ed espandendo tutti i token finché trova qualcosa che non può essere interpretato come numero. Dopo 255 c’è \expandafter che viene espanso, con la conseguenza che viene espanso \number il quale espande \value{index} finché trova un numero, cioè esattamente il valore di index in quel momento. A questo punto \expandafter sparisce e il token successivo è \space che viene espanso a uno spazio: questo finisce il numero cercato dopo \toks e lo spazio che risulta viene ignorato perché segue una costante.Il trucco l’ho imparato da David Kastrup su comp.text.tex.
Ciao
Enrico
-
23 Maggio 2008 alle 11:56 #24290::
Ecco qui come si può fare:
`\toks255=\expandafter{\the\toks255\expandafter\space\number\value{index}\\}`Se provo ad eliminare \expandafter\space succede che viene ottenuto il numero corrispondente a \number\value{index} e attaccato al numero di registro, quindi un pasticcio.
Dunque è utile inserire uno \space precedentemente a quello che sarà il valore del contatore.
Tuttavia il seguente codice funziona:
` \newcounter{idx}\setcounter{idx}{1234}
\toks255=\expandafter{\the\toks255\space\number\value{idx}}
\the\toks255`
ovvero, la domanda: perchè è necessario inserire un secondo \expandafter interno?Grazie.
PS. un ulteriore ringraziamento per gli appunti di programmazione in LaTeX e TeX 💡
-
23 Maggio 2008 alle 15:47 #24291::
Ecco qui come si può fare:
`\toks255=\expandafter{\the\toks255\expandafter\space\number\value{index}\\}`Se provo ad eliminare \expandafter\space succede che viene ottenuto il numero corrispondente a \number\value{index} e attaccato al numero di registro, quindi un pasticcio.
Dunque è utile inserire uno \space precedentemente a quello che sarà il valore del contatore.
Tuttavia il seguente codice funziona:
` \newcounter{idx}\setcounter{idx}{1234}
\toks255=\expandafter{\the\toks255\space\number\value{idx}}
\the\toks255`
ovvero, la domanda: perchè è necessario inserire un secondo \expandafter interno?Certo, se non vuoi incrementare il valore del contatore idx. Infatti il registro \toks255 conterrà esattamente
`\number\value{idx}`
Aggiungendo \expandafter invece avresti
`1234`
C’è una bella differenza, non trovi?Ciao
Enrico
-
25 Maggio 2008 alle 16:49 #24292::
[quote]Ecco qui come si può fare:
`\toks255=\expandafter{\the\toks255\expandafter\space\number\value{index}\\}`Se provo ad eliminare \expandafter\space succede che viene ottenuto il numero corrispondente a \number\value{index} e attaccato al numero di registro, quindi un pasticcio.
Dunque è utile inserire uno \space precedentemente a quello che sarà il valore del contatore.
Tuttavia il seguente codice funziona:
` \newcounter{idx}\setcounter{idx}{1234}
\toks255=\expandafter{\the\toks255\space\number\value{idx}}
\the\toks255`
ovvero, la domanda: perchè è necessario inserire un secondo \expandafter interno?Certo, se non vuoi incrementare il valore del contatore idx. Infatti il registro \toks255 conterrà esattamente
`\number\value{idx}`
Aggiungendo \expandafter invece avresti
`1234`
C’è una bella differenza, non trovi?Ciao
Enrico[/quote]Già, ancora un abbaglio…
… speravo “implicitamente” che funzionasse perchè non riesco a far digerire i token giusti al registro in quest’altro caso:`\fpRegSet{myreg}{1000}
\fpRegGet{myreg}{\mynumber}
\toks255=\expandafter{Il numero adesso vale: \expandafter\space\number\mynumber\\}
\fpRegSet{myreg}{50000}
\fpRegGet{myreg}{\mynumber}
\toks255=\expandafter{\the\toks255 mentre adesso siamo a: \expandafter\space\number\mynumber}
\the\toks255
`
utilizzo il pacchetto fltpoint salvando un valore numerico nel registro denominato myreg, dal quale posso ricavarne il valore depositandolo in un comando (fantasiosamente nominato come \mynumber).
Se compilato il codice produce la stessa situazione precedente, ovverro nel registro viene salvato il token complesso di \mynumber e quindi scaricare i token con \the\toks255 fa apparire solo l’ultimo valore del registro quello attuale.
Come posso fare per inserire invece i token relativi al valore che \mynumber ha in quel momento?Dopo aver provato un po’ di tutto mi sono arreso 🙄 . Grazie.
Ps. perchè invece questo funziona?
`\newcommand\posizione{}\renewcommand\posizione{primo}
\toks255=\expandafter{\posizione}
\the\toks255\renewcommand\posizione{ultimo}
\toks255=\expandafter{\the\toks255 \posizione}
\the\toks255`
-
25 Maggio 2008 alle 18:03 #24293::
… speravo “implicitamente” che funzionasse perchè non riesco a far digerire i token giusti al registro in quest’altro caso:
`\fpRegSet{myreg}{1000}
\fpRegGet{myreg}{\mynumber}
\toks255=\expandafter{Il numero adesso vale: \expandafter\space\number\mynumber\\}
\fpRegSet{myreg}{50000}
\fpRegGet{myreg}{\mynumber}
\toks255=\expandafter{\the\toks255 mentre adesso siamo a: \expandafter\space\number\mynumber}
\the\toks255
`
utilizzo il pacchetto fltpoint salvando un valore numerico nel registro denominato myreg, dal quale posso ricavarne il valore depositandolo in un comando (fantasiosamente nominato come \mynumber).
Se compilato il codice produce la stessa situazione precedente, ovverro nel registro viene salvato il token complesso di \mynumber e quindi scaricare i token con \the\toks255 fa apparire solo l’ultimo valore del registro quello attuale.
Come posso fare per inserire invece i token relativi al valore che \mynumber ha in quel momento?Con il codice
`\toks255=\expandafter{Il numero adesso vale: \expandafter\space\number\mynumber\\}`
il primo \expandafter non fa assolutamente nulla, perché cerca di espandere il token “I” che non è espandibile. Perciò dopo quell’istruzione il registro \toks255 contiene esattamente la lista che hai dato tra le graffe. Qui ci vuole \edef:
`\fpRegSet{myreg}{1000}
\fpRegGet{myreg}{\mynumber}
\edef\temp{Il numero adesso vale: \mynumber\\}
\toks255=\expandafter{\temp}
\fpRegSet{myreg}{50000}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\the\toks255 mentre adesso siamo a: \mynumber}
\temp`
Si può fare anche con i registri token, ma occorre inserire in macro quei testi fissi e usare un bel numero di \expandafter.Ps. perchè invece questo funziona?
`\newcommand\posizione{}\renewcommand\posizione{primo}
\toks255=\expandafter{\posizione}
\the\toks255\renewcommand\posizione{ultimo}
\toks255=\expandafter{\the\toks255 \posizione}
\the\toks255`Perché quando scrivi \the\toks255 la lista viene liberata; dopo \toks255=\expandafter{\posizione} contiene “primo”; alla seconda assegnazione contiene “primo\posizione” e quindi quando il registro viene usato con \the la macro \posizione viene espansa e ciò che ottieni in stampa è “primoultimo”.
Ciao
Enrico
-
26 Maggio 2008 alle 8:48 #24294::
Caro Enrico,
le cose stanno così: mentre la parte del codice che pensavo fosse più difficile da realizzare è un successo, quella più “banale” mi da i maggiori problemi.
Infatti vorrei formattare con il pacchetto numprint il valore contenuto nel registro fltpoint.
Questo lo faccio normalmente se carico il materiale direttamente nel registro di token, mentre non è possibile se l’append viene svolto con edef.
Dunque se utilizzo edef non posso passargli anche un \numprint{\mynumber}, mentre se utilizzo l’append diretto nel registro funziona il numprint ma il valore del registro diventa l’ultimo:
`%funziona senza numprint
\fpRegSet{myreg}{1000,85}\fpRegGet{myreg}{\mynumber}
\edef\temp{Il numero adesso vale: \mynumber}
\toks255=\expandafter{\temp}
\the\toks255
\fpRegSet{myreg}{8541256321,45}\fpRegGet{myreg}{\mynumber}
\edef\temp{\the\toks255 Mentre ora vale: \mynumber}
\toks255=\expandafter{\temp}
\the\toks255
`
`%funziona con numprint ma i registri mantengono tutti l'ultimo valore
\fpRegSet{myreg}{1000,85}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\mynumber}
\toks255={Il numero adesso vale: \numprint{\temp}}
\the\toks255
\fpRegSet{myreg}{8541256321,45}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\mynumber}
\toks255=\expandafter{\the\toks255 Mentre ora vale: \numprint{\temp}}
\the\toks255
`Credo sia necessario passare al piano B, ovvero l’utilizzo esclusivo dei registri tokens senza utilizzare edef.
Imparare correttamente la programmazione (La)TeX richiede molto tempo per svolgere un corso completo ed approfondito magari semplicemente studiando buon materiale con metodo.
Passare immediatamente alla fase applicativa invece, è la via che effettivamente si percorre (almeno per gli autodidatti), perchè il tempo è poco e si vuole giungere ad un risultato corretto al proprio problema o si vuole sviluppare le proprie idee in un pacchetto.
In questo caso ho utilizzato esclusivamente comandi LaTeX ma per forza di cose sono passato ad utilizzare TeX per rivolvere un paio di problemi, ed in particolare questo: preparare una tabella evitando la barriera dei gruppi impliciti delle singole celle.Grazie.
PS. spero ancora di giungere al risultato finale che vi svelerò in una maniera o nell’altra, e comunque non senza indicare i contributi ricevuti.
-
26 Maggio 2008 alle 11:58 #24295::
Caro Enrico,
le cose stanno così: mentre la parte del codice che pensavo fosse più difficile da realizzare è un successo, quella più “banale” mi da i maggiori problemi.
Infatti vorrei formattare con il pacchetto numprint il valore contenuto nel registro fltpoint.
Questo lo faccio normalmente se carico il materiale direttamente nel registro di token, mentre non è possibile se l’append viene svolto con edef.
Dunque se utilizzo edef non posso passargli anche un \numprint{\mynumber}, mentre se utilizzo l’append diretto nel registro funziona il numprint ma il valore del registro diventa l’ultimo:
`%funziona senza numprint
\fpRegSet{myreg}{1000,85}\fpRegGet{myreg}{\mynumber}
\edef\temp{Il numero adesso vale: \mynumber}
\toks255=\expandafter{\temp}
\the\toks255
\fpRegSet{myreg}{8541256321,45}\fpRegGet{myreg}{\mynumber}
\edef\temp{\the\toks255 Mentre ora vale: \mynumber}
\toks255=\expandafter{\temp}
\the\toks255
`
`%funziona con numprint ma i registri mantengono tutti l'ultimo valore
\fpRegSet{myreg}{1000,85}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\mynumber}
\toks255={Il numero adesso vale: \numprint{\temp}}
\the\toks255
\fpRegSet{myreg}{8541256321,45}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\mynumber}
\toks255=\expandafter{\the\toks255 Mentre ora vale: \numprint{\temp}}
\the\toks255
`Credo sia necessario passare al piano B, ovvero l’utilizzo esclusivo dei registri tokens senza utilizzare edef.
Prova a guardare bene: quando esegui la prima assegnazione, il contenuto del registro è “Il numero adesso vale: \numprint{\temp}” che non ti serve a nulla. Non servirebbe a nulla nemmeno scrivere prima \edef\temp{\numprint{\mynumber}} perché di certo \numprint contiene svariate cose non espandibili.
`\def\MessaggioA{Il numero adesso vale: }
\def\MessaggioB{Mentre ora vale: }
\fpRegSet{myreg}{1000,85}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\noexpand\numprint{\mynumber}}
\toks@=\expandafter{\expandafter\MessaggioA\temp\\}
\the\toks@
\fpRegSet{myreg}{8541256321,45}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\noexpand\numprint{\mynumber}}
\toks@=\expandafter\expandafter\expandafter{%
\expandafter\the\expandafter\toks@\expandafter\MessaggioB\temp}
\the\toks@`
Naturalmente la cosa diventa improponibile se ci sono più messaggi di cui tener conto, per via della moltiplicazione degli \expandafter; si dovrebbe andare con l’uso di macro, ma senza sapere dove veramente vuoi arrivare è difficile dire con più precisione. Nota l’uso di un nome simbolico per \toks255 (che ti impone di usare \makeatletter); qui è meglio che con \toks255. In effetti l’uso di \edef può essere migliore:
`\def\MessaggioA{Il numero adesso vale: }
\def\MessaggioB{Mentre ora vale: }
\fpRegSet{myreg}{1000,85}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\noexpand\MessaggioA\noexpand\numprint{\mynumber}}
\toks@=\expandafter{\temp\\}
\the\toks@
\fpRegSet{myreg}{8541256321,45}
\fpRegGet{myreg}{\mynumber}
\edef\temp{\noexpand\MessaggioB\noexpand\numprint{\mynumber}}
\toks@=\expandafter\expandafter\expandafter{%
\expandafter\the\expandafter\toks@\temp}
\the\toks@`
Ciao
Enrico
-
27 Maggio 2008 alle 6:38 #24296::
Ha funzionato, ecco la ricetta “esoterica”:
definizione con edef (che espande tutto quel che trova e paradossalmente incontra istruzioni \noexpand 😆 ), con un noexpand per ogni token complesso.tre expandafter 😆 😆 😆 più alcuni intercalati all’interno della definizione di toks@.
… e alla fine ho raggiunto il risultato sperato.Grazie,
Roberto.
-
-
AutoreRisposte
- Devi essere connesso per rispondere a questo topic.