Beim Lesen der Klasse twentysecondcv.cls
ist mir aufgefallen, dass es einen Befehl gibt, der folgendermaßen definiert ist:
\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}
}
}
wofür wird das verschachtelte \renewcommand
Innere \newcommand
verwendet?
Die komplette Klasse istauf GitHub.
Antwort1
Diese Art der Definition \skills
hat zur Folge, dass bei der ersten Verwendung ein Argument benötigt wird. Anschließend skills
wird es neu definiert, um diesen Wert (plus einige Verarbeitungsschritte) zu speichern, sodass der Befehl (ohne Argument) von nun an das reproduziert, wofür er beim ersten Aufruf eingerichtet wurde.
Nehmen wir als Beispiel die Definition
\newcommand\myname[1]{\renewcommand\myname{#1}}
Wenn Sie ausführen
\myname{Stefano} % corresponds to \renewcommand\myname{Stefano}
„dann“ \myname
steht Stefano
von diesem Moment an für , d. h. bei jeder Verwendung von \myname
wird gesetzt Stefano
.
Antwort2
TeX hat keine Variablenan sichwie andere Programmiersprachen. Es gibt spezielle Register zum Speichern von Dingen wie Zählungen (Ganzzahlen), Dimensionen, Eingabe- und Ausgabeströmen, Tokenlisten usw., aber größtenteils wird alles in Form von Makros definiert. Das heißt, um Informationen in einer Variablen zu speichern, definiert man stattdessen ein Makro.
Was hier getan wurde, ist nicht idiomatisch und begrenzt, da der \skills
Befehl nun seine Bedeutung unwiderruflich geändert hat und der unerfahrene Benutzer der Klasse unerwartete Ergebnisse feststellen wird, wenn er ihn \skills
zweimal verwendet. Normalerweise hätte man, anstatt den Befehl neu zu definieren, stattdessen etwas wie das Folgende getan:
\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}
}
}
dadurch wird der Wert für eine spätere Verwendung gespeichert \@skills
(in dieser Dokumentklasse erfolgt die spätere Verwendung in der \makeprofile
Befehlsdefinition).
Eine idiomatischere Sache wäre in der Tat gewesen,
\newcommand\skills[1]{\def\@skills{#1}}
tikzpicture
und dann die gesamte Umgebung in die \makeprofile
Definition zu verschieben .
Antwort3
Der Befehl \makeprofile
ist definiert als
\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}
}
und Sie sollten es sagen, \skills{x,y,z}
bevor Sie es tun \makeprofile
.
Ich finde, das ist keine gute Programmierung, da hier keine Fehlerprüfung möglich ist.
Es wäre besser,
\newcommand{\skills}[1]{%
\def\twentysecondscv@skills{...#1...}%
}
und in \makeprofile
, statt anzurufen \skills
, tun
\ifdefined\twentysecondscv@skills
\twentysecondscv@skills
\else
\ClassError{twentysecondscv}
{No \protect\skills found}
{You need to define \protect\skills before doing \protect\makeprofile}%
\fi
Bei diesem Code würde die Fehlermeldung genau darauf verweisen, was schiefgelaufen ist.
Scheint auch \skillstext
in den bereitgestellten Vorlagen nirgends verwendet zu werden. Wenn man es vergisst , wird \skills
der Aufruf \makeprofile
einfach geschluckt \skillstext
. Wenn kein \skilltext
Befehl erscheint, wird verschlungen \scriptsize
, was anscheinend nur dazu da ist, geschluckt oder völlig ignoriert zu werden.
Noch besser
\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}%
}
wobei dies \twentisecondscv@repeat
auch für andere Befehle verwendet werden kann, die nur einmal ausgegeben werden sollen.