如何将方法转换为键值版本?

如何将方法转换为键值版本?

我已经被告知很多次了,我应该考虑实现我的方法的键值版本\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}

键值语法的一大优点是它们的顺序完全不相关。

enter image description here

相关内容