- Questo topic ha 14 risposte, 5 partecipanti ed è stato aggiornato l'ultima volta 14 anni, 11 mesi fa da
antonio.macrì.
-
CreatoreTopic
-
24 Settembre 2011 alle 8:59 #64107::
È possibile definire (oppure esiste già?) un comando che sia equivalente a `\clearpage’ se è impostata l’opzione di classe `oneside’ e a `\cleardoublepage’ se si usa `twoside’ (magari anche insieme a `openright’)? Girando su internet ho scoperto che è possibile definire un if del tipo `\ifoneside’ (vedi qui) che dovrebbe poter fare al caso mio, però mi piacerebbe avere il consiglio di qualcuno più competente di me in materia 🙂
-
CreatoreTopic
-
AutoreRisposte
-
-
24 Settembre 2011 alle 9:11 #64108::
Elrond” post=63162È possibile definire (oppure esiste già?) un comando che sia equivalente a `\clearpage’ se è impostata l’opzione di classe `oneside’ e a `\cleardoublepage’ se si usa `twoside’ (magari anche insieme a `openright’)? Girando su internet ho scoperto che è possibile definire un if del tipo `\ifoneside’ (vedi qui) che dovrebbe poter fare al caso mio, però mi piacerebbe avere il consiglio di qualcuno più competente di me in materia 🙂
Sicuramente non sono più competente di te in materia, ma il pacchetto emptypage, se ho capito quello che vuoi, non fa quello che chiedi?
Ciao
Orlando
-
24 Settembre 2011 alle 9:45 #64109::
Nel nucleo di LaTeX è già definita lo switch \if@twoside; nello stesso tempo \cleadouble page gì fa il test per verificare se si sta componendo one oppure two side; quindi quello che vorresti fare è già fatto; ti riporto la definizione di \cleardoublepage:`
\def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
\hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi}
`Anzi la definizione originale controlla anche se bisogna aggiungere una colonna vuota se si sta componendo a due colonne.
-
24 Settembre 2011 alle 10:08 #64110::
ansys” post=63163
È possibile definire (oppure esiste già?) un comando che sia equivalente a `\clearpage’ se è impostata l’opzione di classe `oneside’ e a `\cleardoublepage’ se si usa `twoside’ (magari anche insieme a `openright’)? Girando su internet ho scoperto che è possibile definire un if del tipo `\ifoneside’ (vedi qui) che dovrebbe poter fare al caso mio, però mi piacerebbe avere il consiglio di qualcuno più competente di me in materia 🙂
Sicuramente non sono più competente di te in materia, ma il pacchetto emptypage, se ho capito quello che vuoi, non fa quello che chiedi?
Ciao
OrlandoForse fa quello che vorrei, ma non voglio usare il pacchetto emptypage perché non mi dispiace avere il numero di pagina e la testatina nelle pagine vuote. Comunque grazie per la segnalazione 🙂
OldClaudio” post=63167Nel nucleo di LaTeX è già definita lo switch \if@twoside; nello stesso tempo \cleadouble page gì fa il test per verificare se si sta componendo one oppure two side; quindi quello che vorresti fare è già fatto; ti riporto la definizione di \cleardoublepage:
`
\def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
\hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi}
`Anzi la definizione originale controlla anche se bisogna aggiungere una colonna vuota se si sta componendo a due colonne.
In effetti `\cleardoublepage’ in un documento con l’opzione di classe `oneside’ si comporta come `\clearpage’, l’unico inconveniente che ho trovato è che se si usa `twoside’+`openany’ viene comunque aggiunta una pagina pari bianca. Personalmente non è un problema perché non penso che userò `twoside’+`openany’, sono solo curioso di vedere un comando che faccia tutto questo. Ripeto, per quello che mi serve `\cleardoublepage’ dovrebbe andare sempre bene. Grazie!
-
24 Settembre 2011 alle 10:33 #64111::
Aggiungi alla definizione originale di \cleardoublepage un ulteriore test basato sullo switch \if@openright; oppure creati una tua versione di \cleardoublepage che ammetta un argomento facoltativo, vuoto per defaualt, ma che potrebbe contenere una opzione o una lista di opzioni della forma key=value, cosicché faccia tutto quello che vuoi, e quando ti emette una pagina vuota per andare sul dispari, come fa ora, to possa anche scegliere come deve apparire questa pagina, empty, plain, headings, con lo stile di default, eccetera.
-
24 Settembre 2011 alle 16:19 #64112::
Elrond” post=63162È possibile definire (oppure esiste già?) un comando che sia equivalente a `\clearpage’ se è impostata l’opzione di classe `oneside’ e a `\cleardoublepage’ se si usa `twoside’ (magari anche insieme a `openright’)? Girando su internet ho scoperto che è possibile definire un if del tipo `\ifoneside’ (vedi qui) che dovrebbe poter fare al caso mio, però mi piacerebbe avere il consiglio di qualcuno più competente di me in materia 🙂
Tu vuoi un comando che faccia come \cleardoublepage, eccetto quando è impostata l’opzione “openany”. Bene, quando è impostata questa opzione, il condizionale \if@openright è falso.
`\makeatletter
\newcommand{\cleartochapterpage}{%
\if@openright
\cleardoublepage
\else
\clearpage
\fi}
\makeatother`
Se vuoi ridefinire \cleardoublepage in modo da non dover usare un nuovo comando,
`\makeatletter
\expandafter\def\expandafter\cleardoublepage\expandafter{\expandafter
\if@openright
\cleardoublepage
\else
\clearpage
\fi}
\makeatother`
Esercizio: perché funziona e non va in circolo vizioso?Ciao
Enrico
-
24 Settembre 2011 alle 20:11 #64113::
egreg9″ post=63183`\makeatletter
\expandafter\def\expandafter\cleardoublepage\expandafter{\expandafter
\if@openright
\cleardoublepage
\else
\clearpage
\fi}
\makeatother`
Esercizio: perché funziona e non va in circolo vizioso?Ciao
EnricoMi esercito io: il motivo essenziale è che viene calcolato il significato del comando prima di assegnarlo al token \cleardoublepage. In altri termini, viene espanso il \cleardoublepage presente nel corpo della definizione prima di ridefinirlo, in modo che il suo significato sia quello vecchio, non quello che gli si sta per assegnare.
Ne approfitto per chiedere una cosa sull’espansione di token e in particolare su \expandafter. Quest’ultimo funziona così: prima espande il secondo (che lo segue) token e poi fa riprendere l’espansione dal token che lo segue immediatamente. Ho qualche dubbio su come interpretare quest’ultima affermazione, che mi farebbe venire in mente l’idea che si crei una sorta di stack di espansione. Mi spiego meglio: vogliamo espandere tutta la ridefinizione di \cleardoublepage. Innanzitutto, devo espandere il primo \expandafter (la rappresentazione l’ho improvvisata):
`
\expandafter\def\expandafter\cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
^`
che comporta l’espansione del secondo \expandafter dopo il quale dovrò riprendere a espandere da \def:
`
\def\expandafter\cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
^
^`
L’espansione del secondo \expandafter determina l’espansione del terzo \expandafter dopo il quale dovrò espandere il primo \cleardoublepage:
`
\def\cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
^
^
^`
Ancora la stessa storia:
`
\def\cleardoublepage{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
^
^
^
^`
da cui:
`
\def\cleardoublepage{\if@openright\else\clearpage\fi}
^
^
^
^`A questo punto ho espanso tutti gli \expandafter e \cleardoublepage. L’espansione riprende da \if@openright e, a seguire, da {, \cleardoublepage e infine \def.
Evidentemente il ragionamento non può essere giusto: non posso mica riespandere \cleardoublepage! L’espansione invece viene ripresa direttamente da \def, no? E non si crea nessuno stack, vero?
Ciao,
Antonio
-
24 Settembre 2011 alle 21:00 #64114::
antonio.macrì” post=63196
`\makeatletter
\expandafter\def\expandafter\cleardoublepage\expandafter{\expandafter
\if@openright
\cleardoublepage
\else
\clearpage
\fi}
\makeatother`
Esercizio: perché funziona e non va in circolo vizioso?Ciao
EnricoMi esercito io: il motivo essenziale è che viene calcolato il significato del comando prima di assegnarlo al token \cleardoublepage. In altri termini, viene espanso il \cleardoublepage presente nel corpo della definizione prima di ridefinirlo, in modo che il suo significato sia quello vecchio, non quello che gli si vuole assegnare (che contiene lo stesso \cleardoublepage).
Giusto.
antonio.macrì”Ne approfitto per chiedere una cosa sull’espansione di token e in particolare su \expandafter. Quest’ultimo funziona così: prima espande il secondo (che lo segue) token e poi fa riprendere l’espansione dal token che lo segue immediatamente. Questo mi fa pensare che si crei una sorta di stack di espansione. Mi spiego meglio: vogliamo espandere tutta la ridefinizione di \cleardoublepage. Innanzitutto, devo espandere il primo \expandafter (la rappresentazione l’ho improvvisata):
[…
A questo punto ho espanso tutti gli \expandafter e \cleardoublepage. L’espansione riprende da \if@openright e, a seguire, da {, \cleardoublepage e infine \def.
Giusto il ragionamento?
Evidentemente no: non può mica riespandere \cleardoublepage. Ma allora non mi è ben chiaro come funziona.
Tutto quasi giusto, fino all’ultimo “code”. Vediamo il quasi. TeX mantiene una lista di token che elabora uno alla volta, prendendo il cibo necessario da un “input buffer” i cui rifornimenti vengono dal documento in elaborazione con il processo di “tokenization” (quello che forma comandi o passa caratteri). Se il primo token che ha nella lista è espandibile, esegue l’espansione e le procedure connesse; nel caso di una macro l’espansione provoca la ricerca degli argomenti, quindi anche il rifornimento dal buffer, e la sostituzione del token e dei suoi argomenti con la lista che viene presa dalla memoria, con la sostituzione di #1, …, #9 con gli argomenti stessi. Nel caso di \expandafter l’espansione richiede la lettura di due token e poi provoca l’espansione del secondo come detto; il primo token dopo \expandafter rimane lì nella lista (non è proprio uno stack, come vedi). Quando un token viene espanso, sparisce dalla “main token list” insieme ai suoi argomenti, ma rimane il prodotto dell’espansione da cui si ricomincia.
Ecco allora il punto fondamentale: nella lista che hai accuratamente scritto, il primo token che rimane è \def che non è espandibile! In questo caso TeX esegue la procedura connessa che, in questo caso, consiste nel riconoscere il token da definire, i “parameter tokens” (qui non ce ne sono) e il “replacement text”, cioè ciò che va dalla graffa aperta a quella chiusa corrispondente; il tutto viene passato alla memoria senza espansione e cancellato dalla “main token list”.
Un altro aspetto non secondario: l’espansione di una macro usa la definizione presente in memoria al momento. In questo caso \def ancora non è stato eseguito e quindi la definizione usata per l’espansione di \cleardoublepage a opera della catena di \expandafter è quella “precedente” (l’avevi osservato, ma è meglio dirlo più esplicitamente).
Ciao
Enrico
-
25 Settembre 2011 alle 7:08 #64115::
Grazie della spiegazione.
Sei stato chiarissimo ma voglio essere ancora più esplicito.Dimmi se il discorso fila. Indico con “>” il punto da cui bisogna espandere e separo con “|” ciò che è stato già tokenizzato dai dati grezzi presenti nell’input buffer.
Dovrebbe aversi:
`
> | \expandafter\def\expandafter\cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
> \expandafter | \def\expandafter\cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
> \expandafter\def\expandafter | \cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
\def> \expandafter | \cleardoublepage\expandafter{\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
\def> \expandafter\cleardoublepage\expandafter | {\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
\def\cleardoublepage> \expandafter | {\expandafter\if@openright\cleardoublepage\else\clearpage\fi}
\def\cleardoublepage> \expandafter{\expandafter | \if@openright\cleardoublepage\else\clearpage\fi}
\def\cleardoublepage{> \expandafter | \if@openright\cleardoublepage\else\clearpage\fi}
\def\cleardoublepage{> \expandafter\if@openright\cleardoublepage | \else\clearpage\fi}
\def\cleardoublepage{\if@openright> \cleardoublepage | \else\clearpage\fi}
\def\cleardoublepage{\if@openright> [espansione di \cleardoublepage] | \else\clearpage\fi}\altri\comandi
`
in cui (più o meno) alternativamente legge dall’input buffer e espande un token.A ogni passo, la “main token list” va dall’inizio della riga fino al “|”.
Questo è il nodo: dopo aver espanso \cleardoublepage e letto gli altri dati necessari dall’input buffer, può finire (diciamo così) un “ciclo di elaborazione”, nel senso che nella lista dei token ha tutto quello che gli serve per elaborarla. Quindi esegue il \def e dopo averlo fatto svuota la token list:
`
>|\altri\comandi
`
e si riparte.Grazie di nuovo delle spiegazioni.
Spero che Elrond non me ne voglia per avergli invaso la discussione. 🙂Ciao,
Antonio
-
25 Settembre 2011 alle 7:28 #64116
-
25 Settembre 2011 alle 7:29 #64117::
La vera domanda è:dopo aver espanso \cleardoublepage, è lì che, trovandosi in una situazione tipo
`
\def\cleardoublepage{\if@openright\qualcosa\ottenuto\dall\espansione\di\cleardoublepage > | \else\clearpage\fi}\altri\comandi
`
(rimarco “> |”), si rende conto che deve riprendere dall’inizio della token list?
-
25 Settembre 2011 alle 7:37 #64118::
Non funziona come pensi. Vediamo un esempio più semplice:
`\expandafter\a\expandafter\b\c`
Il primo token è espandibile, quindi TeX lo espande; questo causa l’espansione del secondo \expandafter, ma subito! TeX non esamina \a fino a che l’espansione del primo token sia terminata, ciò che avviene solo quando è espanso \c.Vediamone uno più complicato:
`\expandafter\expandafter\expandafter\a\expandafter\b\c`
I token sono sette, li indico con numeri. L’espansione di 1 causa, nell’ordine, quella di 3, 5 e 7. Al termine di questo avremo
`\expandafter\a\b`
Solo ora il token 2 della lista iniziale viene esaminato per dare dunque
`\a`
Nel caso precedente il risultato sarebbe
`\a\b`
e la differenza salta agli occhi, in particolare quando \b raccoglie argomenti.Ciao
Enrico
-
25 Settembre 2011 alle 17:14 #64119::
Ciao Enrico.
Ho cercato di documentarmi meglio, ma comunque non sono riuscito a capire cosa non va nel mio ragionamento.La notazione che ho usato (ripeto: l’ho improvvisata) non pretendo che rappresenti la verità profonda delle cose, ma spero che sia almeno “didatticamente valida”. Ti chiedo di dirmi in maniera esplicita se è invece fuorviante. Vorrei rappresentare il campo di azione dell’input processor (a destra del ‘|’), dell’expansion processor (tra l’inizio riga e il ‘|’), e dell’execution processor (ciò che sta all’inizio della riga e poi scompare).
Inoltre, dico giusto quando dico che a ogni passo, la “main token list” va dall’inizio della riga fino al “|”? (Non ho trovato riferimenti alla “main token list” nel TeXbook.)
In ogni caso, applicando quella notazione, ottengo esattamente le espansioni che hai riportato tu. Situazione iniziale con main token list vuota:
`
> | \expandafter\expandafter\expandafter\a\expandafter\b\c`
L’input processor legge i caratteri “\expandafter” e li trasforma nel token complesso expandafter
`
> \expandafter | \expandafter\expandafter\a\expandafter\b\c`
affinché l’expansion processor possa espandere expandafter, l’input processor gli prepara altri due token:
`
> \expandafter\expandafter\expandafter | \a\expandafter\b\c`
A questo punto, si può espandere il primo \expaft, e l’espansione lascia intatto il secondo \expaft e avvia l’espansione del terzo:
`
\expandafter >\expandafter | \a\expandafter\b\c`
Ma per espandere il terzo si devono ottenere altri due token, quindi:
`
\expandafter >\expandafter\a\expandafter | \b\c
\expandafter\a >\expandafter | \b\c
\expandafter\a >\expandafter\b\c |
\expandafter\a\b >\c |
\expandafter\a\b[espansione di \c] > |
`Mi pare sia in accordo con quanto dici tu (anche se ti riferivi al primo esempio, ma il concetto rimane):
TeX non esamina \a fino a che l’espansione del primo token sia terminata, ciò che avviene solo quando è espanso \c
Infatti, ora che ha fatto le espansioni a catena dovute al primo \expandafter* (“> |”), può riprendere a espandere dall’originariamente secondo \expandafter, ovvero da quello che io immagino sia ora il primo token della main token list. E quindi:
`
> \expandafter\a\b[espansione di \c] |
\a [espanzione di \b][espansione di \c] |
`Grazie della pazienza,
Antonio_____________________
* Forse sbaglio perché dovrei considerare tutte queste espansioni come un unico passo? Mi riferisco a quando dici:questo causa l’espansione del secondo \expandafter, ma subito!
-
25 Settembre 2011 alle 18:07 #64120
-
26 Settembre 2011 alle 11:36 #64121
-
-
AutoreRisposte
- Devi essere connesso per rispondere a questo topic.