estrarre le opzioni delle classi standard

  • Creatore
    Topic
  • #1633
    Up
    0
    Down
    ::


    ciao a tutti,
    sto scrivendo un pacchetto, che vorrei far interagire con le classi standard.
    in particolare vorrei poter scrivere un po’ di codice che “estragga” le opzioni passate alla classe standard di LaTeX.
    in particolare vorrei sapere se il documento è oneside,twoside,a4,12pt,11pt,10, in modo da dire:
    se il documento è twoside allor processa le seguenti istruzioni, se è oneside… etc

    spero di essermi spiegato
    ciao
    f

Visualizzazione 15 filoni di risposte
  • Autore
    Risposte
    • #1634
      ev
      Partecipante
        Up
        0
        Down
        ::

        in particolare vorrei poter scrivere un po’ di codice che “estragga” le opzioni passate alla classe standard di LaTeX.

        Le opzioni con cui e’ richiamata la classe in uso si trovano in`\@classoptionslist`Si tratta della lista completa (utilizzabile solo nel preambolo) delle opzioni separate solo da una virgola; il parsing devi effettuarlo in separata sede da solo. L’alternativa, che ti semplificherebbe il parsing ma ti complicherebbe la vita in altro modo, e’ usare`\@ifclasswith{}{}{}{}`che pero’ come vedi necessita dell’indicazione esplicita della classe oltre che dell’opzione di cui testare la presenza. Per esempio, quanto segue controlla l’utilizzo di memoir con oneside, ma non funziona minimamente con book:`\@ifclasswith{memoir}{oneside}{\def\pippo{solo fronte}}{\def\pippo{fronte e retro}}`Una soluzione decisamente limitante.

      • #1635
        Up
        0
        Down
        ::


        In effetti la seconda soluzione è molto più facile della prima, ma limitante.

        per quanto riguarda \@classoptionslist è da ieri che ci provo ma non ci cavo un ragno dal buco. ho dato un occhiata in giro e al sorgente di latex ma non ci capisco un piffero e non ho idea di come fare a estrarre le opzioni.

        secondo te mi sto imbarcando in qualcosa di incasinatissimo? dove potrei documentarmi?

        ciao
        f

      • #1636
        ev
        Partecipante
          Up
          0
          Down
          ::

          per quanto riguarda \@classoptionslist è da ieri che ci provo ma non ci cavo un ragno dal buco. ho dato un occhiata in giro e al sorgente di latex ma non ci capisco un piffero e non ho idea di come fare a estrarre le opzioni.

          Per estrarre la testa di una lista di oggetti separati da una virgola potresti “giocherellare” con \def e gli argomenti delimitati nel seguente modo:`\def\controllo#1,#2\fine{%
          \def\temp@a{#2}%
          \ifx\temp@a\@empty
          \let\next\relax
          \else
          \def\next{\controllo#2\fine}%
          \fi
          opzione: #1\newline
          \next}`
          Per usarlo tieni a mente che ci devi aggiungere una virgola, altrimenti l’ultimo argomento non e’ delimitato correttamente:`\def\pippo{ciao,a,tutti}
          \expandafter\controllo\pippo,\fine`Nel tuo caso, invece di scivere opzione XYZ potresti testare #1 (dopo averlo infilato in una macro di appoggio come \temp@b) con \ifx.

          secondo te mi sto imbarcando in qualcosa di incasinatissimo? dove potrei documentarmi?

          Sul TeXbook, ovviamente 😉

        • #1637
          Up
          0
          Down
          ::


          Vediamo un po’ se ci capisco qualcosa
          `\def\controllo#1,#2\fine{%`

          allora: definisci un comando chiamato controllo che ha due argomenti, separati da una virgola. se non ho capito male l’idea hai una lista di elementi e con \controllo li guardi uno per uno, fino alla fine.
          \fine cos’é?

          ` \def\temp@a{#2}%`
          altro comando interno, che si becca il secondo argomento di controllo. mi par di capire che serve per vedere se ci sono aoncora elementi nella lista.

          ` \ifx\temp@a\@empty
          \let\next\relax
          `
          se la mia supposizione è esatta si controlla se non c’è l’n+1 elemento, in tal caso si smette di controllare. immahino \@emty voglia semplicmeente dire vuoto.
          mi sfuggono i dettagli, la differenza fra \if e \ifx, cosa si fa con la seconda riga.

          `
          \else
          \def\next{\controllo#2\fine}%
          \fi
          `
          altrimenti si definisce \next come…
          qui immagino che si salvi il valore trovato.

          `
          opzione: #1\newline
          \next}`

          qui è abbastanza facile: si fa una bella tabellina con scritto
          opzione: x
          opzione: y

          come vedi E. sono davvero limitato…

          Per usarlo tieni a mente che ci devi aggiungere una virgola, altrimenti l’ultimo argomento non e’ delimitato correttamente:[code]\def\pippo{ciao,a,tutti}
          \expandafter\controllo\pippo,\fine

          si, questo è chiaro, anche se continua a sfuggirmi il significato di \fine

          Nel tuo caso, invece di scivere opzione XYZ potresti testare #1 (dopo averlo infilato in una macro di appoggio come \temp@b) con \ifx.

          ???????????

          Sul TeXbook, ovviamente 😉

          già, forse era meglio studiare ancora un po’ che mettersi a smanettare sui pacchetti… lo faccio per imparare, perdonatemi…

          ciao
          f

        • #1638
          ev
          Partecipante
            Up
            0
            Down
            ::

            `\def\controllo#1,#2\fine{%`allora: definisci un comando chiamato controllo che ha due argomenti, separati da una virgola. se non ho capito male l’idea hai una lista di elementi e con \controllo li guardi uno per uno, fino alla fine.

            Esatto.

            \fine cos’é?

            Un token qualunque per segnalare a TeX che il secondo argomento di \controllo e’ tutto quello che si trova tra la prima virgola e questo token, quindi il “resto” della lista.

            ` \def\temp@a{#2}%`altro comando interno, che si becca il secondo argomento di controllo. mi par di capire che serve per vedere se ci sono aoncora elementi nella lista.

            Esatto.

            ` \ifx\temp@a\@empty
            \let\next\relax
            `se la mia supposizione è esatta si controlla se non c’è l’n+1 elemento, in tal caso si smette di controllare.

            Esatto.

            immahino \@emty voglia semplicmeente dire vuoto.

            Esatto. E’ la “versione” interna di \empty, da utilizzarsi preferibilmente perche’ qualche pacchetto potrebbe combinarti lo scherzetto di ridefinire \empty come qualche cosa di non vuoto. Se proprio si vuol essere sicuri, basta crearsi qualche cosa di sicuramente vuoto con \def\sicuramentevuoto{}.

            mi sfuggono i dettagli, la differenza fra \if e \ifx, cosa si fa con la seconda riga.

            \if controlla l’uguaglianza dei character code dei due argomenti (i primi due token che incontra) mentre \ifx effettua un solo passo di espansione dei due token incriminati e controlla che la loro definizione sia esattamente uguale. In questo caso, si controlla che #2 sia completamente vuoto.

            `
            \else
            \def\next{\controllo#2\fine}%
            \fi
            `
            altrimenti si definisce \next come…
            qui immagino che si salvi il valore trovato.

            Con quella ridefinizione di \next si “riimmette” nel flusso di input il comando \controllo passandogli come argomento la coda della lista del passo precedente.

            Nel tuo caso, invece di scivere opzione XYZ potresti testare #1 (dopo averlo infilato in una macro di appoggio come \temp@b) con \ifx.

            ???????????

            Intendevo qualche cosa del tipo:`\def\temp@b{#1}%
            \def\temp@c{12pt}%
            \ifx\temp@b\temp@c
            % Abbiamo beccato l'opzione 12pt
            \else
            \def\temp@c[11pt}%
            \ifx \temp@b\temp@c
            % Abbiamo beccato l'opzione 11pt
            \fi
            \fi`

            già, forse era meglio studiare ancora un po’ che mettersi a smanettare sui pacchetti… lo faccio per imparare, perdonatemi…

            E quale modo migliore di imparare se non mettere in pratica la teoria?

          • #1639
            Up
            0
            Down
            ::


            Secondo me c’hai piantato un erroretto:
            `
            \def\controllo#1,#2\fine{%
              \def\temp@a{#2}%
              \ifx\temp@a\@empty
                \let\next\relax
              \else
            \def\temp@b{#1}%
            \def\temp@c{12pt}%
            \ifx\temp@b\temp@c
              % Abbiamo beccato l'opzione 12pt
            \else
              \def\temp@c[11pt}%
              \ifx \temp@b\temp@c
                % Abbiamo beccato l'opzione 11pt
              \fi
            \fi
                \def\next{\controllo#2\fine}%
              \fi
              opzione: #1\newline
              \next}
            `

            Secondo la tua definizione \controllo come prima cosa guarda se il secondo argoemnto è nullo e in tal caso esce dal ciclo.
            così facendo non viene fatto nessun controllo sul primo elemento.
            secondo me si può partire dall’assunto che la lista è non vuota (le classi hanno sempre almeno un opzione no?) e invertire l’ordine dei controlli, ovvero prima si controlla se il primo elemento corriponde all’opzione taldeitali, poi in caso non ci siano più elementi si esce.

            che ne pensi?
            (ho già scritto il comando che mi salva le opzioni oneside,twoside,10pt,11pt,12pt,a4paper, che funziona da dio ma solo se l’opzione non è la prima della lista. credo manchi solo questo dettaglio e poi posto il codice completo).

            piccolo dettaglio tecnico: c’è un modo di usare l’if ma con il falso? \ifx\temp@a\temp@b in C sarebbe equivalente a \if{a==b}, come si fa invece a fare \if{a!=b}?

            grazie infinite
            f

          • #1640
            Up
            0
            Down
            ::


            Ecco, questa è una macro che estrae le opzioni a4paper,10pt,11pt,12pt,oneside,twoside da una qualinque lista separata da virgole.

            `
            \def\controllo#1,#2\fine{%
            \def\temp@b{#1}%
            \def\temp@c{a4paper}
            \ifx\temp@b\temp@c
            %il documento è a4

            \fi
            \def\temp@c{12pt}%
            \ifx\temp@b\temp@c
            %il documento è 12pt

            \else
            \def\temp@c{11pt}
            \ifx\temp@b\temp@c
            %il documento è 11pt

            \else
            \def\temp@c{10pt}
            \ifx\temp@b\temp@c
            %il documento è 10pt

            \fi
            \fi
            \fi
            \def\temp@c{oneside}
            \ifx\temp@b\temp@c
            %il documento è oneside

            \else
            \def\temp@c{twoside}
            \ifx\temp@b\temp@c
            %il documento è twoside

            \fi
            \fi
            \def\temp@a{#2}%
            \ifx\temp@a\@empty
            \let\next\relax
            \else
            \def\next{\controllo#2\fine}%
            \fi
            \next
            }
            `

            a parte riciclare quanto mi ha detto E. non è che ci abbia messo tanto del mio, ma commento lo stesso il codice:

            `
            \def\controllo#1,#2\fine{%
            \def\temp@b{#1}%
            \def\temp@c{a4paper}
            \ifx\temp@b\temp@c
            %il documento è a4
            \fi
            `

            si suppone che la lista sia costituita da almeno un elemento, se ne salva il valore in \temp@b e si controlla se è uguale a a4paper.
            controllo ha anche un secondo elemento, il secondo della lista, che eventualemnte può essere vuoto (lista costituita da un solo elemento).

            `
            \def\temp@c{12pt}%
            \ifx\temp@b\temp@c
            %il documento è 12pt

            \else
            \def\temp@c{11pt}
            \ifx\temp@b\temp@c
            %il documento è 11pt

            \else
            \def\temp@c{10pt}
            \ifx\temp@b\temp@c
            %il documento è 10pt

            \fi
            \fi
            \fi
            `

            analogamente a quanto sopra, ma si controlla l’opzione della dimensione del carattere

            `
            \def\temp@c{oneside}
            \ifx\temp@b\temp@c
            %il documento è oneside

            \else
            \def\temp@c{twoside}
            \ifx\temp@b\temp@c
            %il documento è twoside

            \fi
            \fi
            `

            ora è il momento di oneside e twoside

            `
            \def\temp@a{#2}%
            \ifx\temp@a\@empty
            \let\next\relax
            `

            si controlla se l’elemnto successivo a quello controllato è vuoto e in tal caso si esce

            `
            \else
            \def\next{\controllo#2\fine}%
            \fi
            \next
            }
            `

            se la lista ha ancora degli elementi questi vengono ripassati in coda al comando \controllo, che ricomincia un altro ciclo.

            grazie mille E. sei stato provvidenziale.
            ora vado a mangià…
            ciao a tutti
            f

          • #1641
            ev
            Partecipante
              Up
              0
              Down
              ::

              Secondo me c’hai piantato un erroretto:

              Secondo me dipende dal tuo copia-incolla: bastava incollare il secondo pezzo al posto di opzione: #1\newline 🙂

              Secondo la tua definizione \controllo come prima cosa guarda se il secondo argoemnto è nullo e in tal caso esce dal ciclo.

              Correzione: \controllo appronta le cose per uscire dal ciclo al termine dell’iterazione corrente, non esce direttamente.

              secondo me si può partire dall’assunto che la lista è non vuota (le classi hanno sempre almeno un opzione no?)

              No.

              piccolo dettaglio tecnico: c’è un modo di usare l’if ma con il falso? \ifx\temp@a\temp@b in C sarebbe equivalente a \if{a==b}, come si fa invece a fare \if{a!=b}?

              Non si fa 🙂 ma puoi sempre usare il ramo else mettendo un \relax nel ramo then.

            • #1642
              Up
              0
              Down
              ::

              secondo me si può partire dall’assunto che la lista è non vuota (le classi hanno sempre almeno un opzione no?)

              No.

              cacchiarola, me ne accorgo ora, avevo male interpretato.
              inizialmente pensavo che in
              \@classoptionslist
              erano contenuti tutti i parametri della classe, pure quelli di default. che ingenuo, la lista contiene solo le opzioni specificate dall’utente.
              se modificare \controllo in maniera da ovviare al problema (lista vuota) non è difficile,questo fatto pone un altro problema.

              il mio pacchetto in un certo senso deve sapere se il foglio è settato a4, qual’è la dimensione del font in uso e se il documento è oneside o twoside.
              per quanto riguarda a4paper non c’è problema perché non è di default su nessuna delle classi standard di LaTeX e quindi il pacchetto, a meno che non ci sia l’opzione esplicita, restituisce un errore.
              per quanto riguarda la dimensione del font credo che di default tutte le classi standard usino 11pt, quindi anche qui non è difficile, basta che definisco 11pt come di default, e negli altri casi questo mi verrà modificato dalla dichiarazione esplicta dell’opzione.
              l’unico vero problema si pone con twoside e oneside, esempio banale book e article. non posso definire nel pacchetto l’uno dei due stili come default, perché altrimenti modifico il comportamento di default di una delle due classi.

              bel rompicapo no?

            • #1643
              ev
              Partecipante
                Up
                0
                Down
                ::

                per quanto riguarda a4paper non c’è problema perché non è di default su nessuna delle classi standard di LaTeX e quindi il pacchetto, a meno che non ci sia l’opzione esplicita, restituisce un errore.

                Oppure, potresti controllare che \paperheight == 297mm e \paperwidth == 210mm, tanto per non porre limiti arbitrari.

                per quanto riguarda la dimensione del font credo che di default tutte le classi standard usino 11pt

                No, la dimensione standard e’ di 10pt. L’ultima cifra di 10, 11 e 12 e’ memorizzata in \@ptsize, quindi potresti controllare se si tratta di uno 0, di un 1 o di un 2.

                l’unico vero problema si pone con twoside e oneside

                Il kernel definisce \if@twoside per permettere controlli di questo tipo e le opzioni oneside e twoside alterano questo valore, quindi:`\if@twoside
                % blah blah blah
                \else
                % blah blah blah
                \fi`

              • #1644
                Up
                0
                Down
                ::


                funziona tutto. l’unica cosa se faccio banalmente

                `
                \if\paperheight == 297mm
                istruzione
                \fi
                `

                non succede niente, ne con \if ne con \ifx. il tutto deriva dalla mia ignoranza rispetto ai costrutti \if di TeX (bisogna davvero che mi metta a sfogliare il texbook)

                ho arrabattato facendo:

                `
                \newdimen\LA@tem@dim
                \setlength{\LA@tem@dim}{297mm}

                \ifx\paperheight\LA@tem@dim
                istruzione
                \fi
                `

                ma non funziona, neppure con \if. vado a vedere se trovo la soluzione.

                per ilr esto tutto bene
                grazie mille
                ciao
                f

              • #1645
                Up
                0
                Down
                ::


                nel frattempo ho anche aggiunto un controllo per verificare se il documento è onecolumn o twocolumn, utilizzando un banalissimo
                \if@twocolumn

                per quanto riguarda portrait credo che se si fa il controllo sulle dimensioni della pagina vada già bene, dal momento che la definizione dell’opzione è:

                `
                {\setlength\@tempdima {\paperheight}%
                \setlength\paperheight {\paperwidth}%
                \setlength\paperwidth {\@tempdima}}
                `

                e se quindi viene specificata l’opzione landascape questo modifica le dimensioni della pagina e quando si fa il controllo su \paperwidth e \paperheigth (è il primo) il pacchetto da un errore…

                ciao
                f

              • #1646
                ev
                Partecipante
                  Up
                  0
                  Down
                  ::

                  `\if\paperheight == 297mm
                  istruzione
                  \fi`non succede niente, ne con \if ne con \ifx. il tutto deriva dalla mia ignoranza rispetto ai costrutti \if di TeX (bisogna davvero che mi metta a sfogliare il texbook)

                  Devi usare \ifdim:`\ifdim\paperheight=297mm
                  % blah blah blah
                  \fi`Inoltre, anche se stai usando i costrutti condizionali del Plain TeX, ti consiglio di dichiarare le variabili contenenti dimensioni con \newlength

                • #1647
                  Up
                  0
                  Down
                  ::

                  Devi usare \ifdim

                  funziona…

                  Inoltre, anche se stai usando i costrutti condizionali del Plain TeX, ti consiglio di dichiarare le variabili contenenti dimensioni con \newlength

                  perché?
                  io sto usando \newdimen, ma solo perché scopiazzo alla grande dalle classi e pacchetti e perché l’ho letto nella guida per scrittori di classi e pacchetti, perché mi consigli il contrario?

                  ancora un grazie infinito, il pacchetto è quasi finito
                  f

                • #1648
                  ev
                  Partecipante
                    Up
                    0
                    Down
                    ::

                    io sto usando \newdimen, ma solo perché scopiazzo alla grande dalle classi e pacchetti e perché l’ho letto nella guida per scrittori di classi e pacchetti, perché mi consigli il contrario?

                    Perché \newdimen è Plain TeX (ok, ok, stai già mischiando LaTeX con non-LaTeX, lo so, altrimenti al posto di \if & Co. avresti usato il pacchetto ifthen) e le variabili di tipo “lunghezza” create con \newdimen sono diverse da quelle create con \newlength (vedere la differenza tra lengths e glues sul TeXbook). Se però sei estremamente sicuro che non ti serve uno \skip allora procedi pure con \newdimen.

                    Ma sei sicuro che in clsguide.{dvi,ps,pdf} consiglino di usare \newdimen?

                  • #1649
                    Up
                    0
                    Down
                    ::

                    Se però sei estremamente sicuro che non ti serve uno \skip allora procedi pure con \newdimen.

                    si sono sicuro, però non mi costa niente usare \newlength.

                    Ma sei sicuro che in clsguide.{dvi,ps,pdf} consiglino di usare \newdimen?

                    mmm, no. al massimo controllo.
                    ciao e ancora grazie
                    f

                Visualizzazione 15 filoni di risposte
                • Devi essere connesso per rispondere a questo topic.

                Go to top