È un sacco di tempo che non riesco a scrivere un post. Ma questo non significa che ho smesso di usare LaTeX, anzi. Quindi è meglio che inizi a riportare i miei esperimenti, altrimenti mi dimentico cosa ho fatto.
Vediamo il problema che volevo affrontare: una tabella molto semplice, ma con molti elementi tutti uguali da ripetere, per di più una tabella che uso in vari file con un numero di colonne diverso. Per farla breve, vediamo la figura e il relativo codice:
%% preamble \usepackage{array} %% document \makebox[\textwidth][c]{% \sffamily \renewcommand{\arraystretch}{1.2} \renewcommand{\tabcolsep}{1mm} \begin{tabular}{|>{\bfseries}l *{8}{|>{\centering}p{3em}} |>{\bfseries\centering\arraybackslash}p{5em}|}\hline esercizio & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} &\textbf{totale}\\\hline punteggio massimo & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 8 \\\hline punteggio ottenuto & & & & & & & & & \\\hline \multicolumn{10}{l}{\sffamily \small Commento di vario tipo.} \end{tabular} }
Domanda: come rendere più snello il codice?
Ho individuato due modi, sicuramente ottimizzabili, ma entrambi caratterizzati da un approccio “facile” al problema.
Soluzione con il pacchetto forloop: la documentazione si trova qui, il comando che utilizzo è:
\forLoop[ step ]{ start }{ stop }{ counter name }{ code }
Per comodità definisco un opportuno contatore, exnum
, che viene incrementato di uno (tramite \stepcounter{exnum}
) ad ogni ciclo e del quale scrivo il valore (tramite \arabic{exnum}
)
%% preamble \usepackage{array} \usepackage{forloop} %% document \newcounter{exnum} % counter for writing the cell number \setcounter{exnum}{0} \newcounter{cellex} \newcommand{\qnum}{7} % number of questions \newcommand{\totnumcell}{9} % \qnum + 2 \makebox[\textwidth][c]{% \sffamily \begin{tabular}{|>{\bfseries}l *{\qnum}{|>{\centering}p{3em}} |>{\bfseries\centering\arraybackslash}p{5em}|}\hline esercizio & \forLoop{1}{\qnum}{cellex}{\textbf{\stepcounter{exnum}\arabic{exnum}} & } \textbf{totale}\\\hline punteggio massimo & \forLoop{1}{\qnum}{cellex}{ 2 & } 14 \\\hline punteggio ottenuto & \forLoop{1}{\qnum}{cellex}{ & } \\\hline \multicolumn{\totnumcell}{l}{\sffamily \small Commento di vario tipo.} \end{tabular} }
Soluzione con TikZ: ho usato il comando foreach
per le iterazioni. Il codice può essere largamente ottimizzato, ma intanto mi è venuto così:
%% preamble \usepackage{tikz} \usetikzlibrary{positioning} %% document \newcommand{\esmax}{4} \begin{center} \begin{tikzpicture}[node distance=0 cm,outer sep = 0pt] \tikzstyle{title}=[draw, rectangle, minimum height=1cm, minimum width=4cm, font=\bfseries \sffamily] \tikzstyle{mycell}=[draw, rectangle, minimum height=1cm, minimum width=5em] %% rows title \node[title] (es) at (0,0) {esercizio}; \node[title] (pmax) [below= of es] {punteggio massimo}; \node[title] (pti) [below= of pmax] {punteggio ottenuto}; %% exercise number \node[mycell,font=\bfseries\sffamily] (n1) [above right= of pmax] {1}; % second cell of the row \foreach \x [remember=\x as \lastx (initially 1)] in {2,...,\esmax}{ \node[mycell,font=\bfseries\sffamily] (n\x) [right= of n\lastx] {\x}; \ifnum \x=\esmax+1 \node[mycell,font=\bfseries\sffamily] (tot) [right= of n\esmax] {totale}; \node[mycell,font=\bfseries\sffamily] (ptot) [below= of tot] {4}; \node[mycell] (last) [below= of ptot] {}; \fi } % %% exercise points and the empty cells below \node[mycell,font=\sffamily] (p1) [right= of pmax] {1}; \node[mycell] (v1) [below= of p1] {};% second cell of the row \foreach \x [remember=\x as \lastx (initially 1)] in {2,...,\esmax}{ \node[mycell,font=\sffamily] (p\x) [right= of p\lastx] {1}; \node[mycell] (v\x) [below= of p\x] {}; } % \end{tikzpicture} \end{center}
e questo è il risultato: