-
Notifications
You must be signed in to change notification settings - Fork 0
/
xkeyval-tutorial.tex
145 lines (115 loc) · 8.76 KB
/
xkeyval-tutorial.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
\documentclass{scrartcl}
\usepackage[utf8x]{inputenc}
\usepackage[italian]{babel}
\usepackage[T1]{fontenc}
\usepackage{color}
%\usepackage{hyperref}
\usepackage{listings}
%\usepackage{amsmath}
\lstset{language=[LaTeX]TeX,
basicstyle=\ttfamily,
keywordstyle=\color{cyan},
escapeinside={^|}{|^},
numbers=left
}
\newcommand{\meta}[1]{$\langle$\textit{#1}$\rangle$}
\begin{document}
\title{Opzioni di pacchetto e di classe con xkeyval}
\subtitle{Un semplice tutorial con casi d'uso illustrati}
\author{Carlo~Stemberger}
\publishers{ver.~0.0}
\maketitle
\begin{abstract}
\noindent Questa guida è un semplice tutorial scritto per aiutare chi inizia a programmare in \LaTeX\ a predisporre opzioni di classe e di pacchetto usando xkeyval. Al di là del proclama ufficiale, lo scopo ultimo di questo lavoro è in realtà quello di mettere ordine tra le idee dell'autore.
\end{abstract}
\section{Le opzioni di pacchetto e di classe}
Quando si scrive una classe o un pacchetto \LaTeX, è quasi sempre necessario prevedere delle \emph{opzioni}, ovvero dei comportamenti alternativi che l'utente attiverà a seconda delle proprie esigenze.
\LaTeX\ offre nativamente questa possibilità. Vediamo subito un primo esempio per capire di cosa parliamo.
\begin{lstlisting}
\usepackage[pluto]{pippo}
\end{lstlisting}
Chiunque abbia usato almeno una volta \LaTeX\ avrà senz'altro visto questo tipo di sintassi nel preambolo dei propri documenti. Ma cosa succede dietro le quinte, quando si carica un pacchetto in questo modo? In breve:
\begin{enumerate}
\item vengono inglobati nel preambolo del documento i comandi e gli ambienti presenti in un file di nome \lstinline+pippo.sty+, per renderli disponibili all'utente;
\item viene seguita la logica attivata dall'opzione \lstinline+pluto+.
\end{enumerate}
Ecco come potrebbe presentarsi lo scheletro del pacchetto \lstinline+pippo.sty+, usando esclusivamente gli strumenti offerti da \LaTeX:
\begin{lstlisting}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{pippo}
\DeclareOption{pluto}{^|\meta{codice}|^}
\ProcessOptions\relax
\end{lstlisting}
dove \meta{codice} sono quelle macro che vengono lanciate nel caso in cui l'utente richiami il pacchetto con l'opzione \lstinline+pluto+.
\section{Le opzioni con xkeyval}
Come si può vedere, fin qui è tutto molto semplice. Per chi è abituato a ragionare in termini di algoritmi, si tratta in buona sostanza della struttura di controllo if--then: \emph{se} l'opzione \lstinline+pluto+ è presente, \emph{allora} fai questo. Ovviamente se l'opzione non viene inserita, non viene fatto niente di particolare.
Tante cose possono essere fatte in questo modo, ma spesso non basta. Il limite maggiore è proprio l'impossibilità di \emph{modulare} l'opzione, ovvero di assegnarle dei valori. Usando gli strumenti nativi di \LaTeX\ l'opzione può solo o esserci, o non esserci.
Il pacchetto xkeyval permette di superare questo limite, offrendo la possibilità di inserire delle opzioni di tipo chiave--valore (key--value, in inglese). La sintassi è in buona parte retro-compatibile con quella che abbiamo presentato in precedenza. Vediamo subito lo stesso esempio usando xkeyval:
\begin{lstlisting}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{pippo}
\RequirePackage{xkeyval}
\DeclareOptionX{pluto}{^|\meta{codice}|^}
\ProcessOptionsX
\end{lstlisting}
Con xkeyval, alle 2 possibilità ``tradizionali'' offerte all'utente della classe o pacchetto che stiamo scrivendo ne viene aggiunta una terza. Infatti ora l'opzione può:
\begin{enumerate}
\item non esserci
\item essere semplicemente presente
\item essere presente nella forma chiave--valore
\end{enumerate}
È facile intuire quanto sia l'incremento di potenza. Ecco qui di seguito una breve descrizione dei diversi aspetti.
\begin{description}
\item[Ordine e chiarezza.] Il primo motivo per preferire in alcuni casi opzioni di tipo chiave--valore è la chiarezza: si vedano a tal proposito gli esempi presentati nelle sezioni \ref{sec:gruppo} e [\dots].
\item[Gestione di infiniti valori.] [\dots]
\end{description}
\section{Gruppo limitato di valori}
\label{sec:gruppo}
Spesso capita di voler lasciare agli utenti la scelta tra un numero limitato di valori. Ecco un esempio reale, tratto dalla classe missa.
\begin{lstlisting}
\RequirePackage{color}
\definecolor{DartmouthGreen}{rgb}{0,0.4392,0.2353}
\definecolor{Violet}{rgb}{0.498,0,1}
\definecolor{ClassicRose}{rgb}{0.9843,0.8,0.9059}
\newcommand{\missa@litcolor}{DartmouthGreen}
\define@choicekey+{missa.cls}{litcolor}[\val\nr]{%
green,violet,white,red,rose,black}[green]{%
\ifcase\nr\relax
\renewcommand{\missa@litcolor}{DartmouthGreen}
\or
\renewcommand{\missa@litcolor}{Violet}
\or
\renewcommand{\missa@litcolor}{#1}
\or
\renewcommand{\missa@litcolor}{#1}
\or
\renewcommand{\missa@litcolor}{ClassicRose}
\or
\renewcommand{\missa@litcolor}{#1}
\fi
}{%
\ClassWarning{missa}{erroneous input ignored}%
}
\ProcessOptionsX
\end{lstlisting}
L'opzione \lstinline+litcolor+ permette di impostare il colore liturgico, che poi sarà utilizzato dalla classe.
Il suo uso è del tutto evidente:
\begin{lstlisting}
\documentclass[litcolor=^|\meta{colore}|^]{missa}
\end{lstlisting}
I colori possibili sono 6: green (verde), violet (violaceo), white (bianco), red (rosso), rose (rosaceo) e black (nero). 3 di questi (bianco, rosso e nero) sono già definiti dal pacchetto color, e sono quindi già pronti per essere usati senza dover scrivere una sola riga di codice, mentre per gli altri è stato necessario impostarli dichiarando le diverse tonalità tramite i valori assegnati ai canali RGB (righe 3--5).
Alla riga 7 semplicemente viene definito un nuovo comando che ha come unico scopo quello di conservare il colore liturgico scelto dall'utente: il valore preimpostato è \lstinline+DartmouthGreen+, che è la tinta di verde precedentemente definita alla riga 3.
Le righe 9--26 meritano un'analisi dettagliata.
Innanzitutto appare subito evidente che la definizione dell'opzione avviene in modo diverso da quanto finora visto. Ecco la spiegazione. Il comando \lstinline+\DeclareOptionX+ è previsto dal xkeyval proprio per agevolare la migrazione dagli strumenti nativi di \LaTeX\ che, come abbiamo visto, hanno una sintassi molto simile. In realtà è possibile sostituire \lstinline+\DeclareOptionX+ con \lstinline+\define@key{missa.cls}+, dove \lstinline+missa.cls+ è il file della classe in oggetto. Tutto ciò che viene dopo non cambia.
\lstinline+\define@key+ è il modo ``normale'' per definire le chiavi usando xkeyval, al di là delle opzioni di pacchetto e di classe. xkeyval offre però anche altri strumenti. In questo caso è stato scelto il comando \lstinline+\define@choicekey+, il quale si usa per definire chiavi che permettono all'utente di inserire uno tra i valori previsti nella definizione, che sono quindi in numero limitato.
Subito dopo l'elenco dei valori ammissibili, tra parentesi quadre è inserito il valore di default, che viene selezionato quando la chiave viene richiamata senza valore.
L'altro argomento tra parentesi quadre è un parametro opzionale previsto dal comando \lstinline+\define@choicekey+; raccoglie, nella prima macro (\lstinline+\val+) l'input dell'utente, e nella seconda (\lstinline+\nr+) il numero corrispondente, partendo da 0 nella conta tra i valori disponibili. Solo la seconda macro viene usata, a partire dalla riga 11, dal comando \TeX\ \lstinline+\ifcase+: nel caso in cui l'utente abbia scelto il valore numero 0 (green), verrà assegnata alla macro \lstinline+\missa@litcolor+ la tinta DartmouthGreen; nel caso del valore numero 1 (violet), la tinta Violet; e così via.
Infine la riga 25 è un secondo comando reso disponibile dalla variante ``+'' del comando \lstinline+\define@choicekey+ (\lstinline|\define@choicekey+|) che viene eseguito al posto del primo nel caso in cui l'utente scelga un valore non compreso tra quelli previsti: in questo caso il compilatore emetterà un avviso, invece di bloccare l'esecuzione.
Riassumendo, ecco i diversi scenari possibili:
\begin{enumerate}
\item l'utente non sceglie l'opzione litcolor quando richiama la classe: il colore liturgico sarà impostato automaticamente come verde (riga 7);
\item l'utente inserisce l'opzione solo come chiave, senza assegnare un valore: il colore sarà sempre il verde, dato che il valore di default alla riga 10 è questo;
\item l'utente inserisce un valore non compreso tra quelli dell'elenco alla riga 10: il compilatore segnalerà il problema (riga 25), ignorerà il valore inserito e lo sostituirà di conseguenza con quello di default, ricadendo nel caso illustrato al punto precedente;
\item l'utente sceglie una coppia chiave--valore corretta, ad esempio \lstinline+litcolor=red+: alla macro \lstinline+\missa@litcolor+ verrà assegnato il valore ``red'' (riga 18), e quindi il colore liturgico sarà il rosso.
\end{enumerate}
\end{document}