Al leer la clase twentysecondcv.cls
noté que hay un comando definido de esta manera:
\newcommand\skills[1]{
\renewcommand{\skills}{
\begin{tikzpicture}
\foreach [count=\i] \x/\y in {#1}{
\draw[fill=maingray,maingray] (0,\i) rectangle (6,\i+0.4);
\draw[fill=white,mainblue](0,\i) rectangle (\y,\i+0.4);
\node [above right] at (0,\i+0.4) {\x};
}
\end{tikzpicture}
}
}
¿Para qué se utiliza el \renewcommand
interior anidado \newcommand
?
La clase completa esen GitHub.
Respuesta1
Definirlo \skills
de esta manera tiene el efecto de que, en el primer uso, necesita un argumento. Luego skills
se redefine para almacenar este valor (más algo de procesamiento) de modo que, de ahora en adelante, el comando (sin argumento) reproduzca aquello para lo que se configuró en la primera llamada.
Como ejemplo, tomemos la definición.
\newcommand\myname[1]{\renewcommand\myname{#1}}
cuando ejecutas
\myname{Stefano} % corresponds to \renewcommand\myname{Stefano}
entonces \myname
representará Stefano
a partir de este momento en adelante, es decir, cada uso de \myname
será tipografiado Stefano
.
Respuesta2
TeX no tiene variablesper secomo otros lenguajes de programación. Hay registros de propósito especial para contener cosas como recuentos (enteros), dimensiones, flujos de entrada y salida, listas de tokens, etc. pero en su mayor parte todo está definido en términos de macros. Eso significa que, para guardar información en una variable, se define una macro.
Lo que se hizo aquí no es idiomático y está limitado en el sentido de que ahora el \skills
comando ha cambiado su significado irrevocablemente y el usuario ingenuo de la clase descubrirá resultados inesperados si la usa \skills
dos veces. Normalmente, en lugar de redefinir el comando, se habría hecho algo como esto:
\newcommand\skills[1]{
\def\@skills{
\begin{tikzpicture}
\foreach [count=\i] \x/\y in {#1}{
\draw[fill=maingray,maingray] (0,\i) rectangle (6,\i+0.4);
\draw[fill=white,mainblue](0,\i) rectangle (\y,\i+0.4);
\node [above right] at (0,\i+0.4) {\x};
}
\end{tikzpicture}
}
}
que almacenaría el valor \@skills
para su uso posterior (en esta clase de documento, el uso posterior viene en la \makeprofile
definición del comando).
De hecho, algo más idiomático habría sido hacer
\newcommand\skills[1]{\def\@skills{#1}}
y luego mover todo el tikzpicture
entorno a la \makeprofile
definición.
Respuesta3
El comando \makeprofile
se define como
\newcommand{\makeprofile}{
\begin{tikzpicture}[remember picture,overlay]
\node [rectangle, fill=sidecolor, anchor=north, minimum width=9cm, minimum height=\paperheight+1cm] (box) at (-5cm,0.5cm){};
\end{tikzpicture}
%------------------------------------------------
\begin{textblock}{6}(0.5, 0.2)
[...irrelevant code...]
\profilesection{Skills}
\skills
\skillstext
\scriptsize
%(*)[The skill scale is from 0 (Fundamental Awareness) to 6 (Expert).]
%------------------------------------------------
\end{textblock}
}
y se supone que debes decirlo \skills{x,y,z}
antes de hacerlo \makeprofile
.
No me parece una buena programación, porque no puede comprobar si hay errores.
Sería mejor hacer
\newcommand{\skills}[1]{%
\def\twentysecondscv@skills{...#1...}%
}
y en \makeprofile
, en lugar de llamar \skills
, hazlo
\ifdefined\twentysecondscv@skills
\twentysecondscv@skills
\else
\ClassError{twentysecondscv}
{No \protect\skills found}
{You need to define \protect\skills before doing \protect\makeprofile}%
\fi
Con este código, el mensaje de error se referiría exactamente a lo que salió mal.
Tampoco \skillstext
parece usarse en ninguna parte de las plantillas proporcionadas. Si uno lo olvida \skills
, la llamada \makeprofile
simplemente se tragará \skillstext
. Si no \skilltext
aparece ninguna orden, devorará \scriptsize
, lo que parece estar ahí sólo con el propósito de ser tragado o ser ignorado por completo.
Aun mejor
\newcommand{\skills}[1]{%
\def\twentysecondscv@skills{...#1...}%
\renewcommand{\skills}[1]{\twentysecondscv@repeat{\skills}}%
}
\newcommand{\twentysecondscv@repeat}[1]{%
\ClassError{twentysecondscv}
{Multiple \protect#1 ignored}
{You should have just one \protect#1 command}%
}
donde \twentisecondscv@repeat
también se puede utilizar para otros comandos que se supone que deben emitirse sólo una vez.