我已经被告知很多次了,我应该考虑实现我的方法的键值版本\createPerson
。我想这样做,但我的问题是我不知道如何继续下去。你能帮我开始并解释一下它的工作原理吗?
该\createPerson
命令根据可用的参数将参数放置在不同的位置,并且仅创建绝对必要的行。
下面是我使用该方法的最少代码示例:
\documentclass{article}
\usepackage{tikz}
\usepackage{datetime}
\usepackage[danish]{varioref}
\usepackage{hyperref}
\usepackage{xifthen}
\RequirePackage[framemethod=TikZ]{mdframed}
\usepackage{multirow, tabularx}
\usepackage[]{units}
\usepackage{xparse}
\usepackage{adjustbox}
%=========================================================================
% CREATE PERSON NEW
%=========================================================================
%Arguments:
% 1) MANDATORY - Image destination
% 2) [OPTIONAL] - Called name
% 3) MANDATORY - Reference to the current full name
% 4) [OPTIONAL] - Full birth name
% 5) MANDATORY - Uniqueue Reference number
% 6) [OPTIONAL] - Birth date in the format of dd. mmm. yyyy
% 7) <OPTIONAL> - Death date in the format of dd. mmm. yyyy
\NewDocumentCommand\createPerson{r<>omomo+d<>}
{
\begin{mdframed}[style=whiteBox]%
\profileImage[width=0.25\textwidth]{#1}
\begin{tabularx}{0.75\textwidth}[t]{lXrc}%
% Row one
Navn: & \nameref{#3} & \textlabel{#5}{PERSON_ID:#3} & $\Re$%
%Create new row if needed
\IfNoValueTF{#2}%
{\IfNoValueTF{#4}%
{\IfNoValueTF{#6}%
{\IfNoValueTF{#7}%
{}%
{\\}}%
{\\}}%
{\\}}%
{\\}%
% Row two
\IfNoValueTF{#4}%
% If no birth name
{\IfNoValueTF{#2}%
% If no called name
{&&}%
% If a called name
{Kaldenavn: & \textlabel{#2}{KN:#3} &}}%
%If a birth name
{Fødenavn: & #4 &}%
%
\IfNoValueTF{#6}%
% If no birth date
{\IfNoValueTF{#7}{}{\textlabel{#7}{DD:#3} & \cross}}%
{\textlabel{#6}{FD:#3} & $\star$}%
% Create new row if needed
\IfNoValueTF{#2}%
{%
\IfNoValueTF{#6}%
{}%
{\IfNoValueTF{#7}%
{}%
{\\}%
}%
}%
{\IfNoValueTF{#4}%
{\IfNoValueTF{#6}%
{}%
{\IfNoValueTF{#7}%
{}%
{\\}%
}%
}%
{\\}%
}%
% Row three
\IfNoValueTF{#2}%
% If no called name
{%
\IfNoValueTF{#6}%
{}%
{\IfNoValueTF{#7}%
{}%
{&&}%
}%
}%
% If a called name
{\IfNoValueTF{#4}%
% If no birth name
{
\IfNoValueTF{#6}%
{}%
{\IfNoValueTF{#7}%
{}%
{&&}%
}%
}%
%If birth name
{Kaldenavn: & \textlabel{#2}{KN:#3} &}%
}%
%
\IfNoValueTF{#7}%
% If no death date
{}%
{\IfNoValueTF{\textlabel{#6}{FD:#3}}{}{\textlabel{#7}{DD:#3} & \cross}}%
\end{tabularx}%
\end{mdframed}%
}
%=========================================================================
% TEXT LABEL
%=========================================================================
\makeatletter%
% Arguments:
% 1) The text
% 2) The label
\newcommand*{\textlabel}[2]{%
\edef\@currentlabel{#1}% Set target label
#1\phantomsection\label{#2}% Print and store label
}
\makeatother
\mdfdefinestyle{whiteBox}{%
linecolor=black,
outerlinewidth=0.75pt,
roundcorner=6pt,
innertopmargin=10pt,
innerbottommargin=10pt,
innerrightmargin=10pt,
innerleftmargin=10pt,
backgroundcolor=white,
outermargin=0cm,
nobreak=true,
align=center}
%=========================================================================
% Profile image in border
%=========================================================================
\newsavebox\profileImageBox
\NewDocumentCommand{\profileImage}%
{O{width=0.6\linewidth}
O{draw=black,line width=0.75pt,rounded corners=6pt}
m}{%
\savebox\profileImageBox{\includegraphics[#1]{#3}}%
\begin{adjustbox}{valign=t}
\begin{tikzpicture}%
\draw [path picture={%
\node at (path picture bounding box.center) {%
\usebox\profileImageBox};},#2]
(0,0) rectangle (\wd\profileImageBox,\ht\profileImageBox);
\end{tikzpicture}%
\end{adjustbox}%
}
%=========================================================================
% Cross
%=========================================================================
\newcommand{\cross}[1][.7pt]{\ooalign{%
\rule[1ex]{1ex}{#1}\cr% Horizontal bar
\hss\rule{#1}{.7em}\hss\cr}% Vertical bar
}
\begin{document}
\section{Carl Wilhelm Larsen}
\label{CarlWilhelmLarsen1867}
\createPerson%
<summer>%
[Carl]%
{CarlWilhelmLarsen1867}%
{315}%
[5 maj 1867]%
<18 maj 1953>%
\end{document}
答案1
下面是一个实现。我通过为四个“角”设置四个 token 列表来简化第二行和第三行的处理,从而大大避免了代码重复和条件嵌套。
\documentclass{article}
\usepackage{tikz}
\usepackage{datetime}
\usepackage[danish]{varioref}
\usepackage{hyperref}
\usepackage{xifthen}
\RequirePackage[framemethod=TikZ]{mdframed}
\usepackage{multirow, tabularx}
\usepackage[]{units}
\usepackage{xparse}
\usepackage{adjustbox}
%=========================================================================
% CREATE PERSON NEW
%=========================================================================
% Keys (M = mandatory, O = optional)
% image (M) - Image destination
% name (O) - Called name
% fullname (M) - Reference to the current full name
% birthname (O) - Full birth name
% ref (M) - Unique Reference number
% birthdate (O) - Birth date in the format of dd. mmm. yyyy
% deathdate (O) - Death date in the format of dd. mmm. yyyy
\ExplSyntaxOn
\NewDocumentCommand\createPerson{m}
{
\group_begin:
\keys_set:nn { firefly/persons } { #1 }
\firefly_person_make:
\group_end:
}
\keys_define:nn { firefly/persons }
{
image .tl_set:N = \l_firefly_persons_image_tl,
image .value_required:n = true,
name .tl_set:N = \l_firefly_persons_name_tl,
fullname .tl_set:N = \l_firefly_persons_fullname_tl,
fullname .value_required:n = true,
birthname .tl_set:N = \l_firefly_persons_birthname_tl,
ref .tl_set:N = \l_firefly_persons_ref_tl,
ref .value_required:n = true,
birthdate .tl_set:N = \l_firefly_persons_birthdate_tl,
deathdate .tl_set:N = \l_firefly_persons_deathdate_tl,
}
\tl_new:N \l__firefly_persons_ul_tl
\tl_new:N \l__firefly_persons_ur_tl
\tl_new:N \l__firefly_persons_ll_tl
\tl_new:N \l__firefly_persons_lr_tl
\tl_const:Nn \c__firefly_persons_test_tl { & }
\cs_new_protected:Nn \firefly_person_make:
{
\begin{mdframed}[style=whiteBox]%
% initialize data for rows two and three
\tl_set:Nn \l__firefly_persons_ul_tl { & }
\tl_set:Nn \l__firefly_persons_ur_tl { & }
\tl_set:Nn \l__firefly_persons_ll_tl { & }
\tl_set:Nn \l__firefly_persons_lr_tl { & }
\tl_if_empty:NTF \l_firefly_persons_birthname_tl
{ % no birth name
\tl_if_empty:NF \l_firefly_persons_name_tl
{ % name
\tl_set:Nn \l__firefly_persons_ul_tl
{
Kaldenavn: & \firefly_persons_label:Vn \l_firefly_persons_name_tl {KN}
}
}
}
{ % birth name
\tl_set:Nn \l__firefly_persons_ul_tl
{
F\o denavn: & \l_firefly_persons_birthname_tl
}
\tl_if_empty:NF \l_firefly_persons_name_tl
{ % name
\tl_set:Nn \l__firefly_persons_ll_tl
{
Kaldenavn: & \firefly_persons_label:Vn \l_firefly_persons_name_tl {KN}
}
}
}
\tl_if_empty:NTF \l_firefly_persons_birthdate_tl
{% no birth date
\tl_if_empty:NF \l_firefly_persons_deathdate_tl
{
\tl_set:Nn \l__firefly_persons_ur_tl
{
\firefly_persons_label:Vn \l_firefly_persons_deathdate_tl {DD} & \cross
}
}
}
{ % birth date
\tl_set:Nn \l__firefly_persons_ur_tl
{
\firefly_persons_label:Vn \l_firefly_persons_birthdate_tl {FD} & $\star$
}
\tl_if_empty:NF \l_firefly_persons_deathdate_tl
{
\tl_set:Nn \l__firefly_persons_lr_tl
{
\firefly_persons_label:Vn \l_firefly_persons_deathdate_tl {DD} & \cross
}
}
}
% print the data
\hspace{-0.75pt}
\profileImage[width=0.25\textwidth]{\l_firefly_persons_image_tl}
\begin{tabularx}{0.75\textwidth}[t]{l>{\raggedright}Xrc}%
% Row one
Navn: &
\nameref{\l_firefly_persons_fullname_tl} &
\firefly_persons_label:Vn \l_firefly_persons_ref_tl {PERSON_ID} & $\Re$
\\
% Row two
\bool_if:nF
{
\tl_if_eq_p:NN \l__firefly_persons_ul_tl \c__firefly_persons_test_tl
&&
\tl_if_eq_p:NN \l__firefly_persons_ur_tl \c__firefly_persons_test_tl
}
{
\l__firefly_persons_ul_tl & \l__firefly_persons_ur_tl \\
}
% Row three
\bool_if:nF
{
\tl_if_eq_p:NN \l__firefly_persons_ll_tl \c__firefly_persons_test_tl
&&
\tl_if_eq_p:NN \l__firefly_persons_lr_tl \c__firefly_persons_test_tl
}
{
\l__firefly_persons_ll_tl & \l__firefly_persons_lr_tl \\
}
\end{tabularx}
\end{mdframed}
}
\cs_new_protected:Nn \firefly_persons_label:nn
{
\tl_set:cn { @currentlabel } { #1 }
#1\phantomsection\label{#2:\l_firefly_persons_name_tl}
}
\cs_generate_variant:Nn \firefly_persons_label:nn { V }
\ExplSyntaxOff
\mdfdefinestyle{whiteBox}{%
linecolor=black,
outerlinewidth=0.75pt,
roundcorner=6pt,
innertopmargin=10pt,
innerbottommargin=10pt,
innerrightmargin=10pt,
innerleftmargin=10pt,
backgroundcolor=white,
outermargin=0cm,
nobreak=true,
align=center}
%=========================================================================
% Profile image in border
%=========================================================================
\newsavebox\profileImageBox
\NewDocumentCommand{\profileImage}%
{O{width=0.6\linewidth}
O{draw=black,line width=0.75pt,rounded corners=6pt}
m}{%
\savebox\profileImageBox{\includegraphics[#1]{#3}}%
\begin{adjustbox}{valign=t}
\begin{tikzpicture}%
\draw [path picture={%
\node at (path picture bounding box.center) {%
\usebox\profileImageBox};},#2]
(0,0) rectangle (\wd\profileImageBox,\ht\profileImageBox);
\end{tikzpicture}%
\end{adjustbox}%
}
%=========================================================================
% Cross
%=========================================================================
\newcommand{\cross}[1][.7pt]{\ooalign{%
\rule[1ex]{1ex}{#1}\cr% Horizontal bar
\hss\rule{#1}{.7em}\hss\cr}% Vertical bar
}
\begin{document}
\section{Carl Wilhelm Larsen}
\label{CarlWilhelmLarsen1867}
\createPerson{
image=../duck,
name=Carl,
fullname=CarlWilhelmLarsen1867,
birthname=Xyz,
ref=315,
birthdate=5 maj 1867,
deathdate=18 maj 1953,
}
\end{document}
键值语法的一大优点是它们的顺序完全不相关。