Definire un epigraph come nota a margine

  • Creatore
    Topic
  • #68598
    Up
    0
    Down
    ::


    Voglio definire un comando che visualizzi una citazione (o simile) come nota a margine, da mettere dopo il comando \chapter e prima del testo. Mi piacerebbe che non crei problemi con il posizionamento del testo, cioè che ignori l’eventuale riga vuota lasciata dopo.

    Ecco l’idea in pratica e una possibile implementazione:
    `\documentclass[10pt,twoside]{scrreprt}

    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage[italian]{babel}
    \usepackage[eulerchapternumbers,pdfspacing]{classicthesis}
    \usepackage{lipsum}

    \setlength{\marginparwidth}{\dimexpr
    2\dimexpr\paperwidth-\textwidth\relax/3-3\marginparsep\relax}

    \newcommand\epigraph[2]{%
    \leavevmode\marginpar{\sffamily\itshape#1\\
    \medskip\hfill#2\enspace}%
    \let\oldpar\par
    \def\par{\let\par\oldpar}\ignorespaces}

    \begin{document}
    \chapter{Prova}

    \epigraph{Security protocols are three-line programs
    that people still manage to get wrong.}{Roger M.~Needham}

    \lipsum
    \end{document}`

    Non so quanto sia corretto ridefinire \par in questo modo e inoltre così facendo funziona solo se si lascia una sola riga vuota (con due o più non va).

    Quale sarebbe il modo corretto di scrivere un tale comando \epigraph?

    Grazie!

    Antonio

Visualizzazione 10 filoni di risposte
  • Autore
    Risposte
    • #68599
      Up
      0
      Down
      ::

      antonio.macrì” post=67710Voglio definire un comando che visualizzi una citazione (o simile) come nota a margine, da mettere dopo il comando \chapter e prima del testo. Mi piacerebbe che non crei problemi con il posizionamento del testo, cioè che ignori l’eventuale riga vuota lasciata dopo.

      Ecco l’idea in pratica e una possibile implementazione:
      `\documentclass[10pt,twoside]{scrreprt}

      \usepackage[T1]{fontenc}
      \usepackage[utf8]{inputenc}
      \usepackage[italian]{babel}
      \usepackage[eulerchapternumbers,pdfspacing]{classicthesis}
      \usepackage{lipsum}

      \setlength{\marginparwidth}{\dimexpr
      2\dimexpr\paperwidth-\textwidth\relax/3-3\marginparsep\relax}

      \newcommand\epigraph[2]{%
      \leavevmode\marginpar{\sffamily\itshape#1\\
      \medskip\hfill#2\enspace}%
      \let\oldpar\par
      \def\par{\let\par\oldpar}\ignorespaces}

      \begin{document}
      \chapter{Prova}

      \epigraph{Security protocols are three-line programs
      that people still manage to get wrong.}{Roger M.~Needham}

      \lipsum
      \end{document}`

      Non so quanto sia corretto ridefinire \par in questo modo e inoltre così facendo funziona solo se si lascia una sola riga vuota (con due o più non va).

      Quale sarebbe il modo corretto di scrivere un tale comando \epigraph?

      Un problema c’è: se non si lascia una riga vuota dopo \epigraph il primo \par che si incontra verrà ignorato.
      `\makeatletter
      \newcommand\epigraph[2]{%
      \leavevmode\marginpar{\sffamily\itshape#1\\
      \medskip\hfill#2\enspace}%
      \@ignorepars}
      \def\@ignorepars{\@ifnextchar\par{\afterassignment\@ignorepars\let\next}{}}
      \makeatother`
      Ciao
      Enrico

    • #68600
      Up
      0
      Down
      ::


      Appunti, pagina 123: \afterassignment usato per eliminare il token successivo (\par).

      Enrico, grazie!

    • #68601
      Up
      0
      Down
      ::

      antonio.macrì” post=67716Appunti, pagina 123: \afterassignment usato per eliminare il token successivo (\par).

      L’idea è di controllare il token che segue: se è \par, dobbiamo in qualche modo eliminarlo ed eseguire il controllo di nuovo. Infatti
      `\afterassignment\@ignorepars`
      inserisce \@ignorepars dopo che un’assegnazione è stata eseguita; ma la eseguiamo subito con \let\next che dopo di sé vede appunto \par (e lo elimina come parte dell’assegnazione del valore a \next).

      Ciao
      Enrico

    • #68602
      Up
      0
      Down
      ::


      Grazie.

      Non mi era chiaro perché si potesse fare
      `\@ifnextchar\par{…}{…}
      `dato che \par non è un carattere (e nemmeno la sua espansione). Mi sono rifatto ai tuoi Appunti (pagine 74-75, per chi ne fosse interessato) e ho risolto. 😉

      A proposito: dov’è definito \par?

      Mi rimane una curiosità: perché hanno scelto come nome \@ifnextchar? Magari è vero che l’uso più diffuso è
      `\@ifnextchar[{…}{…}
      `(per quello che ho visto io), ma con quel nome non ho mai pensato di sfidare la sorte e provare con un token complesso invece di un carattere!

    • #68603
      Up
      0
      Down
      ::

      antonio.macrì” post=67762Grazie.

      Non mi era chiaro perché si potesse fare
      `\@ifnextchar\par{…}{…}
      `dato che \par non è un carattere (e nemmeno la sua espansione). Mi sono rifatto ai tuoi Appunti (pagine 74-75, per chi ne fosse interessato) e ho risolto. 😉

      A proposito: dov’è definito \par?

      Mi rimane una curiosità: perché hanno scelto come nome \@ifnextchar? Magari è vero che l’uso più diffuso è
      `\@ifnextchar[{…}{…}
      `(per quello che ho visto io), ma con quel nome non ho mai pensato di sfidare la sorte e provare con un token complesso invece di un carattere!

      In effetti il nome può ingannare, ma l’uso principale è proprio per definire i comandi con argomento opzionale o con la variante * oppure quelli dell’ambiente picture che vogliono la parentesi tonda.

      \par è una primitiva di TeX che però ha un aspetto molto particolare: una coppia di “newline” consecutivi viene sostituita dal token “\par”, così come questo viene inserito automaticamente quando TeX trova un “comando verticale” come \vskip. Non viene inserito il significato primitivo di \par, ma proprio il token che ha quel nome. Per esempio
      `\let\par\undefined`
      seguito da una riga vuota produce un messaggio di errore. Naturalmente questa è una ridefinizione piuttosto sciocca, ma la peculiarità permette di ridefinire \par in modo che faccia quello che ci serve in alcune situazioni.

      Ciao
      Enrico

    • #68604
      Up
      0
      Down
      ::

      egreg9″ post=67764\par è una primitiva di TeX che però ha un aspetto molto particolare: una coppia di “newline” consecutivi viene sostituita dal token “\par”, così come questo viene inserito automaticamente quando TeX trova un “comando verticale” come \vskip. Non viene inserito il significato primitivo di \par, ma proprio il token che ha quel nome. Per esempio
      `\let\par\undefined`
      seguito da una riga vuota produce un messaggio di errore. Naturalmente questa è una ridefinizione piuttosto sciocca, ma la peculiarità permette di ridefinire \par in modo che faccia quello che ci serve in alcune situazioni.

      Ciao
      Enrico

      Allora ti chiedo: negli Appunti al paragrafo 8.1 (pagina 153) scrivi che l’esecuzione di \par comporta l’inserimento di quattro elementi: \unskip, \penalty10000, \hskip\parfillskip, \penalty-10000.

      Dove è definito questo comportamento? Dentro un file TeX/LaTeX o è interno al compilatore?

      Ti ringrazio!

    • #68605
      Up
      0
      Down
      ::

      antonio.macrì” post=67765

      \par è una primitiva di TeX che però ha un aspetto molto particolare: una coppia di “newline” consecutivi viene sostituita dal token “\par”, così come questo viene inserito automaticamente quando TeX trova un “comando verticale” come \vskip. Non viene inserito il significato primitivo di \par, ma proprio il token che ha quel nome. Per esempio
      `\let\par\undefined`
      seguito da una riga vuota produce un messaggio di errore. Naturalmente questa è una ridefinizione piuttosto sciocca, ma la peculiarità permette di ridefinire \par in modo che faccia quello che ci serve in alcune situazioni.

      Ciao
      Enrico

      Allora ti chiedo: negli Appunti al paragrafo 8.1 (pagina 153) scrivi che l’esecuzione di \par comporta l’inserimento di quattro elementi: \unskip, \penalty10000, \hskip\parfillskip, \penalty-10000.

      Dove è definito questo comportamento? Dentro un file TeX/LaTeX o è interno al compilatore?

      Ti ringrazio!

      Quello è il significato primitivo di \par.

      Ciao
      Enrico

    • #68606
      OldClaudio
      Partecipante
        Up
        0
        Down
        ::


        In realtà \@ifnextchar può verificare che cosa sia qualunque token; l’esecuzione di \@ifnextchar implica sostanzialmente l’assegnazione mediante \futurelet il significato del secondo token alla control sequence \@let@token per poi controllare con altri comandi che cosa fare nell’esisto del confronto dei token, non necessariamente dei caratteri; un carattere è un token ma anche una control sequence è un token; quindi puoi verificare qualunque token anche macro definite con \newcommand o equivalenti, e basta confrontarli con \ifx che ne verifica, se sono sviluppabili, la consistenza del primo sviluppo, vale a dire al definizione. Che cosa faccia \ifx rispetto agli altri condi condizionali è ben spiegato nel TeXbook; gli altri sviluppano i token che seguono, \ifx non li sviluppa ma ne confronta lo sviluppo, se esiste, altrimenti ne confronta solo codice e categoria.

        Il nome giusto che dovrebbe avere \@ifnextchar dovrebbe essere \@ifnexttoken; ma il Grand Wizard DEK ha scelto quell’altro nome, anche perché viene quasi sempre usato per confrontare caratteri.

      • #68607
        Up
        0
        Down
        ::

        OldClaudio” post=67772Il nome giusto che dovrebbe avere \@ifnextchar dovrebbe essere \@ifnexttoken; ma il Grand Wizard DEK ha scelto quell’altro nome, anche perché viene quasi sempre usato per confrontare caratteri.

        Forse Lamport? 🙂

        Ciao
        Enrico

      • #68608
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Sì, naturalmente, il Senior Vice Grand Wizard LL 🙂

        • #68609
          Up
          0
          Down
          ::


          Grazie a voi, i nostri Wizard! 😀

          Ciao
          Antonio

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

      Go to top