声明只能在其他命令中使用的命令

声明只能在其他命令中使用的命令

我是 Latex 的新手,正在创建自己的 CV 类。

我希望能够在其他命令中使用我在类中创建的命令,这样它们就可以围绕特定主题进行分组。下面是我创建的一个代码片段,用于说明我想要实现的目标:

\documentclass[11pt,a4paper]{my-cv}

\CVInfo{
  \FirstName{myFirstName}
  \LastName{myLastName}
  \Email{myEmail}
  \Phone{myPhone}
  \Picture{myPicture}
  \RoundedPictureOptions{
    \PictureScale{0.4}
    \PictureXShift{-0.1cm}
    \PictureYShift{-0.4cm}
    \PictureBorder{
      \PictureBorderIsDashed{Y}
      \PictureBorderThickness{thick}
      \PictureBorderColor{blue}
    }
  }
}

\begin{document}
...
\end{document}

如您所见,有关简历的所有信息都在\简历信息命令,有关图片边框的所有信息都在\图片边框命令等等。

在类内部,这些命令应该仅将一些值设置为在其他地方使用的内部命令:

\newcommand{\FirstName}[1]{
  \def\@firstName{#1}
}

总而言之,我希望严格按照上面的代码所示的方式使用这些命令,即:

\FirstName{myFirstName}
\CVInfo{
...
}

和这个:

\CVInfo{
...
}
\FirstName{myFirstName}

不应该做任何事情\名命令。

有办法吗?无论如何,我不太确定这是否是我在创建自己的课程时应该采用的方法,因此请随意分享有关更好方法的任何评论。

谢谢你!

答案1

如果您更喜欢宏接口而不是键=值接口,您可以定义命令\FirstName\LastName等,以附加到令牌寄存器指令,以重新定义内部宏。如果这样做,您需要确保 .tex 输入文件中可选参数 中的每一行都以注释字符或被标记为控制字标记的内容结尾。否则,在参数 中的行以 或其他未标记为控制字标记的内容结尾\CVInfo的地方,可能会出现不需要的空格标记,从而产生不需要的水平粘连。\CVInfo}

\documentclass[11pt,a4paper]{article}

\makeatletter
\newtoks\CVInfotoks
\newcommand\DefineDontUseTheCommandHereError[2]{%
  \renewcommand#1[1]{\DontUseTheCommandHereError{#1}{#2}}%
}%
\newcommand\DefineDontUseTheCommandOptHereError[2]{%
  \renewcommand#1[1][]{\DontUseTheCommandHereError{#1}{#2}}%
}%
\newcommand\DontUseTheCommandHereError[2]{%
  \ClassError{my-cv}{%
     You can't execute the command \string#1 within the argument of the command \string#2%
  }{%
     Executing the command \string#1 within the argument of the command \string#2 seems not to make sense.%
  }%
}%
% Initial values:
\newcommand*\MyCV@firstName{myFirstName}%
\newcommand*\MyCV@lastName{myLastName}%
\newcommand*\MyCV@Email{myEmail}%
\newcommand*\MyCV@Phone{myPhone}%
\newcommand*\MyCV@Picture{myPicture}%
\newcommand*\MyCV@PictureScale{0.4}%
\newcommand*\MyCV@PictureXShift{-0.1cm}%
\newcommand*\MyCV@PictureYShift{-0.4cm}%
\newcommand*\MyCV@PictureBorderIsDashed{Y}%
\newcommand*\MyCV@PictureBorderThickness{thick}%
\newcommand*\MyCV@PictureBorderColor{blue}%
%
\newcommand\CVInfo[1][]{%
  \begingroup
  \CVInfotoks{}%
  \DefineDontUseTheCommandOptHereError{\CVInfo}{\CVInfo}%
  \long\def\FirstName##1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@firstName{##1}}}%
  \long\def\LastName##1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@lastName{##1}}}%
  \long\def\Email##1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@Email{##1}}}%
  \long\def\Phone##1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@Phone{##1}}}%
  \long\def\Picture##1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@Picture{##1}}}%
  \newcommand\RoundedPictureOptions[1]{%
    \begingroup
    \DefineDontUseTheCommandOptHereError{\CVInfo}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\RoundedPictureOptions}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\FirstName}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\LastName}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\Email}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\Phone}{\RoundedPictureOptions}%
    \DefineDontUseTheCommandHereError{\Picture}{\RoundedPictureOptions}%
    \long\def\PictureScale####1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureScale{####1}}}%
    \long\def\PictureXShift####1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureXShift{####1}}}%
    \long\def\PictureYShift####1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureYShift{####1}}}%
    \newcommand\PictureBorder[1]{%
      \begingroup
      \DefineDontUseTheCommandOptHereError{\CVInfo}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\RoundedPictureOptions}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\FirstName}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\LastName}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\Email}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\Phone}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\Picture}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\PictureBorder}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\PictureScale}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\PictureXShift}{\PictureBorder}%
      \DefineDontUseTheCommandHereError{\PictureYShift}{\PictureBorder}%
      \long\def\PictureBorderIsDashed########1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureBorderIsDashed{########1}}}%
      \long\def\PictureBorderThickness########1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureBorderThickness{########1}}}%
      \long\def\PictureBorderColor########1{\CVInfotoks=\expandafter{\the\CVInfotoks\def\MyCV@PictureBorderColor{########1}}}%
      ####1%
      \expandafter\endgroup
      \expandafter\CVInfotoks\expandafter=\expandafter{\the\CVInfotoks}%
    }%
    ##1%
    \expandafter\endgroup
    \expandafter\CVInfotoks\expandafter=\expandafter{\the\CVInfotoks}%
  }%
  #1%
  \expandafter\endgroup\the\CVInfotoks
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \message{%
    ^^J%
    Internal macros are now defined as follows:^^J%
    \string\MyCV@firstName: \meaning\MyCV@firstName^^J%
    \string\MyCV@lastName: \meaning\MyCV@lastName^^J%
    \string\MyCV@Email: \meaning\MyCV@Email^^J%
    \string\MyCV@Phone: \meaning\MyCV@Phone^^J%
    \string\MyCV@Picture: \meaning\MyCV@Picture^^J%
    \string\MyCV@PictureScale: \meaning\MyCV@PictureScale^^J%
    \string\MyCV@PictureXShift: \meaning\MyCV@PictureXShift^^J%
    \string\MyCV@PictureYShift: \meaning\MyCV@PictureYShift^^J%
    \string\MyCV@PictureBorderIsDashed: \meaning\MyCV@PictureBorderIsDashed^^J%
    \string\MyCV@PictureBorderThickness: \meaning\MyCV@PictureBorderThickness^^J%
    \string\MyCV@PictureBorderColor: \meaning\MyCV@PictureBorderColor^^J%
  }%
}%
\makeatother

\newcommand\FirstName{Outside \string\CVInfo this command is totally different.}

\CVInfo

\CVInfo[%
  \FirstName{John}%
  \LastName{Doe}%
  \Picture{JohnDoe.jpg}%
  \RoundedPictureOptions{%
    % \LastName{Smith} % uncomment to see the error-message.
    % \CVInfo % uncomment to see the error-message.
    % \CVInfo[] % uncomment to see the error-message.
    \PictureScale{0.8}%
    \PictureYShift{0.8cm}%
    \PictureBorder{%
      \PictureBorderIsDashed{N}%
      \PictureBorderThickness{not so thick}%
      \PictureBorderColor{red}%
    }%
    \PictureXShift{0.6cm}%
  }%
  \Email{john\[email protected]}%
  \Phone{123456}%
]%

\message{^^J\string\FirstName: \meaning\FirstName}
\message{^^J^^J\string\Email: \meaning\Email^^J^^J}

\begin{document}

\end{document}

编译上述示例时,终端提供以下消息:

$ pdflatex -shell-escape test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex)
 \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo))

Internal macros are now defined as follows:
\MyCV@firstName: macro:->myFirstName
\MyCV@lastName: macro:->myLastName
\MyCV@Email: macro:->myEmail
\MyCV@Phone: macro:->myPhone
\MyCV@Picture: macro:->myPicture
\MyCV@PictureScale: macro:->0.4
\MyCV@PictureXShift: macro:->-0.1cm
\MyCV@PictureYShift: macro:->-0.4cm
\MyCV@PictureBorderIsDashed: macro:->Y
\MyCV@PictureBorderThickness: macro:->thick
\MyCV@PictureBorderColor: macro:->blue


Internal macros are now defined as follows:
\MyCV@firstName: macro:->John
\MyCV@lastName: macro:->Doe
\MyCV@Email: macro:->john\string @doe.com
\MyCV@Phone: macro:->123456
\MyCV@Picture: macro:->JohnDoe.jpg
\MyCV@PictureScale: macro:->0.8
\MyCV@PictureXShift: macro:->0.6cm
\MyCV@PictureYShift: macro:->0.8cm
\MyCV@PictureBorderIsDashed: macro:->N
\MyCV@PictureBorderThickness: macro:->not so thick
\MyCV@PictureBorderColor: macro:->red


\FirstName: \long macro:->Outside \string \CVInfo this command is totally diffe
rent. 

\Email: undefined

(./test.aux) (./test.aux) )
No pages of output.
Transcript written on test.log.

答案2

您可以使用该包鍵盤用于设置 key-val 接口。

包裹鍵盤是软件包的组成部分Z 和 pgf

包裹鍵盤解释为第七部分:实用程序,第 88 节 - pgfmanual.pdf 的密钥管理。 (手册.pdf是软件包的手册Z 和 pgf

起点可以是:

\documentclass{article}

\usepackage{pgfkeys}

\makeatletter
\newcommand\MapNewCVInfoValueKeyToMacro[3]{%
  % #1 = key
  % #2 = initial definition text of internal macro
  % #3 = internal macro to define from value of key
  \@ifdefinable#3{%
    \pgfkeys{#1/.value required, #1/.store in=#3, #1=#2}%
  }%
}%
\@ifdefinable\ifdashedborder{%
  \@ifdefinable\dashborderfalse{%
    \@ifdefinable\dashbordertrue{%
      \newif\ifdashedborder\dashedborderfalse
    }%
  }%
}%
\pgfkeys{%
  /CVInfo/RoundedPictureOptions/Border/dashed/.is if=dashedborder, 
     /CVInfo/RoundedPictureOptions/Border/dashed=true,
     /CVInfo/RoundedPictureOptions/Border/dashed/.value required,
  /CVInfo/RoundedPictureOptions/.code=\pgfkeys{/CVInfo/RoundedPictureOptions/.cd,#1},
    /CVInfo/RoundedPictureOptions/.value required, 
  /CVInfo/RoundedPictureOptions/Border/.code=\pgfkeys{/CVInfo/RoundedPictureOptions/Border/.cd,#1},
    /CVInfo/RoundedPictureOptions/Border/.value required, 
}%
\MapNewCVInfoValueKeyToMacro{/CVInfo/first name}{myFirstName}{\@Firstname}
\MapNewCVInfoValueKeyToMacro{/CVInfo/last name}{myLastName}{\@Lastname}
\MapNewCVInfoValueKeyToMacro{/CVInfo/email}{myEmail}{\@Email}
\MapNewCVInfoValueKeyToMacro{/CVInfo/phone}{myPhone}{\@Phone}
\MapNewCVInfoValueKeyToMacro{/CVInfo/picture}{myPicture}{\@Picture}
\MapNewCVInfoValueKeyToMacro{/CVInfo/RoundedPictureOptions/scale}{0.4}{\@Picturescale}
\MapNewCVInfoValueKeyToMacro{/CVInfo/RoundedPictureOptions/x shift}{-0.1cm}{\@Picturexshift}
\MapNewCVInfoValueKeyToMacro{/CVInfo/RoundedPictureOptions/y shift}{-0.4cm}{\@Pictureyshift}
\MapNewCVInfoValueKeyToMacro{/CVInfo/RoundedPictureOptions/Border/thickness}{thick}{\@Pictureborderthickness}
\MapNewCVInfoValueKeyToMacro{/CVInfo/RoundedPictureOptions/Border/color}{blue}{\@Picturebordercolor}

\newcommand\CVInfo[1][]{%
  \pgfkeys{/CVInfo/.cd,#1}%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \message{%
    ^^J%
    Internal macros are now defined as follows:^^J%
    \string\@Firstname: \meaning\@Firstname^^J%
    \string\@Lastname: \meaning\@Lastname^^J%
    \string\@Email: \meaning\@Email^^J%
    \string\@Phone: \meaning\@Phone^^J%
    \string\@Picture: \meaning\@Picture^^J%
    \string\@Picturescale: \meaning\@Picturescale^^J%
    \string\@Picturexshift: \meaning\@Picturexshift^^J%
    \string\@Pictureyshift: \meaning\@Pictureyshift^^J%
    \string\ifdashedborder: \meaning\ifdashedborder^^J%
    \string\@Pictureborderthickness: \meaning\@Pictureborderthickness^^J%
    \string\@Picturebordercolor: \meaning\@Picturebordercolor^^J%
  }%
}%

\makeatother

\CVInfo

\CVInfo[%
  first name=John,
  last name=Doe,
  picture=JohnDoe.jpg,
  RoundedPictureOptions={
    scale=0.8,
    x shift=0.6cm,
    y shift=0.8cm,
    Border={
      dashed=false,
      thickness=not so thick,
      color=red
    }%
  },
  email=john\[email protected],
  phone=123456
]

\begin{document}

\end{document}

编译上述示例时,终端将告诉您以下内容:

$ pdflatex -shell-escape test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex)
 \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.t
ex)))

Internal macros are now defined as follows:
\@Firstname: macro:->myFirstName
\@Lastname: macro:->myLastName
\@Email: macro:->myEmail
\@Phone: macro:->myPhone
\@Picture: macro:->myPicture
\@Picturescale: macro:->0.4
\@Picturexshift: macro:->-0.1cm
\@Pictureyshift: macro:->-0.4cm
\ifdashedborder: \iftrue
\@Pictureborderthickness: macro:->thick
\@Picturebordercolor: macro:->blue


Internal macros are now defined as follows:
\@Firstname: macro:->John
\@Lastname: macro:->Doe
\@Email: macro:->john\string @doe.com
\@Phone: macro:->123456
\@Picture: macro:->JohnDoe.jpg
\@Picturescale: macro:->0.8
\@Picturexshift: macro:->0.6cm
\@Pictureyshift: macro:->0.8cm
\ifdashedborder: \iffalse
\@Pictureborderthickness: macro:->not so thick
\@Picturebordercolor: macro:->red
(./test.aux) (./test.aux) )
No pages of output.
Transcript written on test.log.

pgfkeys 包中所谓的密钥树也可用作存储所有数据的数据库。

您无需定义内部宏,就可以使用它\pgfkeysvalueof来获取值键的值:

\documentclass{article}

\usepackage{pgfkeys}

\makeatletter
\newif\ifdashedborder\dashedborderfalse
\pgfkeys{%
  /CVInfo/RoundedPictureOptions/Border/dashed/.is if=dashedborder, 
    /CVInfo/RoundedPictureOptions/Border/dashed=true, 
    /CVInfo/RoundedPictureOptions/Border/dashed/.value required, 
  /CVInfo/first name/.value required, /CVInfo/first name/.initial=myFirstName,
  /CVInfo/last name/.value required, /CVInfo/last name/.initial=myLastName,
  /CVInfo/email/.value required, /CVInfo/email/.initial=myEmail,
  /CVInfo/phone/.value required, /CVInfo/phone/.initial=myPhone,
  /CVInfo/picture/.value required, /CVInfo/picture/.initial=myPicture,
  /CVInfo/RoundedPictureOptions/scale/.value required, /CVInfo/RoundedPictureOptions/scale/.initial=0.4,
  /CVInfo/RoundedPictureOptions/x shift/.value required, /CVInfo/RoundedPictureOptions/x shift/.initial=-0.1cm,
  /CVInfo/RoundedPictureOptions/y shift/.value required, /CVInfo/RoundedPictureOptions/y shift/.initial=-0.4cm,
  /CVInfo/RoundedPictureOptions/Border/thickness/.value required, /CVInfo/RoundedPictureOptions/Border/thickness/.initial=thick,
  /CVInfo/RoundedPictureOptions/Border/color/.value required, /CVInfo/RoundedPictureOptions/Border/color/.initial=blue,
  /CVInfo/RoundedPictureOptions/.code=\pgfkeys{/CVInfo/RoundedPictureOptions/.cd,#1},
    /CVInfo/RoundedPictureOptions/.value required,
  /CVInfo/RoundedPictureOptions/Border/.code=\pgfkeys{/CVInfo/RoundedPictureOptions/Border/.cd,#1},
    /CVInfo/RoundedPictureOptions/Border/.value required
}%

\newcommand\CVInfo[1][]{%
  \pgfkeys{/CVInfo/.cd,#1}%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \message{%
    ^^J%
    Values of keys are set as follows:^^J%
    /CVInfo/first name=\pgfkeysvalueof{/CVInfo/first name}^^J%
    /CVInfo/last name=\pgfkeysvalueof{/CVInfo/last name}^^J%
    /CVInfo/email=\pgfkeysvalueof{/CVInfo/email}^^J%
    /CVInfo/phone=\pgfkeysvalueof{/CVInfo/phone}^^J%
    /CVInfo/picture=\pgfkeysvalueof{/CVInfo/picture}^^J%
    /CVInfo/RoundedPictureOptions/scale=\pgfkeysvalueof{/CVInfo/RoundedPictureOptions/scale}^^J%
    /CVInfo/RoundedPictureOptions/x shift=\pgfkeysvalueof{/CVInfo/RoundedPictureOptions/x shift}^^J%
    /CVInfo/RoundedPictureOptions/y shift=\pgfkeysvalueof{/CVInfo/RoundedPictureOptions/y shift}^^J%
    \string\ifdashedborder: \meaning\ifdashedborder^^J%
    /CVInfo/RoundedPictureOptions/Border/thickness=\pgfkeysvalueof{/CVInfo/RoundedPictureOptions/Border/thickness}^^J%
    /CVInfo/RoundedPictureOptions/Border/color=\pgfkeysvalueof{/CVInfo/RoundedPictureOptions/Border/color}^^J%
  }%
}%

\makeatother

\CVInfo

\CVInfo[%
  first name=John,
  last name=Doe,
  picture=JohnDoe.jpg,
  RoundedPictureOptions={%
    scale=0.8,
    x shift=0.6cm,
    y shift=0.8cm,
    Border={%
      dashed=false,
      thickness=not so thick,
      color=red
    }%
  },
  email=john\[email protected],
  phone=123456
]

\begin{document}

\end{document}

编译上述示例时,终端将告诉您以下内容:

$ pdflatex -shell-escape test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex)
 \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2018-12-01>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
(/usr/share/texlive/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.t
ex)))

Values of keys are set as follows:
/CVInfo/first name=myFirstName
/CVInfo/last name=myLastName
/CVInfo/email=myEmail
/CVInfo/phone=myPhone
/CVInfo/picture=myPicture
/CVInfo/RoundedPictureOptions/scale=0.4
/CVInfo/RoundedPictureOptions/x shift=-0.1cm
/CVInfo/RoundedPictureOptions/y shift=-0.4cm
\ifdashedborder: \iftrue
/CVInfo/RoundedPictureOptions/Border/thickness=thick
/CVInfo/RoundedPictureOptions/Border/color=blue


Values of keys are set as follows:
/CVInfo/first name=John
/CVInfo/last name=Doe
/CVInfo/[email protected]
/CVInfo/phone=123456
/CVInfo/picture=JohnDoe.jpg
/CVInfo/RoundedPictureOptions/scale=0.8
/CVInfo/RoundedPictureOptions/x shift=0.6cm
/CVInfo/RoundedPictureOptions/y shift=0.8cm
\ifdashedborder: \iffalse
/CVInfo/RoundedPictureOptions/Border/thickness=not so thick
/CVInfo/RoundedPictureOptions/Border/color=red
(./test.aux) (./test.aux) )
No pages of output.
Transcript written on test.log.

您可能希望变成/CVInfo/RoundedPictureOptions/Border/thickness一个选择键。

相关内容