Определите 2 переменные и выведите их на печать

Определите 2 переменные и выведите их на печать

Я только начал работать с 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}

Связанный контент