我刚刚开始使用 LaTeX,但是一些最基础的东西还在苦苦挣扎。
我创建了 2 个命令,每个命令为一个变量分配一个值:
\newcommand{\firstname}[1]{\def\@firstname{#1}}
\newcommand{\lastname}[1]{\def\@lastname{#1}}
这些变量是使用文档开头某处的命令设置的:
\firstname{Kevin}
\lastname{De Coninck}
当我尝试打印 时lastname
,一切正常,当我尝试打印 时firstname
,返回以下错误。Use of \@ doesn't match its definition. \@f
我正在使用以下代码在文档中进行打印:
\begin{document}
\@firstname
\end{document}
我在这里遗漏了什么?
更新:整个文档
% ----------------------------------------------------------------------
% -- CONFIGURATION
% ----------------------------------------------------------------------
\documentclass[11pt, a4paper]{article}
% ----------------------------------------------------------------------
% -- PACKAGES
% ----------------------------------------------------------------------
\RequirePackage{geometry}
% ----------------------------------------------------------------------
% -- COMMAND DEFINITIONS
% ----------------------------------------------------------------------
% Summary: Configure the person's name.
% Usage: \name{<firstname>}{<lastname>}
% firstname{<firstname>}
% lastname{<lastname>}
\newcommand{\firstname}[1]{\def\@firstname{#1}}
\newcommand{\lastname}[1]{\def\@lastname{#1}}
% ----------------------------------------------------------------------
% -- LAYOUT CONFIGURATION
% ----------------------------------------------------------------------
\geometry{left=2.0cm, top=5.5cm, right=2.0cm, bottom=2.0cm, footskip=.5cm}
% ----------------------------------------------------------------------
% -- PERSONAL DATA
% ----------------------------------------------------------------------
\firstname{Kevin}
\lastname{De Coninck}
% ----------------------------------------------------------------------
% -- ACTUAL DOCUMENT
% ----------------------------------------------------------------------
\begin{document}
\@firstname
\@lastname
\end{document}
答案1
\makeatletter...\makeatother
我在定义和用法周围添加了常见的对。
请也记住 daleif 的提议:\CMPLXfirstname
似乎更好、更容易。
我也改成\RequirePackage
了\usepackage
(虽然第一个也是允许的,但只适用于包裹,不适用于普通文档)
现在,@
是作为内部命令名称的一部分保留的特殊字符,普通文档用户不应轻易访问这些字符。包或类文件之外的字符@
不被视为命令名称的允许字母,因此\makeatletter
(暂时)更改了此设置,允许@
将其作为此类名称的一部分,然后\makeatother
恢复此设置。
% ----------------------------------------------------------------------
% -- CONFIGURATION
% ----------------------------------------------------------------------
\documentclass[11pt, a4paper]{article}
% ----------------------------------------------------------------------
% -- PACKAGES
% ----------------------------------------------------------------------
\usepackage{geometry}
% ----------------------------------------------------------------------
% -- COMMAND DEFINITIONS
% ----------------------------------------------------------------------
% Summary: Configure the person's name.
% Usage: \name{<firstname>}{<lastname>}
% firstname{<firstname>}
% lastname{<lastname>}
\makeatletter
\newcommand{\firstname}[1]{\def\@firstname{#1}}
\newcommand{\lastname}[1]{\def\@lastname{#1}}
\newcommand{\printname}{%
\@ifundefined{@firstname}{}{\@firstname} \@ifundefined{@lastname}{}{\@lastname}%
}
\makeatother
% ----------------------------------------------------------------------
% -- LAYOUT CONFIGURATION
% ----------------------------------------------------------------------
\geometry{left=2.0cm, top=5.5cm, right=2.0cm, bottom=2.0cm, footskip=.5cm}
% ----------------------------------------------------------------------
% -- PERSONAL DATA
% ----------------------------------------------------------------------
\firstname{Kevin}
\lastname{De Coninck}
% ----------------------------------------------------------------------
% -- ACTUAL DOCUMENT
% ----------------------------------------------------------------------
\begin{document}
\makeatletter
\@firstname\ \@lastname
\makeatother
Or \printname%
\end{document}
答案2
如果您不想使用\makeatletter
.. \makeatother
,您可以使用
\csname..\endcsname
:
\csname @firstname\endcsname
→ \@firstname
。
\csname @lastname\endcsname
→ \@lastname
。
我写了一个小包装器\csname..\endcsname
:
该宏的\CreateCsFromName
工作原理如下:
\CreateCsFromName<preceding tokens with no curly braces>{ControlSequence}
→ <preceding tokens with no curly braces>\ControlSequence
。
如果省略<preceding tokens with no curly braces>
,即如果留空<preceding tokens with no curly braces>
,则\CreateCsFromName
只会从控制序列的名称构造控制序列标记:
\CreateCsFromName{macro}
→ \macro
<preceding tokens with no curly braces>
您可以提供任何命令来(重新)定义,而不必留空:
\CreateCsFromName\long\def{macro}
→ \long\def\macro
\CreateCsFromName\long\def{macro}#1#2{First argument: #1, second argument: #2}
→ \long\def\macro#1#2{First argument: #1, second argument: #2}
\CreateCsFromName\newcommand*{macro}
→ \newcommand*\macro
\CreateCsFromName\newcommand*{macro}[2]{First argument: #1, second argument: #2}
→ \newcommand*\macro[2]{First argument: #1, second argument: #2}
例子:
\documentclass{article}
\newcommand\Exchange[2]{#2#1}
\newcommand\CreateCsFromName{}
\long\def\CreateCsFromName#1#{\romannumeral0\InnerCreateCsFromName{#1}}
\newcommand\InnerCreateCsFromName[2]{%
\expandafter\Exchange\expandafter{\csname#2\endcsname}{ #1}%
}
% raise an error in case \@firstname and \@lastname are already defined:
\CreateCsFromName\newcommand*{@firstname}{}
\CreateCsFromName\newcommand*{@lastname}{}
% commands for silently redefining \@firstname and \@lastname:
\newcommand{\firstname}{\CreateCsFromName\def{@firstname}}
\newcommand{\lastname}{\CreateCsFromName\def{@lastname}}
\firstname{Kevin}
\lastname{De Coninck}
\begin{document}
\CreateCsFromName{@firstname} \CreateCsFromName{@lastname}
\end{document}