Classe o pacchetto: definire comandi facilmente ridefinibili

  • Creatore
    Topic
  • #39500
    Up
    0
    Down
    ::


    Ciao a tutti,

    in una classe che sto realizzando vorrei definire alcuni comandi che però hanno nomi tipici di comandi analoghi forniti da altri pacchetti, per esempio il comando \micro.

    Se però l’utente caricherà un pacchetto che definisce il comando \micro (usando \newcommand), LaTeX restituirà un errore.

    Esiste un modo sufficientemente generale per mettermi al riparo da questo tipo di errori?
    O, in generale, qual è la maniera migliore di definire dei comandi in una classe?

    Grazie.
    Ciao ciao.
    Fra

Visualizzazione 17 filoni di risposte
  • Autore
    Risposte
    • #39501
      Up
      0
      Down
      ::

      Ciao a tutti,

      in una classe che sto realizzando vorrei definire alcuni comandi che però hanno nomi tipici di comandi analoghi forniti da altri pacchetti, per esempio il comando \micro.

      Se però l’utente caricherà un pacchetto che definisce il comando \micro (usando \newcommand), LaTeX restituirà un errore.

      Esiste un modo sufficientemente generale per mettermi al riparo da questo tipo di errori?
      O, in generale, qual è la maniera migliore di definire dei comandi in una classe?

      In linea di massima è bene evitare di definire comandi già presenti in pacchetti di uso comune. Pochi giorni fa qualcuno scrisse su comp.text.tex chiedendo come fare per adoperare \o (necessario per una lettera dell’alfabeto danese) che la classe fornitagli dalla rivista ridefiniva come equivalente di \omega. ❗ Si scoprì poi che anche \a, \b, \d e \l erano ridefiniti come abbreviazioni di lettere greche. ❗

      Fai l’esempio di “\micro”: a che dovrebbe servire questo comando? Se ti serve per il prefisso del SI, la cosa migliore è di scrivere nella tua classe
      `\AtBeginDocument{
      \providecommand{\micro}{…}
      }`
      in modo che, se l’utente della classe carica siunitx, non abbia problemi con l’analogo comando definito nel pacchetto.

      Spiegazione: \AtBeginDocument{} esegue durante l’esecuzione di \begin{document}, quando tutti i pacchetti sono stati caricati e il preambolo è finito. Con “\providecommand{\xyz}…” dici di definire il comando \xyz (stessa sintassi di \newcommand) solo nel caso in cui \xyz non sia già definito.

      Per altri comandi ci saranno altre strade; esempi?

      Ciao
      Enrico

    • #39502
      Up
      0
      Down
      ::

      In linea di massima è bene evitare di definire comandi già presenti in pacchetti di uso comune. Pochi giorni fa qualcuno scrisse su comp.text.tex chiedendo come fare per adoperare \o (necessario per una lettera dell’alfabeto danese) che la classe fornitagli dalla rivista ridefiniva come equivalente di \omega. ❗ Si scoprì poi che anche \a, \b, \d e \l erano ridefiniti come abbreviazioni di lettere greche. ❗

      😀

      Fai l’esempio di “\micro”: a che dovrebbe servire questo comando? Se ti serve per il prefisso del SI, la cosa migliore è di scrivere nella tua classe
      `\AtBeginDocument{
      \providecommand{\micro}{…}
      }`
      in modo che, se l’utente della classe carica siunitx, non abbia problemi con l’analogo comando definito nel pacchetto.

      Grazie mille Enrico! È perfetto! La definizione di \micro, \ohm, e poco altro è appunto per le unità di misura. Volevo fornire comandi di base in modo che, chi non ha bisogno di grandi cose, non deve caricare siunitx.
      Per ora non mi sembra di avere casi che si discostano da questa linea. Ho qualche comando con argomenti, per esempio per scrivere apici e pedici in tondo, ma niente di più.

      Grazie di nuovo.
      Ciao ciao.
      Fra

    • #39503
      Up
      0
      Down
      ::


      Scusate se mi inserisco, ma se ridefinisci \micro e l’utente carica anche siunitx, quando vuole usare \micro all’interno di siunitix può succedere un patatrac…

      Secondo me, se sai che le tue definizioni sono incompatibili con siunitx è meglio verificare se il pacchetto siunitx è stato caricato ed eventualmente emettere un errore.

      Giacomo

    • #39504
      Up
      0
      Down
      ::

      Scusate se mi inserisco, ma se ridefinisci \micro e l’utente carica anche siunitx, quando vuole usare \micro all’interno di siunitix può succedere un patatrac…

      Secondo me, se sai che le tue definizioni sono incompatibili con siunitx è meglio verificare se il pacchetto siunitx è stato caricato ed eventualmente emettere un errore.

      È appunto lo scopo della definizione che ho proposto:
      `\ProvidesClass{pippo}[…]

      \AtBeginDocument{\providecommand{\micro}{…}}
      …`
      Se nel documento LaTeX c’è
      `\documentclass{pippo}

      \usepackage{siunitx}
      …`
      sarà usata la definizione di \micro data da siunitx; se nessuno dei pacchetti caricati dall’utente definisce \micro, ecco che la definizione data dalla classe “pippo” entra in vigore: \providecommand non fa nulla se il comando da definire esiste già. Nessun patatrac.

      Ciao
      Enrico

    • #39505
      Up
      0
      Down
      ::

      Scusate se mi inserisco, ma se ridefinisci \micro e l’utente carica anche siunitx, quando vuole usare \micro all’interno di siunitix può succedere un patatrac…

      Secondo me, se sai che le tue definizioni sono incompatibili con siunitx è meglio verificare se il pacchetto siunitx è stato caricato ed eventualmente emettere un errore.

      Giacomo

      Non so se ho capito ciò che vuoi dire.
      Una persona che carica \siunitx si aspetta che \micro faccia la cosa giusta. E con il codice di Enrico la fa perché ignora la mia definizione nel caso in cui il comando sia già definito.

      Ovviamente per coerenza farò in modo che comandi come \micro facciano la stessa cosa indipendentemente se viene usata la definizione della mia classe o quella di siunitx.
      In questo modo nessuno avrà (spero) brutte sorprese.

      Ciao ciao.
      Fra

      [edit]Non c’è nulla da fare, Enrico è troppo veloce! :D[/edit]

    • #39506
      Up
      0
      Down
      ::


      Grazie della spiegazione.

      Chissa perché ero convinto che \providecommand sovrascrivesse la definizione preesistente.

      Giacomo

    • #39507
      Up
      0
      Down
      ::

      Grazie della spiegazione.

      Chissa perché ero convinto che \providecommand sovrascrivesse la definizione preesistente.

      \providecommand è stato introdotto con LaTeX2e, per risolvere in modo rapido problemi del tipo esposto. Infatti \newcommand dà errore se il comando che segue è definito, mentre \renewcommand dà errore se il comando non è definito.

      Il contesto in cui si usa \providecommand è tipicamente quello di Francesco: se si vuole avere a disposizione un comando che un altro pacchetto definisce insieme ad altri senza dover per forza caricare l’intero pacchetto, ecco che \providecommand fa esattamente ciò che si desidera.

      Altro uso: vogliamo definire a modo nostro un certo comando, indipendentemente dal fatto che sia definito o no in uno dei pacchetti caricati:
      `\providecommand{\pippo}{}
      \renewcommand{\pippo}{…}`
      Con \providecommand ci assicuriamo che \pippo sia definito (non importa che cosa si mette tra le graffe della definizione) e quindi possiamo ridefinirlo.

      Per i curiosi: \providecommand esamina il comando che segue; se è definito esegue \renewcommand, altrimenti esegue \newcommand. Facile, no? La costruzione
      `\@ifdefinable{\pippo}{\newcommand{\pippo}{…}}`
      funziona come \providecommand, ma è molto meno amichevole. La ridefinizione con \providecommand e \renewcommand può essere realizzata con
      `\@ifundefined{pippo}{\newcommand}{\renewcommand}{\pippo}{…}`
      In tutti i casi si può specificare il numero di argomenti come al solito.

      Ciao
      Enrico

    • #39508
      Up
      0
      Down
      ::


      Enrico mi è venuto un dubbio.

      Se voglio definire “debolmente” un comando come abbiamo sopra discusso e se questo comando contiene dei condizionali, credo ci sia un problema.
      Esempio:
      `\providecommand{\celsius}{\ifmmode\mbox{\textcelsius}\else\textcelsius\fi}`

      Infatti un comando con queste caratteristiche dovrebbe essere definito con un \DeclareRobustCommand giusto?

      Esiste una versione speciale di \DeclareRobustCommand che faccia quello che fa \providecommand?

      Ciao ciao.
      Fra

    • #39509
      Up
      0
      Down
      ::


      Sono un po’ stupido.

      Almeno nell’esempio proposto credo basti risolvere così:
      `\providecommand{\celsius}{\ensuremath{\mbox{\textcelsius}}}`

      Però la domanda rimane. Come fare nei casi in cui ho veramente un condizionale o altri costrutti particolari che richiedo un DeclareRobustCommand?

      Ciao ciao.
      Fra

    • #39510
      Up
      0
      Down
      ::

      Sono un po’ stupido.

      Almeno nell’esempio proposto credo basti risolvere così:
      `\providecommand{\celsius}{\ensuremath{\mbox{\textcelsius}}}`

      Però la domanda rimane. Come fare nei casi in cui ho veramente un condizionale o altri costrutti particolari che richiedo un DeclareRobustCommand?

      Ciao ciao.
      Fra

      `\usepackage{etoolbox}
      \providerobustcmd{\pippo}{…}`
      Tanto per imparare qualcosa: la definizione
      `\providecommand{\celsius}{\mbox{\textcelsius}}`
      ti fa proprio schifo? 🙂 Volendo emulare meglio siunitx, ti propongo
      `\providerobustcmd{\celsius}{%
      \ensuremath{{}^{\circ}\kern-\scriptspace\mathrm{C}}}`
      Ciao
      Enrico

    • #39511
      Up
      0
      Down
      ::

      Tanto per imparare qualcosa: la definizione
      `\providecommand{\celsius}{\mbox{\textcelsius}}`
      ti fa proprio schifo? 🙂

      Assolutamente no! Non so perché ma mi ero convinto che \mbox potesse essere usato solo in ambiente matematico (forse la m?!). Ora sono andato un po’ a studiarmi le scatole* 🙂

      Volendo emulare meglio siunitx, ti propongo
      `\providerobustcmd{\celsius}{%
      \ensuremath{{}^{\circ}\kern-\scriptspace\mathrm{C}}}`

      Sì, ero consapevole di questo. Semplicemente prendono cerchietto e C e li avvicinano.
      Textcomp invece genera il carattere “gradi Celsius” di Unicode (Unicode 8451).
      Non so quale sia la scelta migliore tra le due.

      * A proposito: sarebbe interessante un paragrafetto nell’Arte dove si parla dei comandi LaTeX per la gestione delle scatole (\mbox, \makebox, \fbox, \framebox, \newsavebox, \sbox, \savebox, \usebox, \parbox, minipage, Lorenzo ci sei?! :D)

      Grazie Enrico.
      Ciao ciao.
      Fra

    • #39512
      lorenzo.pantieri
      Partecipante
        Up
        0
        Down
        ::

        A proposito: sarebbe interessante un paragrafetto nell’Arte dove si parla dei comandi LaTeX per la gestione delle scatole (\mbox, \makebox, \fbox, \framebox, \newsavebox, \sbox, \savebox, \usebox, \parbox, minipage, Lorenzo ci sei?! :D)

        Ci sono eccome! 😉

        Solo, non credo che quei comandi e ambienti (che, con la sola eccezione di \mbox, trovo piuttosto “TeXnici”) sarebbero utili al lettore “medio” dell’Arte. L’Arte è una guida di base, che ha l’obiettivo di spiegare le cose fondamentali di LaTeX in modo semplice: la compattezza e la semplicità hanno la precedenza sulla “completezza” (peraltro irraggiungible, in una guida a LaTeX).

        Rimanderei senz’altro il lettore “pro” a una guida di base più approfondita: quella di Beccari, ovviamente, e forse anche le bibbie di Knuth, Lamport e il Companion.

        Ciao,
        L.

      • #39513
        Up
        0
        Down
        ::

        A proposito: sarebbe interessante un paragrafetto nell’Arte dove si parla dei comandi LaTeX per la gestione delle scatole (\mbox, \makebox, \fbox, \framebox, \newsavebox, \sbox, \savebox, \usebox, \parbox, minipage, Lorenzo ci sei?! :D)

        Ci sono eccome! 😉

        Solo, non credo che quei comandi e ambienti (che, con la sola eccezione di \mbox, trovo piuttosto “TeXnici”) sarebbero utili al lettore “medio” dell’Arte. L’Arte è una guida di base, che ha l’obiettivo di spiegare le cose fondamentali di LaTeX in modo semplice: la compattezza e la semplicità hanno la precedenza sulla “completezza” (peraltro irraggiungible, in una guida a LaTeX).

        Rimanderei senz’altro il lettore “pro” a una guida di base più approfondita: quella di Beccari, ovviamente, e forse anche le bibbie di Knuth, Lamport e il Companion.

        Ciao,
        L.

        Wow non pensavo lo avresti mai letto! Era solo una provocazione, so bene che l’Arte non è rivolta a un pubblico avanzato, ma lo sai, io ci provo sempre! 😛

        Ciao ciao.
        Fra

      • #39514
        Up
        0
        Down
        ::


        Scusate se riapro la questione, ma ho due piccole domande:

        Volendo emulare meglio siunitx, ti propongo
        `\providerobustcmd{\celsius}{%
        \ensuremath{{}^{\circ}\kern-\scriptspace\mathrm{C}}}`

        1. Ora che ho tolto gli if dai semplici comandi che stavo definendo, è ancora veramente necessario usare etoolbox e il providerobustcmd? Mi è venuto il dubbio perché nel consigliarmi la definizione di \celsius non hai usato un semplice \providecommand.

        2. Se l’uso di \providerobustcmd fosse ancora necessario, che ne pensi se al posto di caricare etoolbox mi limitassi a scrivere:
        `\@ifdefinable{\pippo}{\DeclareRobustCommand{\pippo}{…}}`

        Grazie mille.
        Ciao ciao.
        Fra

      • #39515
        Up
        0
        Down
        ::

        Scusate se riapro la questione, ma ho due piccole domande:

        Volendo emulare meglio siunitx, ti propongo
        `\providerobustcmd{\celsius}{%
        \ensuremath{{}^{\circ}\kern-\scriptspace\mathrm{C}}}`

        1. Ora che ho tolto gli if dai semplici comandi che stavo definendo, è ancora veramente necessario usare etoolbox e il providerobustcmd? Mi è venuto il dubbio perché nel consigliarmi la definizione di \celsius non hai usato un semplice \providecommand.

        2. Se l’uso di \providerobustcmd fosse ancora necessario, che ne pensi se al posto di caricare etoolbox mi limitassi a scrivere:
        `\@ifdefinable{\pippo}{\DeclareRobustCommand{\pippo}{…}}`

        \providerobustcmd è certamente più efficiente di \DeclareRobustCommand; di fatto in questa situazione non è strettamente necessario perché \ensuremath è definito con \DeclareRobustCommand. In genere vanno “irrobustiti” comandi che si pensa possano trovar posto in argomenti mobili.

        Se definisci \celsius con il solo \newcommand (o \providecommand), l’unica differenza è che in un file ausiliario troverai invece di \celsius la sua espansione di primo livello, cioè
        `\ensuremath{{}^{\circ}\kern-\scriptspace\mathrm{C}}`
        perché \ensuremath è irrobustito come \mathrm e gli altri comandi che compaiono non sono espandibili (\circ, \kern e \scriptspace).

        Il vantaggio di {\new|\renew|\provide}robustcmd è che ciascuno di questi definisce un solo comando invece di due e l’espansione è di qualche nanosecondo più veloce. 🙂

        Ciao
        Enrico

      • #39516
        Up
        0
        Down
        ::

        Il vantaggio di {\new|\renew|\provide}robustcmd è che ciascuno di questi definisce un solo comando invece di due e l’espansione è di qualche nanosecondo più veloce.

        Grazie Enrico. Con questa cosa ho anche capito la storia dello spazio aggiuntivo con DeclareRobustCommand.

        Questi sono tutti i comandi che vorrei definire. Non credo se ne aggiungeranno altri.
        Il pacchetto textcomp è precaricato dalla classe. Quali di questi, secondo te, necessitano di un irrobustimento? (Assumiamo che tutti possano essere argomenti mobili)
        Io credo nessuno, a parte le abbreviazioni \g, \C e \A. Giusto?

        `\AtBeginDocument{

        % degree
        \providecommand{\degree}{\mbox{\textdegree}}
        \providecommand{\g}{\degree}

        % gradi Celsius
        \providecommand{\celsius}{\mbox{\textcelsius}}
        \providecommand{\C}{\celsius}

        % Angstrom
        \providecommand{\angstrom}{\mbox{\AA}}
        \providecommand{\A}{\angstrom}

        % micro
        \providecommand{\micro}{\mbox{\textmu}}

        % Ohm
        \providecommand{\ohm}{\ensuremath{\mbox{\textohm}}}

        % times (only math)
        \providecommand{\x}{\times}

        % measurement unit
        \providecommand*{\un}[1]{\ensuremath{\mathrm{\,#1}}}

        % Napier's number
        \providecommand{\eu}{\ensuremath{\mathrm{e}}}

        % imaginary unit
        \providecommand{\iu}{\ensuremath{\mathrm{i}}}

        % roman subscript
        \providecommand*{\rb}[1]{\ensuremath{_\mathrm{#1}}}

        % roman superscript
        \providecommand*{\rp}[1]{\ensuremath{^\mathrm{#1}}}

        % differential (only math)
        \providecommand{\diff}{\mathop{}\!d}

        % derivative and partial derivative (only math)
        \providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
        \providecommand*{\pder}[3][]{%
        \frac{\partial^{#1}#2}{\partial #3^{#1}}%
        }

        }`

        Ciao ciao.
        Fra

      • #39517
        Up
        0
        Down
        ::

        Questi sono tutti i comandi che vorrei definire. Non credo se ne aggiungeranno altri.
        Il pacchetto textcomp è precaricato dalla classe. Quali di questi, secondo te, necessitano di un irrobustimento? (Assumiamo che tutti possano essere argomenti mobili)
        Io credo nessuno, a parte le abbreviazioni \g, \C e \A. Giusto?

        `\newcommand*{\class@container}[1]{\textrm{\upshape#1}}
        \AtBeginDocument{
        % degree
        \providecommand{\degree}{\class@container{\textdegree}}
        \providecommand{\g}{\degree}

        % gradi Celsius
        \providecommand{\celsius}{\class@container{\textcelsius}}
        \providecommand{\C}{\celsius}

        % Angstrom
        \providecommand{\angstrom}{\class@container{\AA}}
        \providecommand{\A}{\angstrom}

        % micro
        \providecommand{\micro}{\class@container{\textmu}}

        % Ohm
        \providecommand{\ohm}{\class@container{\textohm}}

        % times (only math)
        \providecommand{\x}{\times}

        % measurement unit
        \providecommand*{\un}[1]{\ensuremath{\mathrm{\,#1}}}

        % Napier's number
        \providecommand{\eu}{\ensuremath{\mathrm{e}}}

        % imaginary unit
        \providecommand{\iu}{\ensuremath{\mathrm{i}}}

        % roman subscript
        \providecommand*{\rb}[1]{\ensuremath{_\mathrm{#1}}}

        % roman superscript
        \providecommand*{\rp}[1]{\ensuremath{^\mathrm{#1}}}

        % differential (only math)
        \providecommand{\diff}{\mathop{}\!d}

        % derivative and partial derivative (only math)
        \providecommand*{\der}[3][]{\frac{d^{#1}#2}{d #3^{#1}}}
        \providecommand*{\pder}[3][]{%
        \frac{\partial^{#1}#2}{\partial #3^{#1}}%
        }
        }`
        I comandi riguardanti unità di misura devono sempre essere in tondo (diritti). Rimango molto perplesso su \x, ma anche su \A, \g e \C. A parte che l’Angstrom è un’unità deprecata, o sbaglio?

        Trova un nome migliore per \class@container. Se usi amsmath i comandi definiti tramite \textrm cambiano grandezza se scritti in esponenti o pedici.

        Ciao
        Enrico

      • #39518
        Up
        0
        Down
        ::

        I comandi riguardanti unità di misura devono sempre essere in tondo (diritti).

        Uhm credo di aver capito. Mi stai dicendo che con le mie definizioni le unità venivano correttamente composte in tondo nel testo normale e in ambiente matematico, ma se per sbaglio fossero finite, per esempio, in un \textit, sarebbero state composte in corsivo, che è sbagliato. In effetti non avevo considerato questo caso.

        Rimango molto perplesso su \x, ma anche su \A, \g e \C. A parte che l’Angstrom è un’unità deprecata, o sbaglio?

        Diciamo che sono molto indeciso su queste abbreviazioni. Sono solo frutto della mia esperienza. Per esempio \x è nato perché una casa editrice non permetteva l’uso di siunitx e così ho dovuto riscrivere tutti i \SI{7e5}{…} ecc… come $7 \times 10^5…$.
        Con il comando in questione ottengo invece $7 \x 10^5…$ che è leggermente più veloce da scrivere e anche più facile da leggere.

        Sì, l’angstrom non è nel SI. Per me lo potrebbero anche abolire e usare i nanometri ma è usato in moltissimi campi e così mi sono deciso a inserirlo. Ma mi riservo il diritto di farlo sparire 🙂

        Se usi amsmath i comandi definiti tramite \textrm cambiano grandezza se scritti in esponenti o pedici.

        Cioè se non ho capito male mi stai dicendo che usare \textrm per quelle definizioni, senza caricare amsmath, è sbagliato perché a pedice o a apice verrebbero composte con il corpo sbagliato, cioè non opportunamente rimpicciolito. Comunque nella mia classe già carico amsmath.

        Grazie infinite!
        Ciao ciao.
        Fra

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

    Go to top