閱讀課程時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}
then \myname
will 代表Stefano
從這一刻起,即每次使用\myname
will typeset 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
也可以用於其他應該只發出一次的命令。