阅读该课程时twentysecondcv.cls
我注意到有一个命令是这样定义的:
\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}
}
}
嵌套\renewcommand
里面\newcommand
是做什么用的?
完整的课程是在 GitHub 上。
答案1
以这种方式定义\skills
的效果是,在第一次使用时,它需要一个参数。然后skills
重新定义为存储此值(加上一些处理),以便从现在开始,命令(无参数)将重现第一次调用时设置的内容。
举个例子,
\newcommand\myname[1]{\renewcommand\myname{#1}}
当你执行
\myname{Stefano} % corresponds to \renewcommand\myname{Stefano}
然后从此刻起\myname
代表,即每次使用 都将被排版。Stefano
\myname
Stefano
答案2
TeX 没有变量本身与其他编程语言一样。有专用寄存器用于保存计数(整数)、维度、输入和输出流、标记列表等内容。但大多数情况下,所有内容都是以宏的形式定义的。这意味着,要将信息保存在变量中,需要定义一个宏。
这里所做的是非惯用的和有限的,因为现在命令\skills
已经不可逆转地改变了它的含义,并且该类的新手用户如果使用\skills
两次就会发现意想不到的结果。通常,人们不会重新定义命令,而是会做这样的事情:
\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}
}
}
它将存储该值\@skills
以供稍后使用(在此文档类中,稍后的使用来自命令\makeprofile
定义。
事实上,更惯用的做法是
\newcommand\skills[1]{\def\@skills{#1}}
然后将整个tikzpicture
环境移至\makeprofile
定义。
答案3
该命令\makeprofile
定义为
\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}
}
你应该\skills{x,y,z}
在做之前说\makeprofile
。
我认为这不是一个好的编程,因为它无法检查错误。
最好这样做
\newcommand{\skills}[1]{%
\def\twentysecondscv@skills{...#1...}%
}
而\makeprofile
不是\skills
调用
\ifdefined\twentysecondscv@skills
\twentysecondscv@skills
\else
\ClassError{twentysecondscv}
{No \protect\skills found}
{You need to define \protect\skills before doing \protect\makeprofile}%
\fi
有了此代码,错误消息就会准确地指出到底出了什么问题。
\skillstext
在提供的模板中似乎也没有使用过。如果忘记了\skills
,那么调用\makeprofile
只会吞掉\skillstext
。如果没有\skilltext
出现命令,它将吞噬\scriptsize
,这似乎只是为了被吞掉或被完全忽略。
甚至更好
\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}%
}
where\twentisecondscv@repeat
也可以用于其他只应发出一次的命令。